Common.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2012-2013 LunarG, Inc.
  4. //
  5. // All rights reserved.
  6. //
  7. // Redistribution and use in source and binary forms, with or without
  8. // modification, are permitted provided that the following conditions
  9. // are met:
  10. //
  11. // Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. //
  14. // Redistributions in binary form must reproduce the above
  15. // copyright notice, this list of conditions and the following
  16. // disclaimer in the documentation and/or other materials provided
  17. // with the distribution.
  18. //
  19. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  20. // contributors may be used to endorse or promote products derived
  21. // from this software without specific prior written permission.
  22. //
  23. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  26. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  28. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  29. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  31. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  33. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. // POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. #ifndef _COMMON_INCLUDED_
  37. #define _COMMON_INCLUDED_
  38. #include <algorithm>
  39. #include <cassert>
  40. #include <cstdio>
  41. #include <cstdlib>
  42. #include <list>
  43. #include <map>
  44. #include <set>
  45. #include <string>
  46. #include <unordered_map>
  47. #include <unordered_set>
  48. #include <vector>
  49. #if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700)
  50. #include <sstream>
  51. namespace std {
  52. template<typename T>
  53. std::string to_string(const T& val) {
  54. std::ostringstream os;
  55. os << val;
  56. return os.str();
  57. }
  58. }
  59. #endif
  60. #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
  61. #include <basetsd.h>
  62. #ifndef snprintf
  63. #define snprintf sprintf_s
  64. #endif
  65. #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args))
  66. #elif defined (solaris)
  67. #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
  68. #include <sys/int_types.h>
  69. #define UINT_PTR uintptr_t
  70. #else
  71. #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
  72. #include <stdint.h>
  73. #define UINT_PTR uintptr_t
  74. #endif
  75. #if defined(_MSC_VER) && _MSC_VER < 1800
  76. #include <stdlib.h>
  77. inline long long int strtoll (const char* str, char** endptr, int base)
  78. {
  79. return _strtoi64(str, endptr, base);
  80. }
  81. inline unsigned long long int strtoull (const char* str, char** endptr, int base)
  82. {
  83. return _strtoui64(str, endptr, base);
  84. }
  85. inline long long int atoll (const char* str)
  86. {
  87. return strtoll(str, NULL, 10);
  88. }
  89. #endif
  90. #if defined(_MSC_VER)
  91. #define strdup _strdup
  92. #endif
  93. /* windows only pragma */
  94. #ifdef _MSC_VER
  95. #pragma warning(disable : 4786) // Don't warn about too long identifiers
  96. #pragma warning(disable : 4514) // unused inline method
  97. #pragma warning(disable : 4201) // nameless union
  98. #endif
  99. #include "PoolAlloc.h"
  100. //
  101. // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
  102. //
  103. #define POOL_ALLOCATOR_NEW_DELETE(A) \
  104. void* operator new(size_t s) { return (A).allocate(s); } \
  105. void* operator new(size_t, void *_Where) { return (_Where); } \
  106. void operator delete(void*) { } \
  107. void operator delete(void *, void *) { } \
  108. void* operator new[](size_t s) { return (A).allocate(s); } \
  109. void* operator new[](size_t, void *_Where) { return (_Where); } \
  110. void operator delete[](void*) { } \
  111. void operator delete[](void *, void *) { }
  112. namespace glslang {
  113. //
  114. // Pool version of string.
  115. //
  116. typedef pool_allocator<char> TStringAllocator;
  117. typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TString;
  118. } // end namespace glslang
  119. // Repackage the std::hash for use by unordered map/set with a TString key.
  120. namespace std {
  121. template<> struct hash<glslang::TString> {
  122. std::size_t operator()(const glslang::TString& s) const
  123. {
  124. const unsigned _FNV_offset_basis = 2166136261U;
  125. const unsigned _FNV_prime = 16777619U;
  126. unsigned _Val = _FNV_offset_basis;
  127. size_t _Count = s.size();
  128. const char* _First = s.c_str();
  129. for (size_t _Next = 0; _Next < _Count; ++_Next)
  130. {
  131. _Val ^= (unsigned)_First[_Next];
  132. _Val *= _FNV_prime;
  133. }
  134. return _Val;
  135. }
  136. };
  137. }
  138. namespace glslang {
  139. inline TString* NewPoolTString(const char* s)
  140. {
  141. void* memory = GetThreadPoolAllocator().allocate(sizeof(TString));
  142. return new(memory) TString(s);
  143. }
  144. template<class T> inline T* NewPoolObject(T*)
  145. {
  146. return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
  147. }
  148. template<class T> inline T* NewPoolObject(T, int instances)
  149. {
  150. return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances];
  151. }
  152. //
  153. // Pool allocator versions of vectors, lists, and maps
  154. //
  155. template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
  156. public:
  157. POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
  158. typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
  159. TVector() : std::vector<T, pool_allocator<T> >() {}
  160. TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
  161. TVector(size_type i) : std::vector<T, pool_allocator<T> >(i) {}
  162. TVector(size_type i, const T& val) : std::vector<T, pool_allocator<T> >(i, val) {}
  163. };
  164. template <class T> class TList : public std::list<T, pool_allocator<T> > {
  165. };
  166. template <class K, class D, class CMP = std::less<K> >
  167. class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > {
  168. };
  169. template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_to<K> >
  170. class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
  171. };
  172. //
  173. // Persistent string memory. Should only be used for strings that survive
  174. // across compiles/links.
  175. //
  176. typedef std::basic_string<char> TPersistString;
  177. //
  178. // templatized min and max functions.
  179. //
  180. template <class T> T Min(const T a, const T b) { return a < b ? a : b; }
  181. template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
  182. //
  183. // Create a TString object from an integer.
  184. //
  185. #if defined _MSC_VER || defined MINGW_HAS_SECURE_API
  186. inline const TString String(const int i, const int base = 10)
  187. {
  188. char text[16]; // 32 bit ints are at most 10 digits in base 10
  189. _itoa_s(i, text, sizeof(text), base);
  190. return text;
  191. }
  192. #else
  193. inline const TString String(const int i, const int /*base*/ = 10)
  194. {
  195. char text[16]; // 32 bit ints are at most 10 digits in base 10
  196. // we assume base 10 for all cases
  197. snprintf(text, sizeof(text), "%d", i);
  198. return text;
  199. }
  200. #endif
  201. struct TSourceLoc {
  202. void init()
  203. {
  204. name = nullptr; string = 0; line = 0; column = 0;
  205. }
  206. void init(int stringNum) { init(); string = stringNum; }
  207. // Returns the name if it exists. Otherwise, returns the string number.
  208. std::string getStringNameOrNum(bool quoteStringName = true) const
  209. {
  210. if (name != nullptr) {
  211. TString qstr = quoteStringName ? ("\"" + *name + "\"") : *name;
  212. std::string ret_str(qstr.c_str());
  213. return ret_str;
  214. }
  215. return std::to_string((long long)string);
  216. }
  217. const char* getFilename() const
  218. {
  219. if (name == nullptr)
  220. return nullptr;
  221. return name->c_str();
  222. }
  223. const char* getFilenameStr() const { return name == nullptr ? "" : name->c_str(); }
  224. TString* name; // descriptive name for this string, when a textual name is available, otherwise nullptr
  225. int string;
  226. int line;
  227. int column;
  228. };
  229. class TPragmaTable : public TMap<TString, TString> {
  230. public:
  231. POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
  232. };
  233. const int MaxTokenLength = 1024;
  234. template <class T> bool IsPow2(T powerOf2)
  235. {
  236. if (powerOf2 <= 0)
  237. return false;
  238. return (powerOf2 & (powerOf2 - 1)) == 0;
  239. }
  240. // Round number up to a multiple of the given powerOf2, which is not
  241. // a power, just a number that must be a power of 2.
  242. template <class T> void RoundToPow2(T& number, int powerOf2)
  243. {
  244. assert(IsPow2(powerOf2));
  245. number = (number + powerOf2 - 1) & ~(powerOf2 - 1);
  246. }
  247. template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
  248. {
  249. assert(IsPow2(powerOf2));
  250. return ! (number & (powerOf2 - 1));
  251. }
  252. } // end namespace glslang
  253. #endif // _COMMON_INCLUDED_