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