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