type_traits

Go to the documentation of this file.
00001 // C++0x type_traits -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/type_traits
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_TYPE_TRAITS
00030 #define _GLIBCXX_TYPE_TRAITS 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <bits/c++config.h>
00039 
00040 namespace std _GLIBCXX_VISIBILITY(default)
00041 {
00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00043 
00044   /**
00045    * @addtogroup metaprogramming
00046    * @{
00047    */
00048   struct __sfinae_types
00049   {
00050     typedef char __one;
00051     typedef struct { char __arr[2]; } __two;
00052   };
00053 
00054 #define _DEFINE_SPEC_0_HELPER                          \
00055   template<>
00056 
00057 #define _DEFINE_SPEC_1_HELPER                          \
00058   template<typename _Tp>
00059 
00060 #define _DEFINE_SPEC_2_HELPER                          \
00061   template<typename _Tp, typename _Cp>
00062 
00063 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value)    \
00064   _DEFINE_SPEC_##_Order##_HELPER                       \
00065     struct _Trait<_Type>                               \
00066     : public integral_constant<bool, _Value> { };
00067 
00068   // helper classes.
00069 
00070   /// integral_constant
00071   template<typename _Tp, _Tp __v>
00072     struct integral_constant
00073     {
00074       static constexpr _Tp                  value = __v;
00075       typedef _Tp                           value_type;
00076       typedef integral_constant<_Tp, __v>   type;
00077       constexpr operator value_type() { return value; }
00078     };
00079   
00080   /// typedef for true_type
00081   typedef integral_constant<bool, true>     true_type;
00082 
00083   /// typedef for false_type
00084   typedef integral_constant<bool, false>    false_type;
00085 
00086   template<typename _Tp, _Tp __v>
00087     constexpr _Tp integral_constant<_Tp, __v>::value;
00088 
00089   /// remove_cv
00090   template<typename>
00091     struct remove_cv;
00092 
00093   template<typename>
00094     struct __is_void_helper
00095     : public false_type { };
00096   _DEFINE_SPEC(0, __is_void_helper, void, true)
00097 
00098   // primary type categories.
00099 
00100   /// is_void
00101   template<typename _Tp>
00102     struct is_void
00103     : public integral_constant<bool, (__is_void_helper<typename
00104                       remove_cv<_Tp>::type>::value)>
00105     { };
00106 
00107   template<typename>
00108     struct __is_integral_helper
00109     : public false_type { };
00110   _DEFINE_SPEC(0, __is_integral_helper, bool, true)
00111   _DEFINE_SPEC(0, __is_integral_helper, char, true)
00112   _DEFINE_SPEC(0, __is_integral_helper, signed char, true)
00113   _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true)
00114 #ifdef _GLIBCXX_USE_WCHAR_T
00115   _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true)
00116 #endif
00117   _DEFINE_SPEC(0, __is_integral_helper, char16_t, true)
00118   _DEFINE_SPEC(0, __is_integral_helper, char32_t, true)
00119   _DEFINE_SPEC(0, __is_integral_helper, short, true)
00120   _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true)
00121   _DEFINE_SPEC(0, __is_integral_helper, int, true)
00122   _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true)
00123   _DEFINE_SPEC(0, __is_integral_helper, long, true)
00124   _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true)
00125   _DEFINE_SPEC(0, __is_integral_helper, long long, true)
00126   _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true)
00127 
00128   /// is_integral
00129   template<typename _Tp>
00130     struct is_integral
00131     : public integral_constant<bool, (__is_integral_helper<typename
00132                       remove_cv<_Tp>::type>::value)>
00133     { };
00134 
00135   template<typename>
00136     struct __is_floating_point_helper
00137     : public false_type { };
00138   _DEFINE_SPEC(0, __is_floating_point_helper, float, true)
00139   _DEFINE_SPEC(0, __is_floating_point_helper, double, true)
00140   _DEFINE_SPEC(0, __is_floating_point_helper, long double, true)
00141 
00142   /// is_floating_point
00143   template<typename _Tp>
00144     struct is_floating_point
00145     : public integral_constant<bool, (__is_floating_point_helper<typename
00146                       remove_cv<_Tp>::type>::value)>
00147     { };
00148 
00149   /// is_array
00150   template<typename>
00151     struct is_array
00152     : public false_type { };
00153 
00154   template<typename _Tp, std::size_t _Size>
00155     struct is_array<_Tp[_Size]>
00156     : public true_type { };
00157 
00158   template<typename _Tp>
00159     struct is_array<_Tp[]>
00160     : public true_type { };
00161 
00162   template<typename>
00163     struct __is_pointer_helper
00164     : public false_type { };
00165   _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true)
00166 
00167   /// is_pointer
00168   template<typename _Tp>
00169     struct is_pointer
00170     : public integral_constant<bool, (__is_pointer_helper<typename
00171                       remove_cv<_Tp>::type>::value)>
00172     { };
00173 
00174   /// is_reference
00175   template<typename _Tp>
00176     struct is_reference;
00177 
00178   /// is_function
00179   template<typename _Tp>
00180     struct is_function;
00181 
00182   template<typename>
00183     struct __is_member_object_pointer_helper
00184     : public false_type { };
00185   _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*,
00186            !is_function<_Tp>::value)
00187 
00188   /// is_member_object_pointer
00189   template<typename _Tp>
00190     struct is_member_object_pointer
00191     : public integral_constant<bool, (__is_member_object_pointer_helper<
00192                       typename remove_cv<_Tp>::type>::value)>
00193     { };
00194 
00195   template<typename>
00196     struct __is_member_function_pointer_helper
00197     : public false_type { };
00198   _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*,
00199            is_function<_Tp>::value)
00200 
00201   /// is_member_function_pointer
00202   template<typename _Tp>
00203     struct is_member_function_pointer
00204     : public integral_constant<bool, (__is_member_function_pointer_helper<
00205                       typename remove_cv<_Tp>::type>::value)>
00206     { };
00207 
00208   /// is_enum
00209   template<typename _Tp>
00210     struct is_enum
00211     : public integral_constant<bool, __is_enum(_Tp)>
00212     { };
00213 
00214   /// is_union
00215   template<typename _Tp>
00216     struct is_union
00217     : public integral_constant<bool, __is_union(_Tp)>
00218     { };
00219 
00220   /// is_class
00221   template<typename _Tp>
00222     struct is_class
00223     : public integral_constant<bool, __is_class(_Tp)>
00224     { };
00225 
00226   /// is_function
00227   template<typename>
00228     struct is_function
00229     : public false_type { };
00230   template<typename _Res, typename... _ArgTypes>
00231     struct is_function<_Res(_ArgTypes...)>
00232     : public true_type { };
00233   template<typename _Res, typename... _ArgTypes>
00234     struct is_function<_Res(_ArgTypes......)>
00235     : public true_type { };
00236   template<typename _Res, typename... _ArgTypes>
00237     struct is_function<_Res(_ArgTypes...) const>
00238     : public true_type { };
00239   template<typename _Res, typename... _ArgTypes>
00240     struct is_function<_Res(_ArgTypes......) const>
00241     : public true_type { };
00242   template<typename _Res, typename... _ArgTypes>
00243     struct is_function<_Res(_ArgTypes...) volatile>
00244     : public true_type { };
00245   template<typename _Res, typename... _ArgTypes>
00246     struct is_function<_Res(_ArgTypes......) volatile>
00247     : public true_type { };
00248   template<typename _Res, typename... _ArgTypes>
00249     struct is_function<_Res(_ArgTypes...) const volatile>
00250     : public true_type { };
00251   template<typename _Res, typename... _ArgTypes>
00252     struct is_function<_Res(_ArgTypes......) const volatile>
00253     : public true_type { };
00254 
00255   template<typename>
00256     struct __is_nullptr_t_helper
00257     : public false_type { };
00258   _DEFINE_SPEC(0, __is_nullptr_t_helper, std::nullptr_t, true)
00259 
00260   // __is_nullptr_t (extension).
00261   template<typename _Tp>
00262     struct __is_nullptr_t
00263     : public integral_constant<bool, (__is_nullptr_t_helper<typename
00264                       remove_cv<_Tp>::type>::value)>
00265     { };
00266 
00267   // composite type traits.
00268   
00269   /// is_arithmetic
00270   template<typename _Tp>
00271     struct is_arithmetic
00272     : public integral_constant<bool, (is_integral<_Tp>::value
00273                       || is_floating_point<_Tp>::value)>
00274     { };
00275 
00276   /// is_fundamental
00277   template<typename _Tp>
00278     struct is_fundamental
00279     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00280                       || is_void<_Tp>::value)>
00281     { };
00282 
00283   /// is_object
00284   template<typename _Tp>
00285     struct is_object
00286     : public integral_constant<bool, !(is_function<_Tp>::value
00287                        || is_reference<_Tp>::value
00288                        || is_void<_Tp>::value)>
00289     { };
00290 
00291   /// is_member_pointer
00292   template<typename _Tp>
00293     struct is_member_pointer;
00294 
00295   /// is_scalar
00296   template<typename _Tp>
00297     struct is_scalar
00298     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00299                       || is_enum<_Tp>::value
00300                       || is_pointer<_Tp>::value
00301                       || is_member_pointer<_Tp>::value
00302                       || __is_nullptr_t<_Tp>::value)>
00303     { };
00304 
00305   /// is_compound
00306   template<typename _Tp>
00307     struct is_compound
00308     : public integral_constant<bool, !is_fundamental<_Tp>::value> { };
00309 
00310   /// is_member_pointer
00311   template<typename _Tp>
00312     struct __is_member_pointer_helper
00313     : public false_type { };
00314   _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true)
00315 
00316   template<typename _Tp>
00317   struct is_member_pointer
00318     : public integral_constant<bool, (__is_member_pointer_helper<
00319                       typename remove_cv<_Tp>::type>::value)>
00320     { };
00321 
00322   // type properties.
00323   /// is_const
00324   template<typename>
00325     struct is_const
00326     : public false_type { };
00327 
00328   template<typename _Tp>
00329     struct is_const<_Tp const>
00330     : public true_type { };
00331   
00332   /// is_volatile
00333   template<typename>
00334     struct is_volatile
00335     : public false_type { };
00336 
00337   template<typename _Tp>
00338     struct is_volatile<_Tp volatile>
00339     : public true_type { };
00340 
00341   /// is_empty
00342   template<typename _Tp>
00343     struct is_empty
00344     : public integral_constant<bool, __is_empty(_Tp)>
00345     { };
00346 
00347   /// is_polymorphic
00348   template<typename _Tp>
00349     struct is_polymorphic
00350     : public integral_constant<bool, __is_polymorphic(_Tp)>
00351     { };
00352 
00353   /// is_abstract
00354   template<typename _Tp>
00355     struct is_abstract
00356     : public integral_constant<bool, __is_abstract(_Tp)>
00357     { };
00358 
00359   /// has_virtual_destructor
00360   template<typename _Tp>
00361     struct has_virtual_destructor
00362     : public integral_constant<bool, __has_virtual_destructor(_Tp)>
00363     { };
00364 
00365   /// alignment_of
00366   template<typename _Tp>
00367     struct alignment_of
00368     : public integral_constant<std::size_t, __alignof__(_Tp)> { };
00369   
00370   /// rank
00371   template<typename>
00372     struct rank
00373     : public integral_constant<std::size_t, 0> { };
00374    
00375   template<typename _Tp, std::size_t _Size>
00376     struct rank<_Tp[_Size]>
00377     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00378 
00379   template<typename _Tp>
00380     struct rank<_Tp[]>
00381     : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
00382 
00383   /// extent
00384   template<typename, unsigned _Uint = 0>
00385     struct extent
00386     : public integral_constant<std::size_t, 0> { };
00387   
00388   template<typename _Tp, unsigned _Uint, std::size_t _Size>
00389     struct extent<_Tp[_Size], _Uint>
00390     : public integral_constant<std::size_t,
00391                    _Uint == 0 ? _Size : extent<_Tp,
00392                                _Uint - 1>::value>
00393     { };
00394 
00395   template<typename _Tp, unsigned _Uint>
00396     struct extent<_Tp[], _Uint>
00397     : public integral_constant<std::size_t,
00398                    _Uint == 0 ? 0 : extent<_Tp,
00399                                _Uint - 1>::value>
00400     { };
00401 
00402   // relationships between types [4.6].
00403 
00404   /// is_same
00405   template<typename, typename>
00406     struct is_same
00407     : public false_type { };
00408 
00409   template<typename _Tp>
00410     struct is_same<_Tp, _Tp>
00411     : public true_type { };
00412 
00413   // const-volatile modifications [4.7.1].
00414 
00415   /// remove_const
00416   template<typename _Tp>
00417     struct remove_const
00418     { typedef _Tp     type; };
00419 
00420   template<typename _Tp>
00421     struct remove_const<_Tp const>
00422     { typedef _Tp     type; };
00423   
00424   /// remove_volatile
00425   template<typename _Tp>
00426     struct remove_volatile
00427     { typedef _Tp     type; };
00428 
00429   template<typename _Tp>
00430     struct remove_volatile<_Tp volatile>
00431     { typedef _Tp     type; };
00432   
00433   /// remove_cv
00434   template<typename _Tp>
00435     struct remove_cv
00436     {
00437       typedef typename
00438       remove_const<typename remove_volatile<_Tp>::type>::type     type;
00439     };
00440   
00441   /// add_const
00442   template<typename _Tp>
00443     struct add_const
00444     { typedef _Tp const     type; };
00445    
00446   /// add_volatile
00447   template<typename _Tp>
00448     struct add_volatile
00449     { typedef _Tp volatile     type; };
00450   
00451   /// add_cv
00452   template<typename _Tp>
00453     struct add_cv
00454     {
00455       typedef typename
00456       add_const<typename add_volatile<_Tp>::type>::type     type;
00457     };
00458 
00459   // array modifications.
00460 
00461   /// remove_extent
00462   template<typename _Tp>
00463     struct remove_extent
00464     { typedef _Tp     type; };
00465 
00466   template<typename _Tp, std::size_t _Size>
00467     struct remove_extent<_Tp[_Size]>
00468     { typedef _Tp     type; };
00469 
00470   template<typename _Tp>
00471     struct remove_extent<_Tp[]>
00472     { typedef _Tp     type; };
00473 
00474   /// remove_all_extents
00475   template<typename _Tp>
00476     struct remove_all_extents
00477     { typedef _Tp     type; };
00478 
00479   template<typename _Tp, std::size_t _Size>
00480     struct remove_all_extents<_Tp[_Size]>
00481     { typedef typename remove_all_extents<_Tp>::type     type; };
00482 
00483   template<typename _Tp>
00484     struct remove_all_extents<_Tp[]>
00485     { typedef typename remove_all_extents<_Tp>::type     type; };
00486 
00487   // pointer modifications.
00488 
00489   template<typename _Tp, typename>
00490     struct __remove_pointer_helper
00491     { typedef _Tp     type; };
00492 
00493   template<typename _Tp, typename _Up>
00494     struct __remove_pointer_helper<_Tp, _Up*>
00495     { typedef _Up     type; };
00496 
00497   /// remove_pointer
00498   template<typename _Tp>
00499     struct remove_pointer
00500     : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type>
00501     { };
00502 
00503   template<typename>
00504     struct remove_reference;
00505 
00506   /// add_pointer
00507   template<typename _Tp>
00508     struct add_pointer
00509     { typedef typename remove_reference<_Tp>::type*     type; };
00510 
00511   // Primary classification traits.
00512 
00513   /// is_lvalue_reference
00514   template<typename>
00515     struct is_lvalue_reference
00516     : public false_type { };
00517 
00518   template<typename _Tp>
00519     struct is_lvalue_reference<_Tp&>
00520     : public true_type { };
00521 
00522   /// is_rvalue_reference
00523   template<typename>
00524     struct is_rvalue_reference
00525     : public false_type { };
00526 
00527   template<typename _Tp>
00528     struct is_rvalue_reference<_Tp&&>
00529     : public true_type { };
00530 
00531   // Secondary classification traits.
00532 
00533   /// is_reference
00534   template<typename _Tp>
00535     struct is_reference
00536     : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
00537                       || is_rvalue_reference<_Tp>::value)>
00538     { };
00539 
00540   // Reference transformations.
00541 
00542   /// remove_reference
00543   template<typename _Tp>
00544     struct remove_reference
00545     { typedef _Tp   type; };
00546 
00547   template<typename _Tp>
00548     struct remove_reference<_Tp&>
00549     { typedef _Tp   type; };
00550 
00551   template<typename _Tp>
00552     struct remove_reference<_Tp&&>
00553     { typedef _Tp   type; };
00554 
00555   template<typename _Tp,
00556        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
00557        bool = is_rvalue_reference<_Tp>::value>
00558     struct __add_lvalue_reference_helper
00559     { typedef _Tp   type; };
00560 
00561   template<typename _Tp>
00562     struct __add_lvalue_reference_helper<_Tp, true, false>
00563     { typedef _Tp&   type; };
00564 
00565   template<typename _Tp>
00566     struct __add_lvalue_reference_helper<_Tp, false, true>
00567     { typedef typename remove_reference<_Tp>::type&   type; };
00568 
00569   /// add_lvalue_reference
00570   template<typename _Tp>
00571     struct add_lvalue_reference
00572     : public __add_lvalue_reference_helper<_Tp>
00573     { };
00574 
00575   template<typename _Tp,
00576        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
00577     struct __add_rvalue_reference_helper
00578     { typedef _Tp   type; };
00579 
00580   template<typename _Tp>
00581     struct __add_rvalue_reference_helper<_Tp, true>
00582     { typedef _Tp&&   type; };
00583 
00584   /// add_rvalue_reference
00585   template<typename _Tp>
00586     struct add_rvalue_reference
00587     : public __add_rvalue_reference_helper<_Tp>
00588     { };
00589 
00590   // Scalar properties and transformations.
00591 
00592   template<typename _Tp,
00593        bool = is_integral<_Tp>::value,
00594        bool = is_floating_point<_Tp>::value>
00595     struct __is_signed_helper
00596     : public false_type { };
00597 
00598   template<typename _Tp>
00599     struct __is_signed_helper<_Tp, false, true>
00600     : public true_type { };
00601 
00602   template<typename _Tp>
00603     struct __is_signed_helper<_Tp, true, false>
00604     : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))>
00605     { };
00606 
00607   /// is_signed
00608   template<typename _Tp>
00609     struct is_signed
00610     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
00611     { };
00612 
00613   /// is_unsigned
00614   template<typename _Tp>
00615     struct is_unsigned
00616     : public integral_constant<bool, (is_arithmetic<_Tp>::value
00617                       && !is_signed<_Tp>::value)>
00618     { };
00619 
00620   // Member introspection.
00621 
00622   /// is_trivial
00623   template<typename _Tp>
00624     struct is_trivial
00625     : public integral_constant<bool, __is_trivial(_Tp)>
00626     { };
00627 
00628   /// is_standard_layout
00629   template<typename _Tp>
00630     struct is_standard_layout
00631     : public integral_constant<bool, __is_standard_layout(_Tp)>
00632     { };
00633 
00634   /// is_pod
00635   // Could use is_standard_layout && is_trivial instead of the builtin.
00636   template<typename _Tp>
00637     struct is_pod
00638     : public integral_constant<bool, __is_pod(_Tp)>
00639     { };
00640 
00641   /// is_literal_type
00642   template<typename _Tp>
00643     struct is_literal_type
00644     : public integral_constant<bool, __is_literal_type(_Tp)>
00645     { };
00646 
00647   template<typename _Tp>
00648     typename add_rvalue_reference<_Tp>::type declval() noexcept;
00649 
00650   template<typename _Tp, typename... _Args>
00651     class __is_constructible_helper
00652     : public __sfinae_types
00653     {
00654       template<typename _Tp1, typename... _Args1>
00655         static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int);
00656 
00657       template<typename, typename...>
00658         static __two __test(...);
00659 
00660     public:
00661       static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1;
00662     };
00663 
00664   template<typename _Tp, typename _Arg>
00665     class __is_constructible_helper<_Tp, _Arg>
00666     : public __sfinae_types
00667     {
00668       template<typename _Tp1, typename _Arg1>
00669         static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one())
00670     __test(int);
00671 
00672       template<typename, typename>
00673         static __two __test(...);
00674 
00675     public:
00676       static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1;
00677     };
00678 
00679   /// is_constructible
00680   // XXX FIXME
00681   // The C++0x specifications require front-end support, see N2255.
00682   template<typename _Tp, typename... _Args>
00683     struct is_constructible
00684     : public integral_constant<bool,
00685                    __is_constructible_helper<_Tp,
00686                              _Args...>::__value>
00687     { };
00688 
00689   template<bool, typename _Tp, typename... _Args>
00690     struct __is_nt_constructible_helper
00691     { static const bool __value = false; };
00692 
00693   template<typename _Tp, typename... _Args>
00694     struct __is_nt_constructible_helper<true, _Tp, _Args...>
00695     { static const bool __value = noexcept(_Tp(declval<_Args>()...)); };
00696 
00697   template<typename _Tp, typename _Arg>
00698     struct __is_nt_constructible_helper<true, _Tp, _Arg>
00699     {
00700       static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>()));
00701     };
00702 
00703   /// is_nothrow_constructible
00704   template<typename _Tp, typename... _Args>
00705     struct is_nothrow_constructible
00706     : public integral_constant<bool,
00707       __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value,
00708                        _Tp, _Args...>::__value>
00709     { };
00710 
00711   /// has_trivial_default_constructor
00712   template<typename _Tp>
00713     struct has_trivial_default_constructor
00714     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
00715     { };
00716 
00717   /// has_trivial_copy_constructor
00718   template<typename _Tp>
00719     struct has_trivial_copy_constructor
00720     : public integral_constant<bool, __has_trivial_copy(_Tp)>
00721     { };
00722 
00723   /// has_trivial_copy_assign
00724   template<typename _Tp>
00725     struct has_trivial_copy_assign
00726     : public integral_constant<bool, __has_trivial_assign(_Tp)>
00727     { };
00728 
00729   /// has_trivial_destructor
00730   template<typename _Tp>
00731     struct has_trivial_destructor
00732     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
00733     { };
00734 
00735   /// has_nothrow_default_constructor
00736   template<typename _Tp>
00737     struct has_nothrow_default_constructor
00738     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
00739     { };
00740 
00741   /// has_nothrow_copy_constructor
00742   template<typename _Tp>
00743     struct has_nothrow_copy_constructor
00744     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
00745     { };
00746 
00747   /// has_nothrow_copy_assign
00748   template<typename _Tp>
00749     struct has_nothrow_copy_assign
00750     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
00751     { };
00752 
00753   // Relationships between types.
00754 
00755   /// is_base_of
00756   template<typename _Base, typename _Derived>
00757     struct is_base_of
00758     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
00759     { };
00760 
00761   template<typename _From, typename _To,
00762        bool = (is_void<_From>::value || is_function<_To>::value
00763            || is_array<_To>::value)>
00764     struct __is_convertible_helper
00765     { static const bool __value = is_void<_To>::value; };
00766 
00767   template<typename _From, typename _To>
00768     class __is_convertible_helper<_From, _To, false>
00769     : public __sfinae_types
00770     {
00771       template<typename _To1>
00772         static void __test_aux(_To1);
00773 
00774       template<typename _From1, typename _To1>
00775         static decltype(__test_aux<_To1>(std::declval<_From1>()), __one())
00776     __test(int);
00777 
00778       template<typename, typename>
00779         static __two __test(...);
00780 
00781     public:
00782       static const bool __value = sizeof(__test<_From, _To>(0)) == 1;
00783     };
00784 
00785   /// is_convertible
00786   // XXX FIXME
00787   // The C++0x specifications require front-end support, see N2255.
00788   template<typename _From, typename _To>
00789     struct is_convertible
00790     : public integral_constant<bool,
00791                    __is_convertible_helper<_From, _To>::__value>
00792     { };
00793 
00794   /// is_explicitly_convertible
00795   template<typename _From, typename _To>
00796     struct is_explicitly_convertible
00797     : public is_constructible<_To, _From>
00798     { };
00799 
00800   template<std::size_t _Len>
00801     struct __aligned_storage_msa
00802     { 
00803       union __type
00804       {
00805     unsigned char __data[_Len];
00806     struct __attribute__((__aligned__)) { } __align; 
00807       };
00808     };
00809 
00810   /**
00811    *  @brief Alignment type.
00812    *
00813    *  The value of _Align is a default-alignment which shall be the
00814    *  most stringent alignment requirement for any C++ object type
00815    *  whose size is no greater than _Len (3.9). The member typedef
00816    *  type shall be a POD type suitable for use as uninitialized
00817    *  storage for any object whose size is at most _Len and whose
00818    *  alignment is a divisor of _Align.
00819   */
00820   template<std::size_t _Len, std::size_t _Align =
00821        __alignof__(typename __aligned_storage_msa<_Len>::__type)>
00822     struct aligned_storage
00823     { 
00824       union type
00825       {
00826     unsigned char __data[_Len];
00827     struct __attribute__((__aligned__((_Align)))) { } __align; 
00828       };
00829     };
00830 
00831 
00832   // Define a nested type if some predicate holds.
00833   // Primary template.
00834   /// enable_if
00835   template<bool, typename _Tp = void>
00836     struct enable_if 
00837     { };
00838 
00839   // Partial specialization for true.
00840   template<typename _Tp>
00841     struct enable_if<true, _Tp>
00842     { typedef _Tp type; };
00843 
00844 
00845   // A conditional expression, but for types. If true, first, if false, second.
00846   // Primary template.
00847   /// conditional
00848   template<bool _Cond, typename _Iftrue, typename _Iffalse>
00849     struct conditional
00850     { typedef _Iftrue type; };
00851 
00852   // Partial specialization for false.
00853   template<typename _Iftrue, typename _Iffalse>
00854     struct conditional<false, _Iftrue, _Iffalse>
00855     { typedef _Iffalse type; };
00856 
00857 
00858   // Decay trait for arrays and functions, used for perfect forwarding
00859   // in make_pair, make_tuple, etc.
00860   template<typename _Up, 
00861        bool _IsArray = is_array<_Up>::value,
00862        bool _IsFunction = is_function<_Up>::value> 
00863     struct __decay_selector;
00864 
00865   // NB: DR 705.
00866   template<typename _Up> 
00867     struct __decay_selector<_Up, false, false>
00868     { typedef typename remove_cv<_Up>::type __type; };
00869 
00870   template<typename _Up> 
00871     struct __decay_selector<_Up, true, false>
00872     { typedef typename remove_extent<_Up>::type* __type; };
00873 
00874   template<typename _Up> 
00875     struct __decay_selector<_Up, false, true>
00876     { typedef typename add_pointer<_Up>::type __type; };
00877 
00878   /// decay
00879   template<typename _Tp> 
00880     class decay 
00881     { 
00882       typedef typename remove_reference<_Tp>::type __remove_type;
00883 
00884     public:
00885       typedef typename __decay_selector<__remove_type>::__type type;
00886     };
00887 
00888   template<typename _Tp>
00889     class reference_wrapper;
00890 
00891   // Helper which adds a reference to a type when given a reference_wrapper
00892   template<typename _Tp>
00893     struct __strip_reference_wrapper
00894     {
00895       typedef _Tp __type;
00896     };
00897 
00898   template<typename _Tp>
00899     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
00900     {
00901       typedef _Tp& __type;
00902     };
00903 
00904   template<typename _Tp>
00905     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
00906     {
00907       typedef _Tp& __type;
00908     };
00909 
00910   template<typename _Tp>
00911     struct __decay_and_strip
00912     {
00913       typedef typename __strip_reference_wrapper<
00914     typename decay<_Tp>::type>::__type __type;
00915     };
00916 
00917 
00918   // Utility for constructing identically cv-qualified types.
00919   template<typename _Unqualified, bool _IsConst, bool _IsVol>
00920     struct __cv_selector;
00921 
00922   template<typename _Unqualified>
00923     struct __cv_selector<_Unqualified, false, false>
00924     { typedef _Unqualified __type; };
00925 
00926   template<typename _Unqualified>
00927     struct __cv_selector<_Unqualified, false, true>
00928     { typedef volatile _Unqualified __type; };
00929 
00930   template<typename _Unqualified>
00931     struct __cv_selector<_Unqualified, true, false>
00932     { typedef const _Unqualified __type; };
00933 
00934   template<typename _Unqualified>
00935     struct __cv_selector<_Unqualified, true, true>
00936     { typedef const volatile _Unqualified __type; };
00937 
00938   template<typename _Qualified, typename _Unqualified,
00939        bool _IsConst = is_const<_Qualified>::value,
00940        bool _IsVol = is_volatile<_Qualified>::value>
00941     class __match_cv_qualifiers
00942     {
00943       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
00944 
00945     public:
00946       typedef typename __match::__type __type; 
00947     };
00948 
00949 
00950   // Utility for finding the unsigned versions of signed integral types.
00951   template<typename _Tp>
00952     struct __make_unsigned
00953     { typedef _Tp __type; };
00954 
00955   template<>
00956     struct __make_unsigned<char>
00957     { typedef unsigned char __type; };
00958 
00959   template<>
00960     struct __make_unsigned<signed char>
00961     { typedef unsigned char __type; };
00962 
00963   template<>
00964     struct __make_unsigned<short>
00965     { typedef unsigned short __type; };
00966 
00967   template<>
00968     struct __make_unsigned<int>
00969     { typedef unsigned int __type; };
00970 
00971   template<>
00972     struct __make_unsigned<long>
00973     { typedef unsigned long __type; };
00974 
00975   template<>
00976     struct __make_unsigned<long long>
00977     { typedef unsigned long long __type; };
00978 
00979 
00980   // Select between integral and enum: not possible to be both.
00981   template<typename _Tp, 
00982        bool _IsInt = is_integral<_Tp>::value,
00983        bool _IsEnum = is_enum<_Tp>::value>
00984     class __make_unsigned_selector;
00985 
00986   template<typename _Tp>
00987     class __make_unsigned_selector<_Tp, true, false>
00988     {
00989       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
00990       typedef typename __unsignedt::__type __unsigned_type;
00991       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
00992 
00993     public:
00994       typedef typename __cv_unsigned::__type __type;
00995     };
00996 
00997   template<typename _Tp>
00998     class __make_unsigned_selector<_Tp, false, true>
00999     {
01000       // With -fshort-enums, an enum may be as small as a char.
01001       typedef unsigned char __smallest;
01002       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
01003       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
01004       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
01005       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
01006       typedef typename __cond2::type __cond2_type;
01007       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
01008       typedef typename __cond1::type __cond1_type;
01009 
01010     public:
01011       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
01012     };
01013 
01014   // Given an integral/enum type, return the corresponding unsigned
01015   // integer type.
01016   // Primary template.
01017   /// make_unsigned
01018   template<typename _Tp>
01019     struct make_unsigned 
01020     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
01021 
01022   // Integral, but don't define.
01023   template<>
01024     struct make_unsigned<bool>;
01025 
01026 
01027   // Utility for finding the signed versions of unsigned integral types.
01028   template<typename _Tp>
01029     struct __make_signed
01030     { typedef _Tp __type; };
01031 
01032   template<>
01033     struct __make_signed<char>
01034     { typedef signed char __type; };
01035 
01036   template<>
01037     struct __make_signed<unsigned char>
01038     { typedef signed char __type; };
01039 
01040   template<>
01041     struct __make_signed<unsigned short>
01042     { typedef signed short __type; };
01043 
01044   template<>
01045     struct __make_signed<unsigned int>
01046     { typedef signed int __type; };
01047 
01048   template<>
01049     struct __make_signed<unsigned long>
01050     { typedef signed long __type; };
01051 
01052   template<>
01053     struct __make_signed<unsigned long long>
01054     { typedef signed long long __type; };
01055 
01056 
01057   // Select between integral and enum: not possible to be both.
01058   template<typename _Tp, 
01059        bool _IsInt = is_integral<_Tp>::value,
01060        bool _IsEnum = is_enum<_Tp>::value>
01061     class __make_signed_selector;
01062 
01063   template<typename _Tp>
01064     class __make_signed_selector<_Tp, true, false>
01065     {
01066       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
01067       typedef typename __signedt::__type __signed_type;
01068       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
01069 
01070     public:
01071       typedef typename __cv_signed::__type __type;
01072     };
01073 
01074   template<typename _Tp>
01075     class __make_signed_selector<_Tp, false, true>
01076     {
01077       // With -fshort-enums, an enum may be as small as a char.
01078       typedef signed char __smallest;
01079       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
01080       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
01081       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
01082       typedef conditional<__b2, signed int, signed long> __cond2;
01083       typedef typename __cond2::type __cond2_type;
01084       typedef conditional<__b1, signed short, __cond2_type> __cond1;
01085       typedef typename __cond1::type __cond1_type;
01086 
01087     public:
01088       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
01089     };
01090 
01091   // Given an integral/enum type, return the corresponding signed
01092   // integer type.
01093   // Primary template.
01094   /// make_signed
01095   template<typename _Tp>
01096     struct make_signed 
01097     { typedef typename __make_signed_selector<_Tp>::__type type; };
01098 
01099   // Integral, but don't define.
01100   template<>
01101     struct make_signed<bool>;
01102 
01103   /// common_type
01104   template<typename... _Tp>
01105     struct common_type;
01106 
01107   template<typename _Tp>
01108     struct common_type<_Tp>
01109     { typedef _Tp type; };
01110 
01111   template<typename _Tp, typename _Up>
01112     struct common_type<_Tp, _Up>
01113     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
01114 
01115   template<typename _Tp, typename _Up, typename... _Vp>
01116     struct common_type<_Tp, _Up, _Vp...>
01117     {
01118       typedef typename
01119         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
01120     };
01121 
01122   /// declval
01123   template<typename _Tp>
01124     struct __declval_protector
01125     {
01126       static const bool __stop = false;
01127       static typename add_rvalue_reference<_Tp>::type __delegate();
01128     };
01129 
01130   template<typename _Tp>
01131     inline typename add_rvalue_reference<_Tp>::type
01132     declval() noexcept
01133     {
01134       static_assert(__declval_protector<_Tp>::__stop,
01135             "declval() must not be used!");
01136       return __declval_protector<_Tp>::__delegate();
01137     }
01138 
01139   /// result_of
01140   template<typename _Signature>
01141     class result_of;
01142 
01143   template<typename _Functor, typename... _ArgTypes>
01144     struct result_of<_Functor(_ArgTypes...)>
01145     {
01146       typedef
01147         decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
01148         type;
01149     };
01150 
01151   /**
01152    *  Use SFINAE to determine if the type _Tp has a publicly-accessible
01153    *  member type _NTYPE.
01154    */
01155 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE)                         \
01156   template<typename _Tp>                                         \
01157     class __has_##_NTYPE##_helper                                \
01158     : __sfinae_types                                             \
01159     {                                                            \
01160       template<typename _Up>                                     \
01161         struct _Wrap_type                                        \
01162     { };                                                     \
01163                                                                  \
01164       template<typename _Up>                                     \
01165         static __one __test(_Wrap_type<typename _Up::_NTYPE>*);  \
01166                                                                  \
01167       template<typename _Up>                                     \
01168         static __two __test(...);                                \
01169                                                                  \
01170     public:                                                      \
01171       static const bool value = sizeof(__test<_Tp>(0)) == 1;     \
01172     };                                                           \
01173                                                                  \
01174   template<typename _Tp>                                         \
01175     struct __has_##_NTYPE                                        \
01176     : integral_constant<bool, __has_##_NTYPE##_helper            \
01177             <typename remove_cv<_Tp>::type>::value>  \
01178     { };
01179 
01180 #undef _DEFINE_SPEC_0_HELPER
01181 #undef _DEFINE_SPEC_1_HELPER
01182 #undef _DEFINE_SPEC_2_HELPER
01183 #undef _DEFINE_SPEC
01184 
01185   // @} group metaprogramming
01186 _GLIBCXX_END_NAMESPACE_VERSION
01187 } // namespace
01188 
01189 #endif  // __GXX_EXPERIMENTAL_CXX0X__
01190 
01191 #endif  // _GLIBCXX_TYPE_TRAITS