Home | History | Annotate | Download | only in wtf
      1  /*
      2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  *
     20  */
     21 
     22 #ifndef TypeTraits_h
     23 #define TypeTraits_h
     24 
     25 #include "Platform.h"
     26 
     27 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
     28 #include <type_traits>
     29 #endif
     30 
     31 namespace WTF {
     32 
     33     // The following are provided in this file:
     34     //
     35     //   IsInteger<T>::value
     36     //   IsPod<T>::value, see the definition for a note about its limitations
     37     //   IsConvertibleToInteger<T>::value
     38     //
     39     //   IsSameType<T, U>::value
     40     //
     41     //   RemovePointer<T>::Type
     42     //   RemoveReference<T>::Type
     43     //   RemoveConst<T>::Type
     44     //   RemoveVolatile<T>::Type
     45     //   RemoveConstVolatile<T>::Type
     46     //
     47     //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
     48 
     49     template<typename T> struct IsInteger           { static const bool value = false; };
     50     template<> struct IsInteger<bool>               { static const bool value = true; };
     51     template<> struct IsInteger<char>               { static const bool value = true; };
     52     template<> struct IsInteger<signed char>        { static const bool value = true; };
     53     template<> struct IsInteger<unsigned char>      { static const bool value = true; };
     54     template<> struct IsInteger<short>              { static const bool value = true; };
     55     template<> struct IsInteger<unsigned short>     { static const bool value = true; };
     56     template<> struct IsInteger<int>                { static const bool value = true; };
     57     template<> struct IsInteger<unsigned int>       { static const bool value = true; };
     58     template<> struct IsInteger<long>               { static const bool value = true; };
     59     template<> struct IsInteger<unsigned long>      { static const bool value = true; };
     60     template<> struct IsInteger<long long>          { static const bool value = true; };
     61     template<> struct IsInteger<unsigned long long> { static const bool value = true; };
     62 #if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
     63     template<> struct IsInteger<wchar_t>            { static const bool value = true; };
     64 #endif
     65 
     66     template<typename T> struct IsFloatingPoint     { static const bool value = false; };
     67     template<> struct IsFloatingPoint<float>        { static const bool value = true; };
     68     template<> struct IsFloatingPoint<double>       { static const bool value = true; };
     69     template<> struct IsFloatingPoint<long double>  { static const bool value = true; };
     70 
     71     template<typename T> struct IsArithmetic     { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; };
     72 
     73     // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
     74     // Specifically, it doesn't allow for enums or for structs.
     75     template <typename T> struct IsPod           { static const bool value = IsArithmetic<T>::value; };
     76     template <typename P> struct IsPod<P*>       { static const bool value = true; };
     77 
     78     template<typename T> class IsConvertibleToInteger {
     79         // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
     80         // by not converting int's to doubles.
     81         template<bool performCheck, typename U> class IsConvertibleToDouble;
     82         template<typename U> class IsConvertibleToDouble<false, U> {
     83         public:
     84             static const bool value = false;
     85         };
     86 
     87         template<typename U> class IsConvertibleToDouble<true, U> {
     88             typedef char YesType;
     89             struct NoType {
     90                 char padding[8];
     91             };
     92 
     93             static YesType floatCheck(long double);
     94             static NoType floatCheck(...);
     95             static T& t;
     96         public:
     97             static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
     98         };
     99 
    100     public:
    101         static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
    102     };
    103 
    104     template <typename T, typename U> struct IsSameType {
    105         static const bool value = false;
    106     };
    107 
    108     template <typename T> struct IsSameType<T, T> {
    109         static const bool value = true;
    110     };
    111 
    112     template <typename T, typename U> class IsSubclass {
    113         typedef char YesType;
    114         struct NoType {
    115             char padding[8];
    116         };
    117 
    118         static YesType subclassCheck(U*);
    119         static NoType subclassCheck(...);
    120         static T* t;
    121     public:
    122         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    123     };
    124 
    125     template <typename T, template<class V> class U> class IsSubclassOfTemplate {
    126         typedef char YesType;
    127         struct NoType {
    128             char padding[8];
    129         };
    130 
    131         template<typename W> static YesType subclassCheck(U<W>*);
    132         static NoType subclassCheck(...);
    133         static T* t;
    134     public:
    135         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    136     };
    137 
    138     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
    139         typedef T Type;
    140     };
    141 
    142     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
    143         typedef T Type;
    144     };
    145 
    146     template <typename T> struct RemoveConst {
    147         typedef T Type;
    148     };
    149 
    150     template <typename T> struct RemoveConst<const T> {
    151         typedef T Type;
    152     };
    153 
    154     template <typename T> struct RemoveVolatile {
    155         typedef T Type;
    156     };
    157 
    158     template <typename T> struct RemoveVolatile<volatile T> {
    159         typedef T Type;
    160     };
    161 
    162     template <typename T> struct RemoveConstVolatile {
    163         typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
    164     };
    165 
    166     template <typename T> struct RemovePointer {
    167         typedef T Type;
    168     };
    169 
    170     template <typename T> struct RemovePointer<T*> {
    171         typedef T Type;
    172     };
    173 
    174     template <typename T> struct RemoveReference {
    175         typedef T Type;
    176     };
    177 
    178     template <typename T> struct RemoveReference<T&> {
    179         typedef T Type;
    180     };
    181 
    182 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
    183 
    184     // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
    185     // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
    186     template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
    187     template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
    188 
    189 #else
    190 
    191     // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
    192     // and HasTrivialDestructor definitions. The definitions here include most built-in
    193     // scalar types but do not include POD structs and classes. For the intended purposes of
    194     // type_traits this results correct but potentially less efficient code.
    195     template <typename T, T v>
    196     struct IntegralConstant {
    197         static const T value = v;
    198         typedef T value_type;
    199         typedef IntegralConstant<T, v> type;
    200     };
    201 
    202     typedef IntegralConstant<bool, true>  true_type;
    203     typedef IntegralConstant<bool, false> false_type;
    204 
    205 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER)
    206     // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor,
    207     // but for some unexplained reason it doesn't work on built-in types.
    208     template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ };
    209     template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ };
    210 #else
    211     template <typename T> struct HasTrivialConstructor : public false_type{ };
    212     template <typename T> struct HasTrivialDestructor : public false_type{ };
    213 #endif
    214 
    215     template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
    216     template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };
    217 
    218     template <> struct HasTrivialConstructor<float> : public true_type{ };
    219     template <> struct HasTrivialConstructor<const float> : public true_type{ };
    220     template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
    221     template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };
    222 
    223     template <> struct HasTrivialConstructor<double> : public true_type{ };
    224     template <> struct HasTrivialConstructor<const double> : public true_type{ };
    225     template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
    226     template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };
    227 
    228     template <> struct HasTrivialConstructor<long double> : public true_type{ };
    229     template <> struct HasTrivialConstructor<const long double> : public true_type{ };
    230     template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
    231     template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };
    232 
    233     template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
    234     template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
    235     template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
    236     template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };
    237 
    238     template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
    239     template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
    240     template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
    241     template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };
    242 
    243     template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
    244     template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
    245     template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
    246     template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };
    247 
    248     template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
    249     template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
    250     template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
    251     template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };
    252 
    253     template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
    254     template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
    255     template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
    256     template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };
    257 
    258     template <> struct HasTrivialConstructor<signed char> : public true_type{ };
    259     template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
    260     template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
    261     template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };
    262 
    263     template <> struct HasTrivialConstructor<signed short> : public true_type{ };
    264     template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
    265     template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
    266     template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };
    267 
    268     template <> struct HasTrivialConstructor<signed int> : public true_type{ };
    269     template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
    270     template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
    271     template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };
    272 
    273     template <> struct HasTrivialConstructor<signed long> : public true_type{ };
    274     template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
    275     template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
    276     template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };
    277 
    278     template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
    279     template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
    280     template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
    281     template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };
    282 
    283     template <> struct HasTrivialConstructor<bool> : public true_type{ };
    284     template <> struct HasTrivialConstructor<const bool> : public true_type{ };
    285     template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
    286     template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };
    287 
    288     template <> struct HasTrivialConstructor<char> : public true_type{ };
    289     template <> struct HasTrivialConstructor<const char> : public true_type{ };
    290     template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
    291     template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };
    292 
    293     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
    294         template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
    295         template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
    296         template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
    297         template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
    298     #endif
    299 
    300     template <> struct HasTrivialDestructor<float> : public true_type{ };
    301     template <> struct HasTrivialDestructor<const float> : public true_type{ };
    302     template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
    303     template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };
    304 
    305     template <> struct HasTrivialDestructor<double> : public true_type{ };
    306     template <> struct HasTrivialDestructor<const double> : public true_type{ };
    307     template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
    308     template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };
    309 
    310     template <> struct HasTrivialDestructor<long double> : public true_type{ };
    311     template <> struct HasTrivialDestructor<const long double> : public true_type{ };
    312     template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
    313     template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };
    314 
    315     template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
    316     template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
    317     template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
    318     template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };
    319 
    320     template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
    321     template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
    322     template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
    323     template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };
    324 
    325     template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
    326     template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
    327     template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
    328     template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };
    329 
    330     template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
    331     template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
    332     template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
    333     template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };
    334 
    335     template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
    336     template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
    337     template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
    338     template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };
    339 
    340     template <> struct HasTrivialDestructor<signed char> : public true_type{ };
    341     template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
    342     template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
    343     template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };
    344 
    345     template <> struct HasTrivialDestructor<signed short> : public true_type{ };
    346     template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
    347     template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
    348     template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };
    349 
    350     template <> struct HasTrivialDestructor<signed int> : public true_type{ };
    351     template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
    352     template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
    353     template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };
    354 
    355     template <> struct HasTrivialDestructor<signed long> : public true_type{ };
    356     template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
    357     template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
    358     template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };
    359 
    360     template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
    361     template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
    362     template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
    363     template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };
    364 
    365     template <> struct HasTrivialDestructor<bool> : public true_type{ };
    366     template <> struct HasTrivialDestructor<const bool> : public true_type{ };
    367     template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
    368     template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };
    369 
    370     template <> struct HasTrivialDestructor<char> : public true_type{ };
    371     template <> struct HasTrivialDestructor<const char> : public true_type{ };
    372     template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
    373     template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };
    374 
    375     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
    376         template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
    377         template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
    378         template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
    379         template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
    380     #endif
    381 
    382 #endif  // __GLIBCXX__, etc.
    383 
    384 } // namespace WTF
    385 
    386 #endif // TypeTraits_h
    387