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