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 37 #ifndef _COMMON_INCLUDED_ 38 #define _COMMON_INCLUDED_ 39 40 #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API 41 #include <basetsd.h> 42 #define snprintf sprintf_s 43 #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args)) 44 #elif defined (solaris) 45 #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) 46 #include <sys/int_types.h> 47 #define UINT_PTR uintptr_t 48 #else 49 #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) 50 #include <stdint.h> 51 #define UINT_PTR uintptr_t 52 #endif 53 54 #if defined(__ANDROID__) || _MSC_VER < 1700 55 #include <sstream> 56 namespace std { 57 template<typename T> 58 std::string to_string(const T& val) { 59 std::ostringstream os; 60 os << val; 61 return os.str(); 62 } 63 } 64 #endif 65 66 #if defined(_MSC_VER) && _MSC_VER < 1800 67 inline long long int strtoll (const char* str, char** endptr, int base) 68 { 69 return _strtoi64(str, endptr, base); 70 } 71 inline unsigned long long int strtoull (const char* str, char** endptr, int base) 72 { 73 return _strtoui64(str, endptr, base); 74 } 75 inline long long int atoll (const char* str) 76 { 77 return strtoll(str, NULL, 10); 78 } 79 #endif 80 81 /* windows only pragma */ 82 #ifdef _MSC_VER 83 #pragma warning(disable : 4786) // Don't warn about too long identifiers 84 #pragma warning(disable : 4514) // unused inline method 85 #pragma warning(disable : 4201) // nameless union 86 #endif 87 88 #include <set> 89 #include <unordered_set> 90 #include <vector> 91 #include <map> 92 #include <unordered_map> 93 #include <list> 94 #include <algorithm> 95 #include <string> 96 #include <cstdio> 97 #include <cassert> 98 99 #include "PoolAlloc.h" 100 101 // 102 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme. 103 // 104 #define POOL_ALLOCATOR_NEW_DELETE(A) \ 105 void* operator new(size_t s) { return (A).allocate(s); } \ 106 void* operator new(size_t, void *_Where) { return (_Where); } \ 107 void operator delete(void*) { } \ 108 void operator delete(void *, void *) { } \ 109 void* operator new[](size_t s) { return (A).allocate(s); } \ 110 void* operator new[](size_t, void *_Where) { return (_Where); } \ 111 void operator delete[](void*) { } \ 112 void operator delete[](void *, void *) { } 113 114 namespace glslang { 115 116 // 117 // Pool version of string. 118 // 119 typedef pool_allocator<char> TStringAllocator; 120 typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TString; 121 122 } // end namespace glslang 123 124 // Repackage the std::hash for use by unordered map/set with a TString key. 125 namespace std { 126 127 template<> struct hash<glslang::TString> { 128 std::size_t operator()(const glslang::TString& s) const 129 { 130 const unsigned _FNV_offset_basis = 2166136261U; 131 const unsigned _FNV_prime = 16777619U; 132 unsigned _Val = _FNV_offset_basis; 133 size_t _Count = s.size(); 134 const char* _First = s.c_str(); 135 for (size_t _Next = 0; _Next < _Count; ++_Next) 136 { 137 _Val ^= (unsigned)_First[_Next]; 138 _Val *= _FNV_prime; 139 } 140 141 return _Val; 142 } 143 }; 144 } 145 146 namespace glslang { 147 148 inline TString* NewPoolTString(const char* s) 149 { 150 void* memory = GetThreadPoolAllocator().allocate(sizeof(TString)); 151 return new(memory) TString(s); 152 } 153 154 template<class T> inline T* NewPoolObject(T) 155 { 156 return new(GetThreadPoolAllocator().allocate(sizeof(T))) T; 157 } 158 159 template<class T> inline T* NewPoolObject(T, int instances) 160 { 161 return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances]; 162 } 163 164 // 165 // Pool allocator versions of vectors, lists, and maps 166 // 167 template <class T> class TVector : public std::vector<T, pool_allocator<T> > { 168 public: 169 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) 170 171 typedef typename std::vector<T, pool_allocator<T> >::size_type size_type; 172 TVector() : std::vector<T, pool_allocator<T> >() {} 173 TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {} 174 TVector(size_type i) : std::vector<T, pool_allocator<T> >(i) {} 175 TVector(size_type i, const T& val) : std::vector<T, pool_allocator<T> >(i, val) {} 176 }; 177 178 template <class T> class TList : public std::list<T, pool_allocator<T> > { 179 }; 180 181 template <class K, class D, class CMP = std::less<K> > 182 class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > { 183 }; 184 185 template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_to<K> > 186 class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > { 187 }; 188 189 // 190 // Persistent string memory. Should only be used for strings that survive 191 // across compiles/links. 192 // 193 typedef std::basic_string<char> TPersistString; 194 195 // 196 // templatized min and max functions. 197 // 198 template <class T> T Min(const T a, const T b) { return a < b ? a : b; } 199 template <class T> T Max(const T a, const T b) { return a > b ? a : b; } 200 201 // 202 // Create a TString object from an integer. 203 // 204 #if defined _MSC_VER || defined MINGW_HAS_SECURE_API 205 inline const TString String(const int i, const int base = 10) 206 { 207 char text[16]; // 32 bit ints are at most 10 digits in base 10 208 _itoa_s(i, text, sizeof(text), base); 209 return text; 210 } 211 #else 212 inline const TString String(const int i, const int /*base*/ = 10) 213 { 214 char text[16]; // 32 bit ints are at most 10 digits in base 10 215 216 // we assume base 10 for all cases 217 snprintf(text, sizeof(text), "%d", i); 218 219 return text; 220 } 221 #endif 222 223 struct TSourceLoc { 224 void init() { name = nullptr; string = 0; line = 0; column = 0; } 225 // Returns the name if it exists. Otherwise, returns the string number. 226 std::string getStringNameOrNum(bool quoteStringName = true) const 227 { 228 if (name != nullptr) 229 return quoteStringName ? ("\"" + std::string(name) + "\"") : name; 230 return std::to_string((long long)string); 231 } 232 const char* name; // descriptive name for this string 233 int string; 234 int line; 235 int column; 236 }; 237 238 typedef TMap<TString, TString> TPragmaTable; 239 240 const int MaxTokenLength = 1024; 241 242 template <class T> bool IsPow2(T powerOf2) 243 { 244 if (powerOf2 <= 0) 245 return false; 246 247 return (powerOf2 & (powerOf2 - 1)) == 0; 248 } 249 250 // Round number up to a multiple of the given powerOf2, which is not 251 // a power, just a number that must be a power of 2. 252 template <class T> void RoundToPow2(T& number, int powerOf2) 253 { 254 assert(IsPow2(powerOf2)); 255 number = (number + powerOf2 - 1) & ~(powerOf2 - 1); 256 } 257 258 template <class T> bool IsMultipleOfPow2(T number, int powerOf2) 259 { 260 assert(IsPow2(powerOf2)); 261 return ! (number & (powerOf2 - 1)); 262 } 263 264 } // end namespace glslang 265 266 #endif // _COMMON_INCLUDED_ 267