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