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