Home | History | Annotate | Download | only in tr1_impl
      1 // TR1 type_traits -*- C++ -*-
      2 
      3 // Copyright (C) 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_impl/type_traits
     26 *  This is an internal header file, included by other library headers.
     27 *  You should not attempt to use it directly.
     28 */
     29 
     30 namespace std
     31 {
     32 _GLIBCXX_BEGIN_NAMESPACE_TR1
     33 
     34   /**
     35    * @defgroup metaprogramming Type Traits
     36    * @ingroup utilities
     37    *
     38    * Compile time type transformation and information.
     39    * @{
     40    */
     41 
     42   // For use in __is_convertible_simple.
     43   struct __sfinae_types
     44   {
     45     typedef char __one;
     46     typedef struct { char __arr[2]; } __two;
     47   };
     48 
     49 #define _DEFINE_SPEC_0_HELPER                          \
     50   template<>
     51 
     52 #define _DEFINE_SPEC_1_HELPER                          \
     53   template<typename _Tp>
     54 
     55 #define _DEFINE_SPEC_2_HELPER                          \
     56   template<typename _Tp, typename _Cp>
     57 
     58 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
     59   _DEFINE_SPEC_##_Order##_HELPER                       \
     60     struct _Trait<_Type>                               \
     61     : public integral_constant<bool, _Value> { };
     62 
     63   // helper classes [4.3].
     64 
     65   /// integral_constant
     66   template<typename _Tp, _Tp __v>
     67     struct integral_constant
     68     {
     69       static const _Tp                      value = __v;
     70       typedef _Tp                           value_type;
     71       typedef integral_constant<_Tp, __v>   type;
     72     };
     73   
     74   /// typedef for true_type
     75   typedef integral_constant<bool, true>     true_type;
     76 
     77   /// typedef for false_type
     78   typedef integral_constant<bool, false>    false_type;
     79 
     80   template<typename _Tp, _Tp __v>
     81     const _Tp integral_constant<_Tp, __v>::value;
     82 
     83   /// remove_cv
     84   template<typename>
     85     struct remove_cv;
     86 
     87   template<typename>
     88     struct __is_void_helper
     89     : public false_type { };
     90   _DEFINE_SPEC(0, __is_void_helper, void, true)
     91 
     92   // primary type categories [4.5.1].
     93 
     94   /// is_void
     95   template<typename _Tp>
     96     struct is_void
     97     : public integral_constant<bool, (__is_void_helper<typename
     98 				      remove_cv<_Tp>::type>::value)>
     99     { };
    100 
    101   template<typename>
    102     struct __is_integral_helper
    103     : public false_type { };
    104   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
    105   _DEFINE_SPEC(0, __is_integral_helper, char, true)
    106   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
    107   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
    108 #ifdef _GLIBCXX_USE_WCHAR_T
    109   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
    110 #endif
    111 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    112   _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
    113   _DEFINE_SPEC(0, __is_integral_helper, char32_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 #undef _DEFINE_SPEC_0_HELPER
    495 #undef _DEFINE_SPEC_1_HELPER
    496 #undef _DEFINE_SPEC_2_HELPER
    497 #undef _DEFINE_SPEC
    498 
    499   // @} group metaprogramming
    500 _GLIBCXX_END_NAMESPACE_TR1
    501 }
    502