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__) || (defined(_MSC_VER) && _MSC_VER < 1700)
42 #include <sstream>
43 namespace std {
44 template<typename T>
to_string(const T & val)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>
strtoll(const char * str,char ** endptr,int base)71     inline long long int strtoll (const char* str, char** endptr, int base)
72     {
73         return _strtoi64(str, endptr, base);
74     }
strtoull(const char * str,char ** endptr,int base)75     inline unsigned long long int strtoull (const char* str, char** endptr, int base)
76     {
77         return _strtoui64(str, endptr, base);
78     }
atoll(const char * str)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 <cstdlib>
106 #include <cassert>
107 
108 #include "PoolAlloc.h"
109 
110 //
111 // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
112 //
113 #define POOL_ALLOCATOR_NEW_DELETE(A)                                  \
114     void* operator new(size_t s) { return (A).allocate(s); }          \
115     void* operator new(size_t, void *_Where) { return (_Where); }     \
116     void operator delete(void*) { }                                   \
117     void operator delete(void *, void *) { }                          \
118     void* operator new[](size_t s) { return (A).allocate(s); }        \
119     void* operator new[](size_t, void *_Where) { return (_Where); }   \
120     void operator delete[](void*) { }                                 \
121     void operator delete[](void *, void *) { }
122 
123 namespace glslang {
124 
125     //
126     // Pool version of string.
127     //
128     typedef pool_allocator<char> TStringAllocator;
129     typedef std::basic_string <char, std::char_traits<char>, TStringAllocator> TString;
130 
131 } // end namespace glslang
132 
133 // Repackage the std::hash for use by unordered map/set with a TString key.
134 namespace std {
135 
136     template<> struct hash<glslang::TString> {
137         std::size_t operator()(const glslang::TString& s) const
138         {
139             const unsigned _FNV_offset_basis = 2166136261U;
140             const unsigned _FNV_prime = 16777619U;
141             unsigned _Val = _FNV_offset_basis;
142             size_t _Count = s.size();
143             const char* _First = s.c_str();
144             for (size_t _Next = 0; _Next < _Count; ++_Next)
145             {
146                 _Val ^= (unsigned)_First[_Next];
147                 _Val *= _FNV_prime;
148             }
149 
150             return _Val;
151         }
152     };
153 }
154 
155 namespace glslang {
156 
157 inline TString* NewPoolTString(const char* s)
158 {
159     void* memory = GetThreadPoolAllocator().allocate(sizeof(TString));
160     return new(memory) TString(s);
161 }
162 
163 template<class T> inline T* NewPoolObject(T*)
164 {
165     return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
166 }
167 
168 template<class T> inline T* NewPoolObject(T, int instances)
169 {
170     return new(GetThreadPoolAllocator().allocate(instances * sizeof(T))) T[instances];
171 }
172 
173 //
174 // Pool allocator versions of vectors, lists, and maps
175 //
176 template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
177 public:
178     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
179 
180     typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
181     TVector() : std::vector<T, pool_allocator<T> >() {}
182     TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
183     TVector(size_type i) : std::vector<T, pool_allocator<T> >(i) {}
184     TVector(size_type i, const T& val) : std::vector<T, pool_allocator<T> >(i, val) {}
185 };
186 
187 template <class T> class TList  : public std::list<T, pool_allocator<T> > {
188 };
189 
190 template <class K, class D, class CMP = std::less<K> >
191 class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > {
192 };
193 
194 template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_to<K> >
195 class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
196 };
197 
198 //
199 // Persistent string memory.  Should only be used for strings that survive
200 // across compiles/links.
201 //
202 typedef std::basic_string<char> TPersistString;
203 
204 //
205 // templatized min and max functions.
206 //
207 template <class T> T Min(const T a, const T b) { return a < b ? a : b; }
208 template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
209 
210 //
211 // Create a TString object from an integer.
212 //
213 #if defined _MSC_VER || defined MINGW_HAS_SECURE_API
214 inline const TString String(const int i, const int base = 10)
215 {
216     char text[16];     // 32 bit ints are at most 10 digits in base 10
217     _itoa_s(i, text, sizeof(text), base);
218     return text;
219 }
220 #else
221 inline const TString String(const int i, const int /*base*/ = 10)
222 {
223     char text[16];     // 32 bit ints are at most 10 digits in base 10
224 
225     // we assume base 10 for all cases
226     snprintf(text, sizeof(text), "%d", i);
227 
228     return text;
229 }
230 #endif
231 
232 struct TSourceLoc {
233     void init()
234     {
235         name = nullptr; string = 0; line = 0; column = 0;
236     }
237     void init(int stringNum) { init(); string = stringNum; }
238     // Returns the name if it exists. Otherwise, returns the string number.
239     std::string getStringNameOrNum(bool quoteStringName = true) const
240     {
241         if (name != nullptr) {
242             TString qstr = quoteStringName ? ("\"" + *name + "\"") : *name;
243             std::string ret_str(qstr.c_str());
244             return ret_str;
245         }
246         return std::to_string((long long)string);
247     }
248     const char* getFilename() const
249     {
250         if (name == nullptr)
251             return nullptr;
252         return name->c_str();
253     }
254     const char* getFilenameStr() const { return name == nullptr ? "" : name->c_str(); }
255     TString* name; // descriptive name for this string, when a textual name is available, otherwise nullptr
256     int string;
257     int line;
258     int column;
259 };
260 
261 class TPragmaTable : public TMap<TString, TString> {
262 public:
263     POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
264 };
265 
266 const int MaxTokenLength = 1024;
267 
268 template <class T> bool IsPow2(T powerOf2)
269 {
270     if (powerOf2 <= 0)
271         return false;
272 
273     return (powerOf2 & (powerOf2 - 1)) == 0;
274 }
275 
276 // Round number up to a multiple of the given powerOf2, which is not
277 // a power, just a number that must be a power of 2.
278 template <class T> void RoundToPow2(T& number, int powerOf2)
279 {
280     assert(IsPow2(powerOf2));
281     number = (number + powerOf2 - 1) & ~(powerOf2 - 1);
282 }
283 
284 template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
285 {
286     assert(IsPow2(powerOf2));
287     return ! (number & (powerOf2 - 1));
288 }
289 
290 } // end namespace glslang
291 
292 #endif // _COMMON_INCLUDED_
293