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