Home | History | Annotate | Download | only in Include
      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