Home | History | Annotate | Download | only in tr1
      1 // TR1 type_traits -*- C++ -*-
      2 
      3 // Copyright (C) 2004-2013 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 #include <bits/c++config.h>
     35 
     36 namespace std _GLIBCXX_VISIBILITY(default)
     37 {
     38 namespace tr1
     39 {
     40 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     41 
     42   /**
     43    * @addtogroup metaprogramming
     44    * @{
     45    */
     46 
     47   struct __sfinae_types
     48   {
     49     typedef char __one;
     50     typedef struct { char __arr[2]; } __two;
     51   };
     52 
     53 #define _DEFINE_SPEC_0_HELPER                          \
     54   template<>
     55 
     56 #define _DEFINE_SPEC_1_HELPER                          \
     57   template<typename _Tp>
     58 
     59 #define _DEFINE_SPEC_2_HELPER                          \
     60   template<typename _Tp, typename _Cp>
     61 
     62 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
     63   _DEFINE_SPEC_##_Order##_HELPER                       \
     64     struct _Trait<_Type>                               \
     65     : public integral_constant<bool, _Value> { };
     66 
     67   // helper classes [4.3].
     68 
     69   /// integral_constant
     70   template<typename _Tp, _Tp __v>
     71     struct integral_constant
     72     {
     73       static const _Tp                      value = __v;
     74       typedef _Tp                           value_type;
     75       typedef integral_constant<_Tp, __v>   type;
     76     };
     77   
     78   /// typedef for true_type
     79   typedef integral_constant<bool, true>     true_type;
     80 
     81   /// typedef for false_type
     82   typedef integral_constant<bool, false>    false_type;
     83 
     84   template<typename _Tp, _Tp __v>
     85     const _Tp integral_constant<_Tp, __v>::value;
     86 
     87   /// remove_cv
     88   template<typename>
     89     struct remove_cv;
     90 
     91   template<typename>
     92     struct __is_void_helper
     93     : public false_type { };
     94   _DEFINE_SPEC(0, __is_void_helper, void, true)
     95 
     96   // primary type categories [4.5.1].
     97 
     98   /// is_void
     99   template<typename _Tp>
    100     struct is_void
    101     : public integral_constant<bool, (__is_void_helper<typename
    102 				      remove_cv<_Tp>::type>::value)>
    103     { };
    104 
    105   template<typename>
    106     struct __is_integral_helper
    107     : public false_type { };
    108   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
    109   _DEFINE_SPEC(0, __is_integral_helper, char, true)
    110   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
    111   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
    112 #ifdef _GLIBCXX_USE_WCHAR_T
    113   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
    114 #endif
    115   _DEFINE_SPEC(0, __is_integral_helper, short, true)
    116   _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
    117   _DEFINE_SPEC(0, __is_integral_helper, int, true)
    118   _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
    119   _DEFINE_SPEC(0, __is_integral_helper, long, true)
    120   _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
    121   _DEFINE_SPEC(0, __is_integral_helper, long long, true)
    122   _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
    123 
    124   /// is_integral
    125   template<typename _Tp>
    126     struct is_integral
    127     : public integral_constant<bool, (__is_integral_helper<typename
    128 				      remove_cv<_Tp>::type>::value)>
    129     { };
    130 
    131   template<typename>
    132     struct __is_floating_point_helper
    133     : public false_type { };
    134   _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
    135   _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
    136   _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
    137 
    138   /// is_floating_point
    139   template<typename _Tp>
    140     struct is_floating_point
    141     : public integral_constant<bool, (__is_floating_point_helper<typename
    142 				      remove_cv<_Tp>::type>::value)>
    143     { };
    144 
    145   /// is_array
    146   template<typename>
    147     struct is_array
    148     : public false_type { };
    149 
    150   template<typename _Tp, std::size_t _Size>
    151     struct is_array<_Tp[_Size]>
    152     : public true_type { };
    153 
    154   template<typename _Tp>
    155     struct is_array<_Tp[]>
    156     : public true_type { };
    157 
    158   template<typename>
    159     struct __is_pointer_helper
    160     : public false_type { };
    161   _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
    162 
    163   /// is_pointer
    164   template<typename _Tp>
    165     struct is_pointer
    166     : public integral_constant<bool, (__is_pointer_helper<typename
    167 				      remove_cv<_Tp>::type>::value)>
    168     { };
    169 
    170   /// is_reference
    171   template<typename _Tp>
    172     struct is_reference;
    173 
    174   /// is_function
    175   template<typename _Tp>
    176     struct is_function;
    177 
    178   template<typename>
    179     struct __is_member_object_pointer_helper
    180     : public false_type { };
    181   _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
    182 	       !is_function<_Tp>::value)
    183 
    184   /// is_member_object_pointer
    185   template<typename _Tp>
    186     struct is_member_object_pointer
    187     : public integral_constant<bool, (__is_member_object_pointer_helper<
    188 				      typename remove_cv<_Tp>::type>::value)>
    189     { };
    190 
    191   template<typename>
    192     struct __is_member_function_pointer_helper
    193     : public false_type { };
    194   _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
    195 	       is_function<_Tp>::value)
    196 
    197   /// is_member_function_pointer
    198   template<typename _Tp>
    199     struct is_member_function_pointer
    200     : public integral_constant<bool, (__is_member_function_pointer_helper<
    201 				      typename remove_cv<_Tp>::type>::value)>
    202     { };
    203 
    204   /// is_enum
    205   template<typename _Tp>
    206     struct is_enum
    207     : public integral_constant<bool, __is_enum(_Tp)>
    208     { };
    209 
    210   /// is_union
    211   template<typename _Tp>
    212     struct is_union
    213     : public integral_constant<bool, __is_union(_Tp)>
    214     { };
    215 
    216   /// is_class
    217   template<typename _Tp>
    218     struct is_class
    219     : public integral_constant<bool, __is_class(_Tp)>
    220     { };
    221 
    222   /// is_function
    223   template<typename>
    224     struct is_function
    225     : public false_type { };
    226   template<typename _Res, typename... _ArgTypes>
    227     struct is_function<_Res(_ArgTypes...)>
    228     : public true_type { };
    229   template<typename _Res, typename... _ArgTypes>
    230     struct is_function<_Res(_ArgTypes......)>
    231     : public true_type { };
    232   template<typename _Res, typename... _ArgTypes>
    233     struct is_function<_Res(_ArgTypes...) const>
    234     : public true_type { };
    235   template<typename _Res, typename... _ArgTypes>
    236     struct is_function<_Res(_ArgTypes......) const>
    237     : public true_type { };
    238   template<typename _Res, typename... _ArgTypes>
    239     struct is_function<_Res(_ArgTypes...) volatile>
    240     : public true_type { };
    241   template<typename _Res, typename... _ArgTypes>
    242     struct is_function<_Res(_ArgTypes......) volatile>
    243     : public true_type { };
    244   template<typename _Res, typename... _ArgTypes>
    245     struct is_function<_Res(_ArgTypes...) const volatile>
    246     : public true_type { };
    247   template<typename _Res, typename... _ArgTypes>
    248     struct is_function<_Res(_ArgTypes......) const volatile>
    249     : public true_type { };
    250 
    251   // composite type traits [4.5.2].
    252   
    253   /// is_arithmetic
    254   template<typename _Tp>
    255     struct is_arithmetic
    256     : public integral_constant<bool, (is_integral<_Tp>::value
    257 				      || is_floating_point<_Tp>::value)>
    258     { };
    259 
    260   /// is_fundamental
    261   template<typename _Tp>
    262     struct is_fundamental
    263     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    264 				      || is_void<_Tp>::value)>
    265     { };
    266 
    267   /// is_object
    268   template<typename _Tp>
    269     struct is_object
    270     : public integral_constant<bool, !(is_function<_Tp>::value
    271 				       || is_reference<_Tp>::value
    272 				       || is_void<_Tp>::value)>
    273     { };
    274 
    275   /// is_member_pointer
    276   template<typename _Tp>
    277     struct is_member_pointer;
    278 
    279   /// is_scalar
    280   template<typename _Tp>
    281     struct is_scalar
    282     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    283 				      || is_enum<_Tp>::value
    284 				      || is_pointer<_Tp>::value
    285 				      || is_member_pointer<_Tp>::value)>
    286     { };
    287 
    288   /// is_compound
    289   template<typename _Tp>
    290     struct is_compound
    291     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
    292 
    293   /// is_member_pointer
    294   template<typename _Tp>
    295     struct __is_member_pointer_helper
    296     : public false_type { };
    297   _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
    298 
    299   template<typename _Tp>
    300   struct is_member_pointer
    301     : public integral_constant<bool, (__is_member_pointer_helper<
    302 				      typename remove_cv<_Tp>::type>::value)>
    303     { };
    304 
    305   // type properties [4.5.3].
    306   /// is_const
    307   template<typename>
    308     struct is_const
    309     : public false_type { };
    310 
    311   template<typename _Tp>
    312     struct is_const<_Tp const>
    313     : public true_type { };
    314   
    315   /// is_volatile
    316   template<typename>
    317     struct is_volatile
    318     : public false_type { };
    319 
    320   template<typename _Tp>
    321     struct is_volatile<_Tp volatile>
    322     : public true_type { };
    323 
    324   /// is_empty
    325   template<typename _Tp>
    326     struct is_empty
    327     : public integral_constant<bool, __is_empty(_Tp)>
    328     { };
    329 
    330   /// is_polymorphic
    331   template<typename _Tp>
    332     struct is_polymorphic
    333     : public integral_constant<bool, __is_polymorphic(_Tp)>
    334     { };
    335 
    336   /// is_abstract
    337   template<typename _Tp>
    338     struct is_abstract
    339     : public integral_constant<bool, __is_abstract(_Tp)>
    340     { };
    341 
    342   /// has_virtual_destructor
    343   template<typename _Tp>
    344     struct has_virtual_destructor
    345     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
    346     { };
    347 
    348   /// alignment_of
    349   template<typename _Tp>
    350     struct alignment_of
    351     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
    352   
    353   /// rank
    354   template<typename>
    355     struct rank
    356     : public integral_constant<std::size_t, 0> { };
    357    
    358   template<typename _Tp, std::size_t _Size>
    359     struct rank<_Tp[_Size]>
    360     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    361 
    362   template<typename _Tp>
    363     struct rank<_Tp[]>
    364     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    365 
    366   /// extent
    367   template<typename, unsigned _Uint = 0>
    368     struct extent
    369     : public integral_constant<std::size_t, 0> { };
    370   
    371   template<typename _Tp, unsigned _Uint, std::size_t _Size>
    372     struct extent<_Tp[_Size], _Uint>
    373     : public integral_constant<std::size_t,
    374 			       _Uint == 0 ? _Size : extent<_Tp,
    375 							   _Uint - 1>::value>
    376     { };
    377 
    378   template<typename _Tp, unsigned _Uint>
    379     struct extent<_Tp[], _Uint>
    380     : public integral_constant<std::size_t,
    381 			       _Uint == 0 ? 0 : extent<_Tp,
    382 						       _Uint - 1>::value>
    383     { };
    384 
    385   // relationships between types [4.6].
    386 
    387   /// is_same
    388   template<typename, typename>
    389     struct is_same
    390     : public false_type { };
    391 
    392   template<typename _Tp>
    393     struct is_same<_Tp, _Tp>
    394     : public true_type { };
    395 
    396   // const-volatile modifications [4.7.1].
    397 
    398   /// remove_const
    399   template<typename _Tp>
    400     struct remove_const
    401     { typedef _Tp     type; };
    402 
    403   template<typename _Tp>
    404     struct remove_const<_Tp const>
    405     { typedef _Tp     type; };
    406   
    407   /// remove_volatile
    408   template<typename _Tp>
    409     struct remove_volatile
    410     { typedef _Tp     type; };
    411 
    412   template<typename _Tp>
    413     struct remove_volatile<_Tp volatile>
    414     { typedef _Tp     type; };
    415   
    416   /// remove_cv
    417   template<typename _Tp>
    418     struct remove_cv
    419     {
    420       typedef typename
    421       remove_const<typename remove_volatile<_Tp>::type>::type     type;
    422     };
    423   
    424   /// add_const
    425   template<typename _Tp>
    426     struct add_const
    427     { typedef _Tp const     type; };
    428    
    429   /// add_volatile
    430   template<typename _Tp>
    431     struct add_volatile
    432     { typedef _Tp volatile     type; };
    433   
    434   /// add_cv
    435   template<typename _Tp>
    436     struct add_cv
    437     {
    438       typedef typename
    439       add_const<typename add_volatile<_Tp>::type>::type     type;
    440     };
    441 
    442   // array modifications [4.7.3].
    443 
    444   /// remove_extent
    445   template<typename _Tp>
    446     struct remove_extent
    447     { typedef _Tp     type; };
    448 
    449   template<typename _Tp, std::size_t _Size>
    450     struct remove_extent<_Tp[_Size]>
    451     { typedef _Tp     type; };
    452 
    453   template<typename _Tp>
    454     struct remove_extent<_Tp[]>
    455     { typedef _Tp     type; };
    456 
    457   /// remove_all_extents
    458   template<typename _Tp>
    459     struct remove_all_extents
    460     { typedef _Tp     type; };
    461 
    462   template<typename _Tp, std::size_t _Size>
    463     struct remove_all_extents<_Tp[_Size]>
    464     { typedef typename remove_all_extents<_Tp>::type     type; };
    465 
    466   template<typename _Tp>
    467     struct remove_all_extents<_Tp[]>
    468     { typedef typename remove_all_extents<_Tp>::type     type; };
    469 
    470   // pointer modifications [4.7.4].
    471 
    472   template<typename _Tp, typename>
    473     struct __remove_pointer_helper
    474     { typedef _Tp     type; };
    475 
    476   template<typename _Tp, typename _Up>
    477     struct __remove_pointer_helper<_Tp, _Up*>
    478     { typedef _Up     type; };
    479 
    480   /// remove_pointer
    481   template<typename _Tp>
    482     struct remove_pointer
    483     : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
    484     { };
    485 
    486   template<typename>
    487     struct remove_reference;
    488 
    489   /// add_pointer
    490   template<typename _Tp>
    491     struct add_pointer
    492     { typedef typename remove_reference<_Tp>::type*     type; };
    493 
    494   template<typename>
    495     struct is_reference
    496     : public false_type { };
    497 
    498   template<typename _Tp>
    499     struct is_reference<_Tp&>
    500     : public true_type { };
    501 
    502   template<typename _Tp>
    503     struct is_pod
    504     : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
    505     { };
    506 
    507   template<typename _Tp>
    508     struct has_trivial_constructor
    509     : public integral_constant<bool, is_pod<_Tp>::value>
    510     { };
    511 
    512   template<typename _Tp>
    513     struct has_trivial_copy
    514     : public integral_constant<bool, is_pod<_Tp>::value>
    515     { };
    516 
    517   template<typename _Tp>
    518     struct has_trivial_assign
    519     : public integral_constant<bool, is_pod<_Tp>::value>
    520     { };
    521 
    522   template<typename _Tp>
    523     struct has_trivial_destructor
    524     : public integral_constant<bool, is_pod<_Tp>::value>
    525     { };
    526 
    527   template<typename _Tp>
    528     struct has_nothrow_constructor
    529     : public integral_constant<bool, is_pod<_Tp>::value>
    530     { };
    531 
    532   template<typename _Tp>
    533     struct has_nothrow_copy
    534     : public integral_constant<bool, is_pod<_Tp>::value>
    535     { };
    536 
    537   template<typename _Tp>
    538     struct has_nothrow_assign
    539     : public integral_constant<bool, is_pod<_Tp>::value>
    540     { };
    541 
    542   template<typename>
    543     struct __is_signed_helper
    544     : public false_type { };
    545   _DEFINE_SPEC(0, __is_signed_helper, signed char, true)
    546   _DEFINE_SPEC(0, __is_signed_helper, short, true)
    547   _DEFINE_SPEC(0, __is_signed_helper, int, true)
    548   _DEFINE_SPEC(0, __is_signed_helper, long, true)
    549   _DEFINE_SPEC(0, __is_signed_helper, long long, true)
    550 
    551   template<typename _Tp>
    552     struct is_signed
    553     : public integral_constant<bool, (__is_signed_helper<typename
    554 				      remove_cv<_Tp>::type>::value)>
    555     { };
    556 
    557   template<typename>
    558     struct __is_unsigned_helper
    559     : public false_type { };
    560   _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true)
    561   _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true)
    562   _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true)
    563   _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true)
    564   _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true)
    565 
    566   template<typename _Tp>
    567     struct is_unsigned
    568     : public integral_constant<bool, (__is_unsigned_helper<typename
    569 				      remove_cv<_Tp>::type>::value)>
    570     { };
    571 
    572   template<typename _Base, typename _Derived>
    573     struct __is_base_of_helper
    574     {
    575       typedef typename remove_cv<_Base>::type    _NoCv_Base;
    576       typedef typename remove_cv<_Derived>::type _NoCv_Derived;
    577       static const bool __value = (is_same<_Base, _Derived>::value
    578 				   || (__is_base_of(_Base, _Derived)
    579 				       && !is_same<_NoCv_Base,
    580 				                   _NoCv_Derived>::value));
    581     };
    582  
    583   template<typename _Base, typename _Derived>
    584     struct is_base_of
    585     : public integral_constant<bool,
    586 			       __is_base_of_helper<_Base, _Derived>::__value>
    587     { };
    588 
    589   template<typename _From, typename _To>
    590     struct __is_convertible_simple
    591     : public __sfinae_types
    592     {
    593     private:
    594       static __one __test(_To);
    595       static __two __test(...);
    596       static _From __makeFrom();
    597     
    598     public:
    599       static const bool __value = sizeof(__test(__makeFrom())) == 1;
    600     };
    601 
    602   template<typename _Tp>
    603     struct add_reference;
    604 
    605   template<typename _Tp>
    606     struct __is_int_or_cref
    607     {
    608       typedef typename remove_reference<_Tp>::type __rr_Tp;
    609       static const bool __value = (is_integral<_Tp>::value
    610 				   || (is_integral<__rr_Tp>::value
    611 				       && is_const<__rr_Tp>::value
    612 				       && !is_volatile<__rr_Tp>::value));
    613     };
    614 
    615   template<typename _From, typename _To,
    616 	   bool = (is_void<_From>::value || is_void<_To>::value
    617 		   || is_function<_To>::value || is_array<_To>::value
    618 		   // This special case is here only to avoid warnings.	
    619 		   || (is_floating_point<typename
    620 		       remove_reference<_From>::type>::value
    621 		       && __is_int_or_cref<_To>::__value))>
    622     struct __is_convertible_helper
    623     {
    624       // "An imaginary lvalue of type From...".
    625       static const bool __value = (__is_convertible_simple<typename
    626 				   add_reference<_From>::type, _To>::__value);
    627     };
    628 
    629   template<typename _From, typename _To>
    630     struct __is_convertible_helper<_From, _To, true>
    631     { static const bool __value = (is_void<_To>::value
    632 				   || (__is_int_or_cref<_To>::__value
    633 				       && !is_void<_From>::value)); };
    634 
    635   template<typename _From, typename _To>
    636     struct is_convertible
    637     : public integral_constant<bool,
    638 			       __is_convertible_helper<_From, _To>::__value>
    639     { };
    640 
    641   // reference modifications [4.7.2].
    642   template<typename _Tp>
    643     struct remove_reference
    644     { typedef _Tp     type; };
    645 
    646   template<typename _Tp>
    647     struct remove_reference<_Tp&>
    648     { typedef _Tp     type; };
    649 
    650   // NB: Careful with reference to void.
    651   template<typename _Tp, bool = (is_void<_Tp>::value
    652 				 || is_reference<_Tp>::value)>
    653     struct __add_reference_helper
    654     { typedef _Tp&    type; };
    655 
    656   template<typename _Tp>
    657     struct __add_reference_helper<_Tp, true>
    658     { typedef _Tp     type; };
    659 
    660   template<typename _Tp>
    661     struct add_reference
    662     : public __add_reference_helper<_Tp>
    663     { };
    664 
    665   // other transformations [4.8].
    666   template<std::size_t _Len, std::size_t _Align>
    667     struct aligned_storage
    668     { 
    669       union type
    670       {
    671 	unsigned char __data[_Len];
    672 	struct __attribute__((__aligned__((_Align)))) { } __align; 
    673       };
    674     };
    675 
    676 #undef _DEFINE_SPEC_0_HELPER
    677 #undef _DEFINE_SPEC_1_HELPER
    678 #undef _DEFINE_SPEC_2_HELPER
    679 #undef _DEFINE_SPEC
    680 
    681   /// @} group metaprogramming
    682 
    683 _GLIBCXX_END_NAMESPACE_VERSION
    684 }
    685 }
    686 
    687 #endif // _GLIBCXX_TR1_TYPE_TRAITS
    688