Home | History | Annotate | Download | only in tr1
      1 // TR1 type_traits -*- C++ -*-
      2 
      3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file tr1/type_traits
     26  *  This is a TR1 C++ Library header. 
     27  */
     28 
     29 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
     30 #define _GLIBCXX_TR1_TYPE_TRAITS 1
     31 
     32 #pragma GCC system_header
     33 
     34 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
     35 #  error TR1 header cannot be included from C++0x header
     36 #endif
     37 
     38 #include <cstddef>
     39 
     40 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
     41 #  include <tr1_impl/type_traits>
     42 #else
     43 #  define _GLIBCXX_INCLUDE_AS_TR1
     44 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
     45 #  define _GLIBCXX_END_NAMESPACE_TR1 }
     46 #  define _GLIBCXX_TR1 tr1::
     47 #  include <tr1_impl/type_traits>
     48 #  undef _GLIBCXX_TR1
     49 #  undef _GLIBCXX_END_NAMESPACE_TR1
     50 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
     51 #  undef _GLIBCXX_INCLUDE_AS_TR1
     52 #endif
     53 
     54 namespace std
     55 {
     56 namespace tr1
     57 {
     58 #define _DEFINE_SPEC(_Trait, _Type)    \
     59   template<>                           \
     60     struct _Trait<_Type>	       \
     61     : public true_type { };
     62 
     63   template<typename>
     64     struct is_reference
     65     : public false_type { };
     66 
     67   template<typename _Tp>
     68     struct is_reference<_Tp&>
     69     : public true_type { };
     70 
     71   template<typename _Tp>
     72     struct is_pod
     73     : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
     74     { };
     75 
     76   template<typename _Tp>
     77     struct has_trivial_constructor
     78     : public integral_constant<bool, is_pod<_Tp>::value>
     79     { };
     80 
     81   template<typename _Tp>
     82     struct has_trivial_copy
     83     : public integral_constant<bool, is_pod<_Tp>::value>
     84     { };
     85 
     86   template<typename _Tp>
     87     struct has_trivial_assign
     88     : public integral_constant<bool, is_pod<_Tp>::value>
     89     { };
     90 
     91   template<typename _Tp>
     92     struct has_trivial_destructor
     93     : public integral_constant<bool, is_pod<_Tp>::value>
     94     { };
     95 
     96   template<typename _Tp>
     97     struct has_nothrow_constructor
     98     : public integral_constant<bool, is_pod<_Tp>::value>
     99     { };
    100 
    101   template<typename _Tp>
    102     struct has_nothrow_copy
    103     : public integral_constant<bool, is_pod<_Tp>::value>
    104     { };
    105 
    106   template<typename _Tp>
    107     struct has_nothrow_assign
    108     : public integral_constant<bool, is_pod<_Tp>::value>
    109     { };
    110 
    111   template<typename>
    112     struct __is_signed_helper
    113     : public false_type { };
    114   _DEFINE_SPEC(__is_signed_helper, signed char)
    115   _DEFINE_SPEC(__is_signed_helper, short)
    116   _DEFINE_SPEC(__is_signed_helper, int)
    117   _DEFINE_SPEC(__is_signed_helper, long)
    118   _DEFINE_SPEC(__is_signed_helper, long long)
    119 
    120   template<typename _Tp>
    121     struct is_signed
    122     : public integral_constant<bool, (__is_signed_helper<typename
    123 				      remove_cv<_Tp>::type>::value)>
    124     { };
    125 
    126   template<typename>
    127     struct __is_unsigned_helper
    128     : public false_type { };
    129   _DEFINE_SPEC(__is_unsigned_helper, unsigned char)
    130   _DEFINE_SPEC(__is_unsigned_helper, unsigned short)
    131   _DEFINE_SPEC(__is_unsigned_helper, unsigned int)
    132   _DEFINE_SPEC(__is_unsigned_helper, unsigned long)
    133   _DEFINE_SPEC(__is_unsigned_helper, unsigned long long)
    134 
    135   template<typename _Tp>
    136     struct is_unsigned
    137     : public integral_constant<bool, (__is_unsigned_helper<typename
    138 				      remove_cv<_Tp>::type>::value)>
    139     { };
    140 
    141   template<typename _Base, typename _Derived>
    142     struct __is_base_of_helper
    143     {
    144       typedef typename remove_cv<_Base>::type    _NoCv_Base;
    145       typedef typename remove_cv<_Derived>::type _NoCv_Derived;
    146       static const bool __value = (is_same<_Base, _Derived>::value
    147 				   || (__is_base_of(_Base, _Derived)
    148 				       && !is_same<_NoCv_Base,
    149 				                   _NoCv_Derived>::value));
    150     };
    151  
    152   template<typename _Base, typename _Derived>
    153     struct is_base_of
    154     : public integral_constant<bool,
    155 			       __is_base_of_helper<_Base, _Derived>::__value>
    156     { };
    157 
    158   template<typename _From, typename _To>
    159     struct __is_convertible_simple
    160     : public __sfinae_types
    161     {
    162     private:
    163       static __one __test(_To);
    164       static __two __test(...);
    165       static _From __makeFrom();
    166     
    167     public:
    168       static const bool __value = sizeof(__test(__makeFrom())) == 1;
    169     };
    170 
    171   template<typename _Tp>
    172     struct add_reference;
    173 
    174   template<typename _Tp>
    175     struct __is_int_or_cref
    176     {
    177       typedef typename remove_reference<_Tp>::type __rr_Tp;
    178       static const bool __value = (is_integral<_Tp>::value
    179 				   || (is_integral<__rr_Tp>::value
    180 				       && is_const<__rr_Tp>::value
    181 				       && !is_volatile<__rr_Tp>::value));
    182     };
    183 
    184   template<typename _From, typename _To,
    185 	   bool = (is_void<_From>::value || is_void<_To>::value
    186 		   || is_function<_To>::value || is_array<_To>::value
    187 		   // This special case is here only to avoid warnings.	
    188 		   || (is_floating_point<typename
    189 		       remove_reference<_From>::type>::value
    190 		       && __is_int_or_cref<_To>::__value))>
    191     struct __is_convertible_helper
    192     {
    193       // "An imaginary lvalue of type From...".
    194       static const bool __value = (__is_convertible_simple<typename
    195 				   add_reference<_From>::type, _To>::__value);
    196     };
    197 
    198   template<typename _From, typename _To>
    199     struct __is_convertible_helper<_From, _To, true>
    200     { static const bool __value = (is_void<_To>::value
    201 				   || (__is_int_or_cref<_To>::__value
    202 				       && !is_void<_From>::value)); };
    203 
    204   template<typename _From, typename _To>
    205     struct is_convertible
    206     : public integral_constant<bool,
    207 			       __is_convertible_helper<_From, _To>::__value>
    208     { };
    209 
    210   // reference modifications [4.7.2].
    211   template<typename _Tp>
    212     struct remove_reference
    213     { typedef _Tp     type; };
    214 
    215   template<typename _Tp>
    216     struct remove_reference<_Tp&>
    217     { typedef _Tp     type; };
    218 
    219   // NB: Careful with reference to void.
    220   template<typename _Tp, bool = (is_void<_Tp>::value
    221 				 || is_reference<_Tp>::value)>
    222     struct __add_reference_helper
    223     { typedef _Tp&    type; };
    224 
    225   template<typename _Tp>
    226     struct __add_reference_helper<_Tp, true>
    227     { typedef _Tp     type; };
    228 
    229   template<typename _Tp>
    230     struct add_reference
    231     : public __add_reference_helper<_Tp>
    232     { };
    233 
    234   // other transformations [4.8].
    235   template<std::size_t _Len, std::size_t _Align>
    236     struct aligned_storage
    237     { 
    238       union type
    239       {
    240 	unsigned char __data[_Len];
    241 	struct __attribute__((__aligned__((_Align)))) { } __align; 
    242       };
    243     };
    244 
    245 #undef _DEFINE_SPEC
    246 }
    247 }
    248 
    249 #endif // _GLIBCXX_TR1_TYPE_TRAITS
    250