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     //   RemoveConst<T>::Type
     43     //   RemoveVolatile<T>::Type
     44     //   RemoveConstVolatile<T>::Type
     45     //
     46     //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
     47 
     48     template<typename T> struct IsInteger           { static const bool value = false; };
     49     template<> struct IsInteger<bool>               { static const bool value = true; };
     50     template<> struct IsInteger<char>               { static const bool value = true; };
     51     template<> struct IsInteger<signed char>        { static const bool value = true; };
     52     template<> struct IsInteger<unsigned char>      { static const bool value = true; };
     53     template<> struct IsInteger<short>              { static const bool value = true; };
     54     template<> struct IsInteger<unsigned short>     { static const bool value = true; };
     55     template<> struct IsInteger<int>                { static const bool value = true; };
     56     template<> struct IsInteger<unsigned int>       { static const bool value = true; };
     57     template<> struct IsInteger<long>               { static const bool value = true; };
     58     template<> struct IsInteger<unsigned long>      { static const bool value = true; };
     59     template<> struct IsInteger<long long>          { static const bool value = true; };
     60     template<> struct IsInteger<unsigned long long> { static const bool value = true; };
     61 #if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
     62     template<> struct IsInteger<wchar_t>            { static const bool value = true; };
     63 #endif
     64 
     65     // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
     66     // Specifically, it doesn't allow for enums or for structs.
     67     template <typename T> struct IsPod           { static const bool value = IsInteger<T>::value; };
     68     template <> struct IsPod<float>              { static const bool value = true; };
     69     template <> struct IsPod<double>             { static const bool value = true; };
     70     template <> struct IsPod<long double>        { static const bool value = true; };
     71     template <typename P> struct IsPod<P*>       { static const bool value = true; };
     72 
     73     template<typename T> class IsConvertibleToInteger {
     74         // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
     75         // by not converting int's to doubles.
     76         template<bool performCheck, typename U> class IsConvertibleToDouble;
     77         template<typename U> class IsConvertibleToDouble<false, U> {
     78         public:
     79             static const bool value = false;
     80         };
     81 
     82         template<typename U> class IsConvertibleToDouble<true, U> {
     83             typedef char YesType;
     84             struct NoType {
     85                 char padding[8];
     86             };
     87 
     88             static YesType floatCheck(long double);
     89             static NoType floatCheck(...);
     90             static T& t;
     91         public:
     92             static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
     93         };
     94 
     95     public:
     96         static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
     97     };
     98 
     99     template <typename T, typename U> struct IsSameType {
    100         static const bool value = false;
    101     };
    102 
    103     template <typename T> struct IsSameType<T, T> {
    104         static const bool value = true;
    105     };
    106 
    107     template <typename T, typename U> class IsSubclass {
    108         typedef char YesType;
    109         struct NoType {
    110             char padding[8];
    111         };
    112 
    113         static YesType subclassCheck(U*);
    114         static NoType subclassCheck(...);
    115         static T* t;
    116     public:
    117         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    118     };
    119 
    120     template <typename T, template<class V> class U> class IsSubclassOfTemplate {
    121         typedef char YesType;
    122         struct NoType {
    123             char padding[8];
    124         };
    125 
    126         template<typename W> static YesType subclassCheck(U<W>*);
    127         static NoType subclassCheck(...);
    128         static T* t;
    129     public:
    130         static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
    131     };
    132 
    133     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
    134         typedef T Type;
    135     };
    136 
    137     template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
    138         typedef T Type;
    139     };
    140 
    141     template <typename T> struct RemoveConst {
    142         typedef T Type;
    143     };
    144 
    145     template <typename T> struct RemoveConst<const T> {
    146         typedef T Type;
    147     };
    148 
    149     template <typename T> struct RemoveVolatile {
    150         typedef T Type;
    151     };
    152 
    153     template <typename T> struct RemoveVolatile<volatile T> {
    154         typedef T Type;
    155     };
    156 
    157     template <typename T> struct RemoveConstVolatile {
    158         typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
    159     };
    160 
    161     template <typename T> struct RemovePointer {
    162         typedef T Type;
    163     };
    164 
    165     template <typename T> struct RemovePointer<T*> {
    166         typedef T Type;
    167     };
    168 
    169 #if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
    170 
    171     // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
    172     // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
    173     template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
    174     template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
    175 
    176 #else
    177 
    178     // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
    179     // and HasTrivialDestructor definitions. The definitions here include most built-in
    180     // scalar types but do not include POD structs and classes. For the intended purposes of
    181     // type_traits this results correct but potentially less efficient code.
    182     template <typename T, T v>
    183     struct IntegralConstant {
    184         static const T value = v;
    185         typedef T value_type;
    186         typedef IntegralConstant<T, v> type;
    187     };
    188 
    189     typedef IntegralConstant<bool, true>  true_type;
    190     typedef IntegralConstant<bool, false> false_type;
    191 
    192 #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER)
    193     // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor,
    194     // but for some unexplained reason it doesn't work on built-in types.
    195     template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ };
    196     template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ };
    197 #else
    198     template <typename T> struct HasTrivialConstructor : public false_type{ };
    199     template <typename T> struct HasTrivialDestructor : public false_type{ };
    200 #endif
    201 
    202     template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
    203     template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };
    204 
    205     template <> struct HasTrivialConstructor<float> : public true_type{ };
    206     template <> struct HasTrivialConstructor<const float> : public true_type{ };
    207     template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
    208     template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };
    209 
    210     template <> struct HasTrivialConstructor<double> : public true_type{ };
    211     template <> struct HasTrivialConstructor<const double> : public true_type{ };
    212     template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
    213     template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };
    214 
    215     template <> struct HasTrivialConstructor<long double> : public true_type{ };
    216     template <> struct HasTrivialConstructor<const long double> : public true_type{ };
    217     template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
    218     template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };
    219 
    220     template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
    221     template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
    222     template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
    223     template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };
    224 
    225     template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
    226     template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
    227     template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
    228     template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };
    229 
    230     template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
    231     template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
    232     template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
    233     template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };
    234 
    235     template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
    236     template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
    237     template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
    238     template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };
    239 
    240     template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
    241     template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
    242     template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
    243     template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };
    244 
    245     template <> struct HasTrivialConstructor<signed char> : public true_type{ };
    246     template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
    247     template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
    248     template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };
    249 
    250     template <> struct HasTrivialConstructor<signed short> : public true_type{ };
    251     template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
    252     template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
    253     template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };
    254 
    255     template <> struct HasTrivialConstructor<signed int> : public true_type{ };
    256     template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
    257     template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
    258     template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };
    259 
    260     template <> struct HasTrivialConstructor<signed long> : public true_type{ };
    261     template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
    262     template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
    263     template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };
    264 
    265     template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
    266     template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
    267     template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
    268     template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };
    269 
    270     template <> struct HasTrivialConstructor<bool> : public true_type{ };
    271     template <> struct HasTrivialConstructor<const bool> : public true_type{ };
    272     template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
    273     template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };
    274 
    275     template <> struct HasTrivialConstructor<char> : public true_type{ };
    276     template <> struct HasTrivialConstructor<const char> : public true_type{ };
    277     template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
    278     template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };
    279 
    280     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
    281         template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
    282         template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
    283         template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
    284         template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
    285     #endif
    286 
    287     template <> struct HasTrivialDestructor<float> : public true_type{ };
    288     template <> struct HasTrivialDestructor<const float> : public true_type{ };
    289     template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
    290     template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };
    291 
    292     template <> struct HasTrivialDestructor<double> : public true_type{ };
    293     template <> struct HasTrivialDestructor<const double> : public true_type{ };
    294     template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
    295     template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };
    296 
    297     template <> struct HasTrivialDestructor<long double> : public true_type{ };
    298     template <> struct HasTrivialDestructor<const long double> : public true_type{ };
    299     template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
    300     template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };
    301 
    302     template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
    303     template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
    304     template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
    305     template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };
    306 
    307     template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
    308     template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
    309     template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
    310     template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };
    311 
    312     template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
    313     template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
    314     template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
    315     template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };
    316 
    317     template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
    318     template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
    319     template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
    320     template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };
    321 
    322     template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
    323     template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
    324     template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
    325     template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };
    326 
    327     template <> struct HasTrivialDestructor<signed char> : public true_type{ };
    328     template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
    329     template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
    330     template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };
    331 
    332     template <> struct HasTrivialDestructor<signed short> : public true_type{ };
    333     template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
    334     template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
    335     template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };
    336 
    337     template <> struct HasTrivialDestructor<signed int> : public true_type{ };
    338     template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
    339     template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
    340     template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };
    341 
    342     template <> struct HasTrivialDestructor<signed long> : public true_type{ };
    343     template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
    344     template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
    345     template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };
    346 
    347     template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
    348     template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
    349     template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
    350     template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };
    351 
    352     template <> struct HasTrivialDestructor<bool> : public true_type{ };
    353     template <> struct HasTrivialDestructor<const bool> : public true_type{ };
    354     template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
    355     template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };
    356 
    357     template <> struct HasTrivialDestructor<char> : public true_type{ };
    358     template <> struct HasTrivialDestructor<const char> : public true_type{ };
    359     template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
    360     template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };
    361 
    362     #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
    363         template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
    364         template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
    365         template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
    366         template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
    367     #endif
    368 
    369 #endif  // __GLIBCXX__, etc.
    370 
    371 } // namespace WTF
    372 
    373 #endif // TypeTraits_h
    374