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