Home | History | Annotate | Download | only in 4.6.x-google
      1 // C++0x type_traits -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009, 2010 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 include/type_traits
     26  *  This is a Standard C++ Library header.
     27  */
     28 
     29 #ifndef _GLIBCXX_TYPE_TRAITS
     30 #define _GLIBCXX_TYPE_TRAITS 1
     31 
     32 #pragma GCC system_header
     33 
     34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
     35 # include <bits/c++0x_warning.h>
     36 #else
     37 
     38 #include <bits/c++config.h>
     39 
     40 namespace std _GLIBCXX_VISIBILITY(default)
     41 {
     42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     43 
     44   /**
     45    * @addtogroup metaprogramming
     46    * @{
     47    */
     48   struct __sfinae_types
     49   {
     50     typedef char __one;
     51     typedef struct { char __arr[2]; } __two;
     52   };
     53 
     54 #define _DEFINE_SPEC_0_HELPER                          \
     55   template<>
     56 
     57 #define _DEFINE_SPEC_1_HELPER                          \
     58   template<typename _Tp>
     59 
     60 #define _DEFINE_SPEC_2_HELPER                          \
     61   template<typename _Tp, typename _Cp>
     62 
     63 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
     64   _DEFINE_SPEC_##_Order##_HELPER                       \
     65     struct _Trait<_Type>                               \
     66     : public integral_constant<bool, _Value> { };
     67 
     68   // helper classes.
     69 
     70   /// integral_constant
     71   template<typename _Tp, _Tp __v>
     72     struct integral_constant
     73     {
     74       static constexpr _Tp                  value = __v;
     75       typedef _Tp                           value_type;
     76       typedef integral_constant<_Tp, __v>   type;
     77       constexpr operator value_type() { return value; }
     78     };
     79   
     80   /// typedef for true_type
     81   typedef integral_constant<bool, true>     true_type;
     82 
     83   /// typedef for false_type
     84   typedef integral_constant<bool, false>    false_type;
     85 
     86   template<typename _Tp, _Tp __v>
     87     constexpr _Tp integral_constant<_Tp, __v>::value;
     88 
     89   /// remove_cv
     90   template<typename>
     91     struct remove_cv;
     92 
     93   template<typename>
     94     struct __is_void_helper
     95     : public false_type { };
     96   _DEFINE_SPEC(0, __is_void_helper, void, true)
     97 
     98   // primary type categories.
     99 
    100   /// is_void
    101   template<typename _Tp>
    102     struct is_void
    103     : public integral_constant<bool, (__is_void_helper<typename
    104 				      remove_cv<_Tp>::type>::value)>
    105     { };
    106 
    107   template<typename>
    108     struct __is_integral_helper
    109     : public false_type { };
    110   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
    111   _DEFINE_SPEC(0, __is_integral_helper, char, true)
    112   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
    113   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
    114 #ifdef _GLIBCXX_USE_WCHAR_T
    115   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
    116 #endif
    117   _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
    118   _DEFINE_SPEC(0, __is_integral_helper, char32_t, true)
    119   _DEFINE_SPEC(0, __is_integral_helper, short, true)
    120   _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
    121   _DEFINE_SPEC(0, __is_integral_helper, int, true)
    122   _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
    123   _DEFINE_SPEC(0, __is_integral_helper, long, true)
    124   _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
    125   _DEFINE_SPEC(0, __is_integral_helper, long long, true)
    126   _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
    127 
    128   /// is_integral
    129   template<typename _Tp>
    130     struct is_integral
    131     : public integral_constant<bool, (__is_integral_helper<typename
    132 				      remove_cv<_Tp>::type>::value)>
    133     { };
    134 
    135   template<typename>
    136     struct __is_floating_point_helper
    137     : public false_type { };
    138   _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
    139   _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
    140   _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
    141 
    142   /// is_floating_point
    143   template<typename _Tp>
    144     struct is_floating_point
    145     : public integral_constant<bool, (__is_floating_point_helper<typename
    146 				      remove_cv<_Tp>::type>::value)>
    147     { };
    148 
    149   /// is_array
    150   template<typename>
    151     struct is_array
    152     : public false_type { };
    153 
    154   template<typename _Tp, std::size_t _Size>
    155     struct is_array<_Tp[_Size]>
    156     : public true_type { };
    157 
    158   template<typename _Tp>
    159     struct is_array<_Tp[]>
    160     : public true_type { };
    161 
    162   template<typename>
    163     struct __is_pointer_helper
    164     : public false_type { };
    165   _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
    166 
    167   /// is_pointer
    168   template<typename _Tp>
    169     struct is_pointer
    170     : public integral_constant<bool, (__is_pointer_helper<typename
    171 				      remove_cv<_Tp>::type>::value)>
    172     { };
    173 
    174   /// is_reference
    175   template<typename _Tp>
    176     struct is_reference;
    177 
    178   /// is_function
    179   template<typename _Tp>
    180     struct is_function;
    181 
    182   template<typename>
    183     struct __is_member_object_pointer_helper
    184     : public false_type { };
    185   _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
    186 	       !is_function<_Tp>::value)
    187 
    188   /// is_member_object_pointer
    189   template<typename _Tp>
    190     struct is_member_object_pointer
    191     : public integral_constant<bool, (__is_member_object_pointer_helper<
    192 				      typename remove_cv<_Tp>::type>::value)>
    193     { };
    194 
    195   template<typename>
    196     struct __is_member_function_pointer_helper
    197     : public false_type { };
    198   _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
    199 	       is_function<_Tp>::value)
    200 
    201   /// is_member_function_pointer
    202   template<typename _Tp>
    203     struct is_member_function_pointer
    204     : public integral_constant<bool, (__is_member_function_pointer_helper<
    205 				      typename remove_cv<_Tp>::type>::value)>
    206     { };
    207 
    208   /// is_enum
    209   template<typename _Tp>
    210     struct is_enum
    211     : public integral_constant<bool, __is_enum(_Tp)>
    212     { };
    213 
    214   /// is_union
    215   template<typename _Tp>
    216     struct is_union
    217     : public integral_constant<bool, __is_union(_Tp)>
    218     { };
    219 
    220   /// is_class
    221   template<typename _Tp>
    222     struct is_class
    223     : public integral_constant<bool, __is_class(_Tp)>
    224     { };
    225 
    226   /// is_function
    227   template<typename>
    228     struct is_function
    229     : public false_type { };
    230   template<typename _Res, typename... _ArgTypes>
    231     struct is_function<_Res(_ArgTypes...)>
    232     : public true_type { };
    233   template<typename _Res, typename... _ArgTypes>
    234     struct is_function<_Res(_ArgTypes......)>
    235     : public true_type { };
    236   template<typename _Res, typename... _ArgTypes>
    237     struct is_function<_Res(_ArgTypes...) const>
    238     : public true_type { };
    239   template<typename _Res, typename... _ArgTypes>
    240     struct is_function<_Res(_ArgTypes......) const>
    241     : public true_type { };
    242   template<typename _Res, typename... _ArgTypes>
    243     struct is_function<_Res(_ArgTypes...) volatile>
    244     : public true_type { };
    245   template<typename _Res, typename... _ArgTypes>
    246     struct is_function<_Res(_ArgTypes......) volatile>
    247     : public true_type { };
    248   template<typename _Res, typename... _ArgTypes>
    249     struct is_function<_Res(_ArgTypes...) const volatile>
    250     : public true_type { };
    251   template<typename _Res, typename... _ArgTypes>
    252     struct is_function<_Res(_ArgTypes......) const volatile>
    253     : public true_type { };
    254 
    255   template<typename>
    256     struct __is_nullptr_t_helper
    257     : public false_type { };
    258   _DEFINE_SPEC(0, __is_nullptr_t_helper, std::nullptr_t, true)
    259 
    260   // __is_nullptr_t (extension).
    261   template<typename _Tp>
    262     struct __is_nullptr_t
    263     : public integral_constant<bool, (__is_nullptr_t_helper<typename
    264 				      remove_cv<_Tp>::type>::value)>
    265     { };
    266 
    267   // composite type traits.
    268   
    269   /// is_arithmetic
    270   template<typename _Tp>
    271     struct is_arithmetic
    272     : public integral_constant<bool, (is_integral<_Tp>::value
    273 				      || is_floating_point<_Tp>::value)>
    274     { };
    275 
    276   /// is_fundamental
    277   template<typename _Tp>
    278     struct is_fundamental
    279     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    280 				      || is_void<_Tp>::value)>
    281     { };
    282 
    283   /// is_object
    284   template<typename _Tp>
    285     struct is_object
    286     : public integral_constant<bool, !(is_function<_Tp>::value
    287 				       || is_reference<_Tp>::value
    288 				       || is_void<_Tp>::value)>
    289     { };
    290 
    291   /// is_member_pointer
    292   template<typename _Tp>
    293     struct is_member_pointer;
    294 
    295   /// is_scalar
    296   template<typename _Tp>
    297     struct is_scalar
    298     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    299 				      || is_enum<_Tp>::value
    300 				      || is_pointer<_Tp>::value
    301 				      || is_member_pointer<_Tp>::value
    302 				      || __is_nullptr_t<_Tp>::value)>
    303     { };
    304 
    305   /// is_compound
    306   template<typename _Tp>
    307     struct is_compound
    308     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
    309 
    310   /// is_member_pointer
    311   template<typename _Tp>
    312     struct __is_member_pointer_helper
    313     : public false_type { };
    314   _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
    315 
    316   template<typename _Tp>
    317   struct is_member_pointer
    318     : public integral_constant<bool, (__is_member_pointer_helper<
    319 				      typename remove_cv<_Tp>::type>::value)>
    320     { };
    321 
    322   // type properties.
    323   /// is_const
    324   template<typename>
    325     struct is_const
    326     : public false_type { };
    327 
    328   template<typename _Tp>
    329     struct is_const<_Tp const>
    330     : public true_type { };
    331   
    332   /// is_volatile
    333   template<typename>
    334     struct is_volatile
    335     : public false_type { };
    336 
    337   template<typename _Tp>
    338     struct is_volatile<_Tp volatile>
    339     : public true_type { };
    340 
    341   /// is_empty
    342   template<typename _Tp>
    343     struct is_empty
    344     : public integral_constant<bool, __is_empty(_Tp)>
    345     { };
    346 
    347   /// is_polymorphic
    348   template<typename _Tp>
    349     struct is_polymorphic
    350     : public integral_constant<bool, __is_polymorphic(_Tp)>
    351     { };
    352 
    353   /// is_abstract
    354   template<typename _Tp>
    355     struct is_abstract
    356     : public integral_constant<bool, __is_abstract(_Tp)>
    357     { };
    358 
    359   /// has_virtual_destructor
    360   template<typename _Tp>
    361     struct has_virtual_destructor
    362     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
    363     { };
    364 
    365   /// alignment_of
    366   template<typename _Tp>
    367     struct alignment_of
    368     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
    369   
    370   /// rank
    371   template<typename>
    372     struct rank
    373     : public integral_constant<std::size_t, 0> { };
    374    
    375   template<typename _Tp, std::size_t _Size>
    376     struct rank<_Tp[_Size]>
    377     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    378 
    379   template<typename _Tp>
    380     struct rank<_Tp[]>
    381     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
    382 
    383   /// extent
    384   template<typename, unsigned _Uint = 0>
    385     struct extent
    386     : public integral_constant<std::size_t, 0> { };
    387   
    388   template<typename _Tp, unsigned _Uint, std::size_t _Size>
    389     struct extent<_Tp[_Size], _Uint>
    390     : public integral_constant<std::size_t,
    391 			       _Uint == 0 ? _Size : extent<_Tp,
    392 							   _Uint - 1>::value>
    393     { };
    394 
    395   template<typename _Tp, unsigned _Uint>
    396     struct extent<_Tp[], _Uint>
    397     : public integral_constant<std::size_t,
    398 			       _Uint == 0 ? 0 : extent<_Tp,
    399 						       _Uint - 1>::value>
    400     { };
    401 
    402   // relationships between types [4.6].
    403 
    404   /// is_same
    405   template<typename, typename>
    406     struct is_same
    407     : public false_type { };
    408 
    409   template<typename _Tp>
    410     struct is_same<_Tp, _Tp>
    411     : public true_type { };
    412 
    413   // const-volatile modifications [4.7.1].
    414 
    415   /// remove_const
    416   template<typename _Tp>
    417     struct remove_const
    418     { typedef _Tp     type; };
    419 
    420   template<typename _Tp>
    421     struct remove_const<_Tp const>
    422     { typedef _Tp     type; };
    423   
    424   /// remove_volatile
    425   template<typename _Tp>
    426     struct remove_volatile
    427     { typedef _Tp     type; };
    428 
    429   template<typename _Tp>
    430     struct remove_volatile<_Tp volatile>
    431     { typedef _Tp     type; };
    432   
    433   /// remove_cv
    434   template<typename _Tp>
    435     struct remove_cv
    436     {
    437       typedef typename
    438       remove_const<typename remove_volatile<_Tp>::type>::type     type;
    439     };
    440   
    441   /// add_const
    442   template<typename _Tp>
    443     struct add_const
    444     { typedef _Tp const     type; };
    445    
    446   /// add_volatile
    447   template<typename _Tp>
    448     struct add_volatile
    449     { typedef _Tp volatile     type; };
    450   
    451   /// add_cv
    452   template<typename _Tp>
    453     struct add_cv
    454     {
    455       typedef typename
    456       add_const<typename add_volatile<_Tp>::type>::type     type;
    457     };
    458 
    459   // array modifications.
    460 
    461   /// remove_extent
    462   template<typename _Tp>
    463     struct remove_extent
    464     { typedef _Tp     type; };
    465 
    466   template<typename _Tp, std::size_t _Size>
    467     struct remove_extent<_Tp[_Size]>
    468     { typedef _Tp     type; };
    469 
    470   template<typename _Tp>
    471     struct remove_extent<_Tp[]>
    472     { typedef _Tp     type; };
    473 
    474   /// remove_all_extents
    475   template<typename _Tp>
    476     struct remove_all_extents
    477     { typedef _Tp     type; };
    478 
    479   template<typename _Tp, std::size_t _Size>
    480     struct remove_all_extents<_Tp[_Size]>
    481     { typedef typename remove_all_extents<_Tp>::type     type; };
    482 
    483   template<typename _Tp>
    484     struct remove_all_extents<_Tp[]>
    485     { typedef typename remove_all_extents<_Tp>::type     type; };
    486 
    487   // pointer modifications.
    488 
    489   template<typename _Tp, typename>
    490     struct __remove_pointer_helper
    491     { typedef _Tp     type; };
    492 
    493   template<typename _Tp, typename _Up>
    494     struct __remove_pointer_helper<_Tp, _Up*>
    495     { typedef _Up     type; };
    496 
    497   /// remove_pointer
    498   template<typename _Tp>
    499     struct remove_pointer
    500     : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
    501     { };
    502 
    503   template<typename>
    504     struct remove_reference;
    505 
    506   /// add_pointer
    507   template<typename _Tp>
    508     struct add_pointer
    509     { typedef typename remove_reference<_Tp>::type*     type; };
    510 
    511   // Primary classification traits.
    512 
    513   /// is_lvalue_reference
    514   template<typename>
    515     struct is_lvalue_reference
    516     : public false_type { };
    517 
    518   template<typename _Tp>
    519     struct is_lvalue_reference<_Tp&>
    520     : public true_type { };
    521 
    522   /// is_rvalue_reference
    523   template<typename>
    524     struct is_rvalue_reference
    525     : public false_type { };
    526 
    527   template<typename _Tp>
    528     struct is_rvalue_reference<_Tp&&>
    529     : public true_type { };
    530 
    531   // Secondary classification traits.
    532 
    533   /// is_reference
    534   template<typename _Tp>
    535     struct is_reference
    536     : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
    537 				      || is_rvalue_reference<_Tp>::value)>
    538     { };
    539 
    540   // Reference transformations.
    541 
    542   /// remove_reference
    543   template<typename _Tp>
    544     struct remove_reference
    545     { typedef _Tp   type; };
    546 
    547   template<typename _Tp>
    548     struct remove_reference<_Tp&>
    549     { typedef _Tp   type; };
    550 
    551   template<typename _Tp>
    552     struct remove_reference<_Tp&&>
    553     { typedef _Tp   type; };
    554 
    555   template<typename _Tp,
    556 	   bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
    557 	   bool = is_rvalue_reference<_Tp>::value>
    558     struct __add_lvalue_reference_helper
    559     { typedef _Tp   type; };
    560 
    561   template<typename _Tp>
    562     struct __add_lvalue_reference_helper<_Tp, true, false>
    563     { typedef _Tp&   type; };
    564 
    565   template<typename _Tp>
    566     struct __add_lvalue_reference_helper<_Tp, false, true>
    567     { typedef typename remove_reference<_Tp>::type&   type; };
    568 
    569   /// add_lvalue_reference
    570   template<typename _Tp>
    571     struct add_lvalue_reference
    572     : public __add_lvalue_reference_helper<_Tp>
    573     { };
    574 
    575   template<typename _Tp,
    576 	   bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
    577     struct __add_rvalue_reference_helper
    578     { typedef _Tp   type; };
    579 
    580   template<typename _Tp>
    581     struct __add_rvalue_reference_helper<_Tp, true>
    582     { typedef _Tp&&   type; };
    583 
    584   /// add_rvalue_reference
    585   template<typename _Tp>
    586     struct add_rvalue_reference
    587     : public __add_rvalue_reference_helper<_Tp>
    588     { };
    589 
    590   // Scalar properties and transformations.
    591 
    592   template<typename _Tp,
    593 	   bool = is_integral<_Tp>::value,
    594 	   bool = is_floating_point<_Tp>::value>
    595     struct __is_signed_helper
    596     : public false_type { };
    597 
    598   template<typename _Tp>
    599     struct __is_signed_helper<_Tp, false, true>
    600     : public true_type { };
    601 
    602   template<typename _Tp>
    603     struct __is_signed_helper<_Tp, true, false>
    604     : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
    605     { };
    606 
    607   /// is_signed
    608   template<typename _Tp>
    609     struct is_signed
    610     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
    611     { };
    612 
    613   /// is_unsigned
    614   template<typename _Tp>
    615     struct is_unsigned
    616     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    617 				      && !is_signed<_Tp>::value)>
    618     { };
    619 
    620   // Member introspection.
    621 
    622   /// is_trivial
    623   template<typename _Tp>
    624     struct is_trivial
    625     : public integral_constant<bool, __is_trivial(_Tp)>
    626     { };
    627 
    628   /// is_standard_layout
    629   template<typename _Tp>
    630     struct is_standard_layout
    631     : public integral_constant<bool, __is_standard_layout(_Tp)>
    632     { };
    633 
    634   /// is_pod
    635   // Could use is_standard_layout && is_trivial instead of the builtin.
    636   template<typename _Tp>
    637     struct is_pod
    638     : public integral_constant<bool, __is_pod(_Tp)>
    639     { };
    640 
    641   /// is_literal_type
    642   template<typename _Tp>
    643     struct is_literal_type
    644     : public integral_constant<bool, __is_literal_type(_Tp)>
    645     { };
    646 
    647   template<typename _Tp>
    648     typename add_rvalue_reference<_Tp>::type declval() noexcept;
    649 
    650   template<typename _Tp, typename... _Args>
    651     class __is_constructible_helper
    652     : public __sfinae_types
    653     {
    654       template<typename _Tp1, typename... _Args1>
    655         static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
    656 
    657       template<typename, typename...>
    658         static __two __test(...);
    659 
    660     public:
    661       static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
    662     };
    663 
    664   template<typename _Tp, typename _Arg>
    665     class __is_constructible_helper<_Tp, _Arg>
    666     : public __sfinae_types
    667     {
    668       template<typename _Tp1, typename _Arg1>
    669         static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
    670 	__test(int);
    671 
    672       template<typename, typename>
    673         static __two __test(...);
    674 
    675     public:
    676       static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
    677     };
    678 
    679   /// is_constructible
    680   // XXX FIXME
    681   // The C++0x specifications require front-end support, see N2255.
    682   template<typename _Tp, typename... _Args>
    683     struct is_constructible
    684     : public integral_constant<bool,
    685 			       __is_constructible_helper<_Tp,
    686 							 _Args...>::__value>
    687     { };
    688 
    689   template<bool, typename _Tp, typename... _Args>
    690     struct __is_nt_constructible_helper
    691     { static const bool __value = false; };
    692 
    693   template<typename _Tp, typename... _Args>
    694     struct __is_nt_constructible_helper<true, _Tp, _Args...>
    695     { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
    696 
    697   template<typename _Tp, typename _Arg>
    698     struct __is_nt_constructible_helper<true, _Tp, _Arg>
    699     {
    700       static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
    701     };
    702 
    703   /// is_nothrow_constructible
    704   template<typename _Tp, typename... _Args>
    705     struct is_nothrow_constructible
    706     : public integral_constant<bool,
    707 	  __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
    708 				       _Tp, _Args...>::__value>
    709     { };
    710 
    711   /// has_trivial_default_constructor
    712   template<typename _Tp>
    713     struct has_trivial_default_constructor
    714     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
    715     { };
    716 
    717   /// has_trivial_copy_constructor
    718   template<typename _Tp>
    719     struct has_trivial_copy_constructor
    720     : public integral_constant<bool, __has_trivial_copy(_Tp)>
    721     { };
    722 
    723   /// has_trivial_copy_assign
    724   template<typename _Tp>
    725     struct has_trivial_copy_assign
    726     : public integral_constant<bool, __has_trivial_assign(_Tp)>
    727     { };
    728 
    729   /// has_trivial_destructor
    730   template<typename _Tp>
    731     struct has_trivial_destructor
    732     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
    733     { };
    734 
    735   /// has_nothrow_default_constructor
    736   template<typename _Tp>
    737     struct has_nothrow_default_constructor
    738     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
    739     { };
    740 
    741   /// has_nothrow_copy_constructor
    742   template<typename _Tp>
    743     struct has_nothrow_copy_constructor
    744     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
    745     { };
    746 
    747   /// has_nothrow_copy_assign
    748   template<typename _Tp>
    749     struct has_nothrow_copy_assign
    750     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
    751     { };
    752 
    753   // Relationships between types.
    754 
    755   /// is_base_of
    756   template<typename _Base, typename _Derived>
    757     struct is_base_of
    758     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
    759     { };
    760 
    761   template<typename _From, typename _To,
    762 	   bool = (is_void<_From>::value || is_function<_To>::value
    763 		   || is_array<_To>::value)>
    764     struct __is_convertible_helper
    765     { static const bool __value = is_void<_To>::value; };
    766 
    767   template<typename _From, typename _To>
    768     class __is_convertible_helper<_From, _To, false>
    769     : public __sfinae_types
    770     {
    771       template<typename _To1>
    772         static void __test_aux(_To1);
    773 
    774       template<typename _From1, typename _To1>
    775         static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
    776 	__test(int);
    777 
    778       template<typename, typename>
    779         static __two __test(...);
    780 
    781     public:
    782       static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
    783     };
    784 
    785   /// is_convertible
    786   // XXX FIXME
    787   // The C++0x specifications require front-end support, see N2255.
    788   template<typename _From, typename _To>
    789     struct is_convertible
    790     : public integral_constant<bool,
    791 			       __is_convertible_helper<_From, _To>::__value>
    792     { };
    793 
    794   /// is_explicitly_convertible
    795   template<typename _From, typename _To>
    796     struct is_explicitly_convertible
    797     : public is_constructible<_To, _From>
    798     { };
    799 
    800   template<std::size_t _Len>
    801     struct __aligned_storage_msa
    802     { 
    803       union __type
    804       {
    805 	unsigned char __data[_Len];
    806 	struct __attribute__((__aligned__)) { } __align; 
    807       };
    808     };
    809 
    810   /**
    811    *  @brief Alignment type.
    812    *
    813    *  The value of _Align is a default-alignment which shall be the
    814    *  most stringent alignment requirement for any C++ object type
    815    *  whose size is no greater than _Len (3.9). The member typedef
    816    *  type shall be a POD type suitable for use as uninitialized
    817    *  storage for any object whose size is at most _Len and whose
    818    *  alignment is a divisor of _Align.
    819   */
    820   template<std::size_t _Len, std::size_t _Align =
    821 	   __alignof__(typename __aligned_storage_msa<_Len>::__type)>
    822     struct aligned_storage
    823     { 
    824       union type
    825       {
    826 	unsigned char __data[_Len];
    827 	struct __attribute__((__aligned__((_Align)))) { } __align; 
    828       };
    829     };
    830 
    831 
    832   // Define a nested type if some predicate holds.
    833   // Primary template.
    834   /// enable_if
    835   template<bool, typename _Tp = void>
    836     struct enable_if 
    837     { };
    838 
    839   // Partial specialization for true.
    840   template<typename _Tp>
    841     struct enable_if<true, _Tp>
    842     { typedef _Tp type; };
    843 
    844 
    845   // A conditional expression, but for types. If true, first, if false, second.
    846   // Primary template.
    847   /// conditional
    848   template<bool _Cond, typename _Iftrue, typename _Iffalse>
    849     struct conditional
    850     { typedef _Iftrue type; };
    851 
    852   // Partial specialization for false.
    853   template<typename _Iftrue, typename _Iffalse>
    854     struct conditional<false, _Iftrue, _Iffalse>
    855     { typedef _Iffalse type; };
    856 
    857 
    858   // Decay trait for arrays and functions, used for perfect forwarding
    859   // in make_pair, make_tuple, etc.
    860   template<typename _Up, 
    861 	   bool _IsArray = is_array<_Up>::value,
    862 	   bool _IsFunction = is_function<_Up>::value> 
    863     struct __decay_selector;
    864 
    865   // NB: DR 705.
    866   template<typename _Up> 
    867     struct __decay_selector<_Up, false, false>
    868     { typedef typename remove_cv<_Up>::type __type; };
    869 
    870   template<typename _Up> 
    871     struct __decay_selector<_Up, true, false>
    872     { typedef typename remove_extent<_Up>::type* __type; };
    873 
    874   template<typename _Up> 
    875     struct __decay_selector<_Up, false, true>
    876     { typedef typename add_pointer<_Up>::type __type; };
    877 
    878   /// decay
    879   template<typename _Tp> 
    880     class decay 
    881     { 
    882       typedef typename remove_reference<_Tp>::type __remove_type;
    883 
    884     public:
    885       typedef typename __decay_selector<__remove_type>::__type type;
    886     };
    887 
    888   template<typename _Tp>
    889     class reference_wrapper;
    890 
    891   // Helper which adds a reference to a type when given a reference_wrapper
    892   template<typename _Tp>
    893     struct __strip_reference_wrapper
    894     {
    895       typedef _Tp __type;
    896     };
    897 
    898   template<typename _Tp>
    899     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
    900     {
    901       typedef _Tp& __type;
    902     };
    903 
    904   template<typename _Tp>
    905     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
    906     {
    907       typedef _Tp& __type;
    908     };
    909 
    910   template<typename _Tp>
    911     struct __decay_and_strip
    912     {
    913       typedef typename __strip_reference_wrapper<
    914 	typename decay<_Tp>::type>::__type __type;
    915     };
    916 
    917 
    918   // Utility for constructing identically cv-qualified types.
    919   template<typename _Unqualified, bool _IsConst, bool _IsVol>
    920     struct __cv_selector;
    921 
    922   template<typename _Unqualified>
    923     struct __cv_selector<_Unqualified, false, false>
    924     { typedef _Unqualified __type; };
    925 
    926   template<typename _Unqualified>
    927     struct __cv_selector<_Unqualified, false, true>
    928     { typedef volatile _Unqualified __type; };
    929 
    930   template<typename _Unqualified>
    931     struct __cv_selector<_Unqualified, true, false>
    932     { typedef const _Unqualified __type; };
    933 
    934   template<typename _Unqualified>
    935     struct __cv_selector<_Unqualified, true, true>
    936     { typedef const volatile _Unqualified __type; };
    937 
    938   template<typename _Qualified, typename _Unqualified,
    939 	   bool _IsConst = is_const<_Qualified>::value,
    940 	   bool _IsVol = is_volatile<_Qualified>::value>
    941     class __match_cv_qualifiers
    942     {
    943       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
    944 
    945     public:
    946       typedef typename __match::__type __type; 
    947     };
    948 
    949 
    950   // Utility for finding the unsigned versions of signed integral types.
    951   template<typename _Tp>
    952     struct __make_unsigned
    953     { typedef _Tp __type; };
    954 
    955   template<>
    956     struct __make_unsigned<char>
    957     { typedef unsigned char __type; };
    958 
    959   template<>
    960     struct __make_unsigned<signed char>
    961     { typedef unsigned char __type; };
    962 
    963   template<>
    964     struct __make_unsigned<short>
    965     { typedef unsigned short __type; };
    966 
    967   template<>
    968     struct __make_unsigned<int>
    969     { typedef unsigned int __type; };
    970 
    971   template<>
    972     struct __make_unsigned<long>
    973     { typedef unsigned long __type; };
    974 
    975   template<>
    976     struct __make_unsigned<long long>
    977     { typedef unsigned long long __type; };
    978 
    979 
    980   // Select between integral and enum: not possible to be both.
    981   template<typename _Tp, 
    982 	   bool _IsInt = is_integral<_Tp>::value,
    983 	   bool _IsEnum = is_enum<_Tp>::value>
    984     class __make_unsigned_selector;
    985 
    986   template<typename _Tp>
    987     class __make_unsigned_selector<_Tp, true, false>
    988     {
    989       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
    990       typedef typename __unsignedt::__type __unsigned_type;
    991       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
    992 
    993     public:
    994       typedef typename __cv_unsigned::__type __type;
    995     };
    996 
    997   template<typename _Tp>
    998     class __make_unsigned_selector<_Tp, false, true>
    999     {
   1000       // With -fshort-enums, an enum may be as small as a char.
   1001       typedef unsigned char __smallest;
   1002       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
   1003       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
   1004       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
   1005       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
   1006       typedef typename __cond2::type __cond2_type;
   1007       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
   1008       typedef typename __cond1::type __cond1_type;
   1009 
   1010     public:
   1011       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
   1012     };
   1013 
   1014   // Given an integral/enum type, return the corresponding unsigned
   1015   // integer type.
   1016   // Primary template.
   1017   /// make_unsigned
   1018   template<typename _Tp>
   1019     struct make_unsigned 
   1020     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
   1021 
   1022   // Integral, but don't define.
   1023   template<>
   1024     struct make_unsigned<bool>;
   1025 
   1026 
   1027   // Utility for finding the signed versions of unsigned integral types.
   1028   template<typename _Tp>
   1029     struct __make_signed
   1030     { typedef _Tp __type; };
   1031 
   1032   template<>
   1033     struct __make_signed<char>
   1034     { typedef signed char __type; };
   1035 
   1036   template<>
   1037     struct __make_signed<unsigned char>
   1038     { typedef signed char __type; };
   1039 
   1040   template<>
   1041     struct __make_signed<unsigned short>
   1042     { typedef signed short __type; };
   1043 
   1044   template<>
   1045     struct __make_signed<unsigned int>
   1046     { typedef signed int __type; };
   1047 
   1048   template<>
   1049     struct __make_signed<unsigned long>
   1050     { typedef signed long __type; };
   1051 
   1052   template<>
   1053     struct __make_signed<unsigned long long>
   1054     { typedef signed long long __type; };
   1055 
   1056 
   1057   // Select between integral and enum: not possible to be both.
   1058   template<typename _Tp, 
   1059 	   bool _IsInt = is_integral<_Tp>::value,
   1060 	   bool _IsEnum = is_enum<_Tp>::value>
   1061     class __make_signed_selector;
   1062 
   1063   template<typename _Tp>
   1064     class __make_signed_selector<_Tp, true, false>
   1065     {
   1066       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
   1067       typedef typename __signedt::__type __signed_type;
   1068       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
   1069 
   1070     public:
   1071       typedef typename __cv_signed::__type __type;
   1072     };
   1073 
   1074   template<typename _Tp>
   1075     class __make_signed_selector<_Tp, false, true>
   1076     {
   1077       // With -fshort-enums, an enum may be as small as a char.
   1078       typedef signed char __smallest;
   1079       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
   1080       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
   1081       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
   1082       typedef conditional<__b2, signed int, signed long> __cond2;
   1083       typedef typename __cond2::type __cond2_type;
   1084       typedef conditional<__b1, signed short, __cond2_type> __cond1;
   1085       typedef typename __cond1::type __cond1_type;
   1086 
   1087     public:
   1088       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
   1089     };
   1090 
   1091   // Given an integral/enum type, return the corresponding signed
   1092   // integer type.
   1093   // Primary template.
   1094   /// make_signed
   1095   template<typename _Tp>
   1096     struct make_signed 
   1097     { typedef typename __make_signed_selector<_Tp>::__type type; };
   1098 
   1099   // Integral, but don't define.
   1100   template<>
   1101     struct make_signed<bool>;
   1102 
   1103   /// common_type
   1104   template<typename... _Tp>
   1105     struct common_type;
   1106 
   1107   template<typename _Tp>
   1108     struct common_type<_Tp>
   1109     { typedef _Tp type; };
   1110 
   1111   template<typename _Tp, typename _Up>
   1112     struct common_type<_Tp, _Up>
   1113     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
   1114 
   1115   template<typename _Tp, typename _Up, typename... _Vp>
   1116     struct common_type<_Tp, _Up, _Vp...>
   1117     {
   1118       typedef typename
   1119         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
   1120     };
   1121 
   1122   /// declval
   1123   template<typename _Tp>
   1124     struct __declval_protector
   1125     {
   1126       static const bool __stop = false;
   1127       static typename add_rvalue_reference<_Tp>::type __delegate();
   1128     };
   1129 
   1130   template<typename _Tp>
   1131     inline typename add_rvalue_reference<_Tp>::type
   1132     declval() noexcept
   1133     {
   1134       static_assert(__declval_protector<_Tp>::__stop,
   1135 		    "declval() must not be used!");
   1136       return __declval_protector<_Tp>::__delegate();
   1137     }
   1138 
   1139   /// result_of
   1140   template<typename _Signature>
   1141     class result_of;
   1142 
   1143   template<typename _MemPtr, typename _Arg>
   1144     struct _Result_of_memobj;
   1145 
   1146   template<typename _Res, typename _Class, typename _Arg>
   1147     struct _Result_of_memobj<_Res _Class::*, _Arg>
   1148     {
   1149     private:
   1150       typedef _Res _Class::* _Func;
   1151 
   1152       template<typename _Tp>
   1153 	static _Tp _S_get(const _Class&);
   1154       template<typename _Tp>
   1155 	static decltype(*std::declval<_Tp>()) _S_get(...);
   1156         
   1157     public:
   1158       typedef
   1159         decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
   1160         __type;
   1161     };
   1162 
   1163   template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
   1164     struct _Result_of_memfun;
   1165 
   1166   template<typename _Res, typename _Class, typename _Arg, typename... _Args>
   1167     struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...>
   1168     {
   1169     private:
   1170       typedef _Res _Class::* _Func;
   1171 
   1172       template<typename _Tp>
   1173 	static _Tp _S_get(const _Class&);
   1174       template<typename _Tp>
   1175 	static decltype(*std::declval<_Tp>()) _S_get(...);
   1176         
   1177     public:
   1178       typedef
   1179         decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
   1180             (std::declval<_Args>()...) )
   1181         __type;
   1182     };
   1183 
   1184   template<bool, bool, typename _Functor, typename... _ArgTypes>
   1185     struct _Result_of_impl;
   1186 
   1187   template<typename _Functor, typename... _ArgTypes>
   1188     struct _Result_of_impl<false, false, _Functor, _ArgTypes...>
   1189     {
   1190       typedef
   1191         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
   1192         __type;
   1193     };
   1194 
   1195   template<typename _MemPtr, typename _Arg>
   1196     struct _Result_of_impl<true, false, _MemPtr, _Arg>
   1197     : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg>
   1198     {
   1199       typedef typename _Result_of_memobj<
   1200 	typename remove_reference<_MemPtr>::type, _Arg>::__type
   1201 	__type;
   1202     };
   1203 
   1204   template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
   1205     struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...>
   1206     : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg,
   1207                         _ArgTypes...>
   1208     {
   1209       typedef typename _Result_of_memfun<
   1210 	typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type
   1211 	__type;
   1212     };
   1213 
   1214   template<typename _Functor, typename... _ArgTypes>
   1215     struct result_of<_Functor(_ArgTypes...)>
   1216     : _Result_of_impl<is_member_object_pointer<
   1217                         typename remove_reference<_Functor>::type >::value,
   1218                       is_member_function_pointer<
   1219 			typename remove_reference<_Functor>::type >::value,
   1220 		      _Functor, _ArgTypes...>
   1221     {
   1222       typedef typename _Result_of_impl<
   1223 	is_member_object_pointer<
   1224 	  typename remove_reference<_Functor>::type >::value,
   1225         is_member_function_pointer<
   1226 	  typename remove_reference<_Functor>::type >::value,
   1227        	_Functor, _ArgTypes...>::__type
   1228 	type;
   1229     };
   1230 
   1231   /**
   1232    *  Use SFINAE to determine if the type _Tp has a publicly-accessible
   1233    *  member type _NTYPE.
   1234    */
   1235 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE)                         \
   1236   template<typename _Tp>                                         \
   1237     class __has_##_NTYPE##_helper                                \
   1238     : __sfinae_types                                             \
   1239     {                                                            \
   1240       template<typename _Up>                                     \
   1241         struct _Wrap_type                                        \
   1242 	{ };                                                     \
   1243                                                                  \
   1244       template<typename _Up>                                     \
   1245         static __one __test(_Wrap_type<typename _Up::_NTYPE>*);  \
   1246                                                                  \
   1247       template<typename _Up>                                     \
   1248         static __two __test(...);                                \
   1249                                                                  \
   1250     public:                                                      \
   1251       static const bool value = sizeof(__test<_Tp>(0)) == 1;     \
   1252     };                                                           \
   1253                                                                  \
   1254   template<typename _Tp>                                         \
   1255     struct __has_##_NTYPE                                        \
   1256     : integral_constant<bool, __has_##_NTYPE##_helper            \
   1257 			<typename remove_cv<_Tp>::type>::value>  \
   1258     { };
   1259 
   1260 #undef _DEFINE_SPEC_0_HELPER
   1261 #undef _DEFINE_SPEC_1_HELPER
   1262 #undef _DEFINE_SPEC_2_HELPER
   1263 #undef _DEFINE_SPEC
   1264 
   1265   // @} group metaprogramming
   1266 _GLIBCXX_END_NAMESPACE_VERSION
   1267 } // namespace
   1268 
   1269 #endif  // __GXX_EXPERIMENTAL_CXX0X__
   1270 
   1271 #endif  // _GLIBCXX_TYPE_TRAITS
   1272