# type_traits

Go to the documentation of this file.

    00001 // C++0x type_traits -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009 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 <c++0x_warning.h>
    00036 #else
    00037
    00038 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
    00039 #  error C++0x header cannot be included from TR1 header
    00040 #endif
    00041
    00042 #include <cstddef>
    00043
    00044 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
    00045 #  include <tr1_impl/type_traits>
    00046 #else
    00047 #  define _GLIBCXX_INCLUDE_AS_CXX0X
    00048 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1
    00049 #  define _GLIBCXX_END_NAMESPACE_TR1
    00050 #  define _GLIBCXX_TR1
    00051 #  include <tr1_impl/type_traits>
    00052 #  undef _GLIBCXX_TR1
    00053 #  undef _GLIBCXX_END_NAMESPACE_TR1
    00054 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
    00055 #  undef _GLIBCXX_INCLUDE_AS_CXX0X
    00056 #endif
    00057
    00058 namespace std
    00059 {
    00060   /** @addtogroup metaprogramming
    00061    * @{
    00062    */
    00063
    00064   // Primary classification traits.
    00065
    00066   /// is_lvalue_reference
    00067   template<typename>
    00068     struct is_lvalue_reference
    00069     : public false_type { };
    00070
    00071   template<typename _Tp>
    00072     struct is_lvalue_reference<_Tp&>
    00073     : public true_type { };
    00074
    00075   /// is_rvalue_reference
    00076   template<typename>
    00077     struct is_rvalue_reference
    00078     : public false_type { };
    00079
    00080   template<typename _Tp>
    00081     struct is_rvalue_reference<_Tp&&>
    00082     : public true_type { };
    00083
    00084   // Secondary classification traits.
    00085
    00086   /// is_reference
    00087   template<typename _Tp>
    00088     struct is_reference
    00089     : public integral_constant<bool, (is_lvalue_reference<_Tp>::value
    00090                       || is_rvalue_reference<_Tp>::value)>
    00091     { };
    00092
    00093   // Reference transformations.
    00094
    00095   /// remove_reference
    00096   template<typename _Tp>
    00097     struct remove_reference
    00098     { typedef _Tp   type; };
    00099
    00100   template<typename _Tp>
    00101     struct remove_reference<_Tp&>
    00102     { typedef _Tp   type; };
    00103
    00104   template<typename _Tp>
    00105     struct remove_reference<_Tp&&>
    00106     { typedef _Tp   type; };
    00107
    00108   template<typename _Tp,
    00109        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value,
    00110        bool = is_rvalue_reference<_Tp>::value>
    00111     struct __add_lvalue_reference_helper
    00112     { typedef _Tp   type; };
    00113
    00114   template<typename _Tp>
    00115     struct __add_lvalue_reference_helper<_Tp, true, false>
    00116     { typedef _Tp&   type; };
    00117
    00118   template<typename _Tp>
    00119     struct __add_lvalue_reference_helper<_Tp, false, true>
    00120     { typedef typename remove_reference<_Tp>::type&   type; };
    00121
    00122   /// add_lvalue_reference
    00123   template<typename _Tp>
    00124     struct add_lvalue_reference
    00125     : public __add_lvalue_reference_helper<_Tp>
    00126     { };
    00127
    00128   template<typename _Tp,
    00129        bool = !is_reference<_Tp>::value && !is_void<_Tp>::value>
    00130     struct __add_rvalue_reference_helper
    00131     { typedef _Tp   type; };
    00132
    00133   template<typename _Tp>
    00134     struct __add_rvalue_reference_helper<_Tp, true>
    00135     { typedef _Tp&&   type; };
    00136
    00137   /// add_rvalue_reference
    00138   template<typename _Tp>
    00139     struct add_rvalue_reference
    00140     : public __add_rvalue_reference_helper<_Tp>
    00141     { };
    00142
    00143   // Scalar properties and transformations.
    00144
    00145   template<typename _Tp,
    00146        bool = is_integral<_Tp>::value,
    00147        bool = is_floating_point<_Tp>::value>
    00148     struct __is_signed_helper
    00149     : public false_type { };
    00150
    00151   template<typename _Tp>
    00152     struct __is_signed_helper<_Tp, false, true>
    00153     : public true_type { };
    00154
    00155   template<typename _Tp>
    00156     struct __is_signed_helper<_Tp, true, false>
    00157     : public integral_constant<bool, _Tp(-1) < _Tp(0)>
    00158     { };
    00159
    00160   /// is_signed
    00161   template<typename _Tp>
    00162     struct is_signed
    00163     : public integral_constant<bool, __is_signed_helper<_Tp>::value>
    00164     { };
    00165
    00166   /// is_unsigned
    00167   template<typename _Tp>
    00168     struct is_unsigned
    00169     : public integral_constant<bool, (is_arithmetic<_Tp>::value
    00170                       && !is_signed<_Tp>::value)>
    00171     { };
    00172
    00173   // Member introspection.
    00174
    00175   /// is_pod
    00176   template<typename _Tp>
    00177     struct is_pod
    00178     : public integral_constant<bool, __is_pod(_Tp)>
    00179     { };
    00180
    00181   /// has_trivial_default_constructor
    00182   template<typename _Tp>
    00183     struct has_trivial_default_constructor
    00184     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
    00185     { };
    00186
    00187   /// has_trivial_copy_constructor
    00188   template<typename _Tp>
    00189     struct has_trivial_copy_constructor
    00190     : public integral_constant<bool, __has_trivial_copy(_Tp)>
    00191     { };
    00192
    00193   /// has_trivial_assign
    00194   template<typename _Tp>
    00195     struct has_trivial_assign
    00196     : public integral_constant<bool, __has_trivial_assign(_Tp)>
    00197     { };
    00198
    00199   /// has_trivial_destructor
    00200   template<typename _Tp>
    00201     struct has_trivial_destructor
    00202     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
    00203     { };
    00204
    00205   /// has_nothrow_default_constructor
    00206   template<typename _Tp>
    00207     struct has_nothrow_default_constructor
    00208     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
    00209     { };
    00210
    00211   /// has_nothrow_copy_constructor
    00212   template<typename _Tp>
    00213     struct has_nothrow_copy_constructor
    00214     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
    00215     { };
    00216
    00217   /// has_nothrow_assign
    00218   template<typename _Tp>
    00219     struct has_nothrow_assign
    00220     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
    00221     { };
    00222
    00223   /// is_base_of
    00224   template<typename _Base, typename _Derived>
    00225     struct is_base_of
    00226     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
    00227     { };
    00228
    00229   // Relationships between types.
    00230   template<typename _From, typename _To>
    00231     struct __is_convertible_simple
    00232     : public __sfinae_types
    00233     {
    00234     private:
    00235       static __one __test(_To);
    00236       static __two __test(...);
    00237       static _From __makeFrom();
    00238
    00239     public:
    00240       static const bool __value = sizeof(__test(__makeFrom())) == 1;
    00241     };
    00242
    00243   template<typename _Tp>
    00244     struct __is_int_or_cref
    00245     {
    00246       typedef typename remove_reference<_Tp>::type __rr_Tp;
    00247       static const bool __value = (is_integral<_Tp>::value
    00248                    || (is_integral<__rr_Tp>::value
    00249                        && is_const<__rr_Tp>::value
    00250                        && !is_volatile<__rr_Tp>::value));
    00251     };
    00252
    00253   template<typename _From, typename _To,
    00254        bool = (is_void<_From>::value || is_void<_To>::value
    00255            || is_function<_To>::value || is_array<_To>::value
    00256            // This special case is here only to avoid warnings.
    00257            || (is_floating_point<typename
    00258                remove_reference<_From>::type>::value
    00259                && __is_int_or_cref<_To>::__value))>
    00260     struct __is_convertible_helper
    00261     {
    00262       // "An imaginary lvalue of type From...".
    00263       static const bool __value = (__is_convertible_simple<typename
    00264                    add_lvalue_reference<_From>::type,
    00265                    _To>::__value);
    00266     };
    00267
    00268   template<typename _From, typename _To>
    00269     struct __is_convertible_helper<_From, _To, true>
    00270     { static const bool __value = (is_void<_To>::value
    00271                    || (__is_int_or_cref<_To>::__value
    00272                        && !is_void<_From>::value)); };
    00273
    00274   // XXX FIXME
    00275   // The C++0x specifications are different, see N2255.
    00276   /// is_convertible
    00277   template<typename _From, typename _To>
    00278     struct is_convertible
    00279     : public integral_constant<bool,
    00280                    __is_convertible_helper<_From, _To>::__value>
    00281     { };
    00282
    00283   template<std::size_t _Len>
    00284     struct __aligned_storage_msa
    00285     {
    00286       union __type
    00287       {
    00288     unsigned char __data[_Len];
    00289     struct __attribute__((__aligned__)) { } __align;
    00290       };
    00291     };
    00292
    00293   /**
    00294    *  @brief Alignment type.
    00295    *
    00296    *  The value of _Align is a default-alignment which shall be the
    00297    *  most stringent alignment requirement for any C++ object type
    00298    *  whose size is no greater than _Len (3.9). The member typedef
    00299    *  type shall be a POD type suitable for use as uninitialized
    00300    *  storage for any object whose size is at most _Len and whose
    00301    *  alignment is a divisor of _Align.
    00302   */
    00303   template<std::size_t _Len, std::size_t _Align =
    00304        __alignof__(typename __aligned_storage_msa<_Len>::__type)>
    00305     struct aligned_storage
    00306     {
    00307       union type
    00308       {
    00309     unsigned char __data[_Len];
    00310     struct __attribute__((__aligned__((_Align)))) { } __align;
    00311       };
    00312     };
    00313
    00314
    00315   // Define a nested type if some predicate holds.
    00316   // Primary template.
    00317   /// enable_if
    00318   template<bool, typename _Tp = void>
    00319     struct enable_if
    00320     { };
    00321
    00322   // Partial specialization for true.
    00323   template<typename _Tp>
    00324     struct enable_if<true, _Tp>
    00325     { typedef _Tp type; };
    00326
    00327
    00328   // A conditional expression, but for types. If true, first, if false, second.
    00329   // Primary template.
    00330   /// conditional
    00331   template<bool _Cond, typename _Iftrue, typename _Iffalse>
    00332     struct conditional
    00333     { typedef _Iftrue type; };
    00334
    00335   // Partial specialization for false.
    00336   template<typename _Iftrue, typename _Iffalse>
    00337     struct conditional<false, _Iftrue, _Iffalse>
    00338     { typedef _Iffalse type; };
    00339
    00340
    00341   // Decay trait for arrays and functions, used for perfect forwarding
    00342   // in make_pair, make_tuple, etc.
    00343   template<typename _Up,
    00344        bool _IsArray = is_array<_Up>::value,
    00345        bool _IsFunction = is_function<_Up>::value>
    00346     struct __decay_selector;
    00347
    00348   // NB: DR 705.
    00349   template<typename _Up>
    00350     struct __decay_selector<_Up, false, false>
    00351     { typedef typename remove_cv<_Up>::type __type; };
    00352
    00353   template<typename _Up>
    00354     struct __decay_selector<_Up, true, false>
    00355     { typedef typename remove_extent<_Up>::type* __type; };
    00356
    00357   template<typename _Up>
    00358     struct __decay_selector<_Up, false, true>
    00359     { typedef typename add_pointer<_Up>::type __type; };
    00360
    00361   /// decay
    00362   template<typename _Tp>
    00363     struct decay
    00364     {
    00365     private:
    00366       typedef typename remove_reference<_Tp>::type __remove_type;
    00367
    00368     public:
    00369       typedef typename __decay_selector<__remove_type>::__type type;
    00370     };
    00371
    00372
    00373   // Utility for constructing identically cv-qualified types.
    00374   template<typename _Unqualified, bool _IsConst, bool _IsVol>
    00375     struct __cv_selector;
    00376
    00377   template<typename _Unqualified>
    00378     struct __cv_selector<_Unqualified, false, false>
    00379     { typedef _Unqualified __type; };
    00380
    00381   template<typename _Unqualified>
    00382     struct __cv_selector<_Unqualified, false, true>
    00383     { typedef volatile _Unqualified __type; };
    00384
    00385   template<typename _Unqualified>
    00386     struct __cv_selector<_Unqualified, true, false>
    00387     { typedef const _Unqualified __type; };
    00388
    00389   template<typename _Unqualified>
    00390     struct __cv_selector<_Unqualified, true, true>
    00391     { typedef const volatile _Unqualified __type; };
    00392
    00393   template<typename _Qualified, typename _Unqualified,
    00394        bool _IsConst = is_const<_Qualified>::value,
    00395        bool _IsVol = is_volatile<_Qualified>::value>
    00396     struct __match_cv_qualifiers
    00397     {
    00398     private:
    00399       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
    00400
    00401     public:
    00402       typedef typename __match::__type __type;
    00403     };
    00404
    00405
    00406   // Utility for finding the unsigned versions of signed integral types.
    00407   template<typename _Tp>
    00408     struct __make_unsigned
    00409     { typedef _Tp __type; };
    00410
    00411   template<>
    00412     struct __make_unsigned<char>
    00413     { typedef unsigned char __type; };
    00414
    00415   template<>
    00416     struct __make_unsigned<signed char>
    00417     { typedef unsigned char __type; };
    00418
    00419   template<>
    00420     struct __make_unsigned<short>
    00421     { typedef unsigned short __type; };
    00422
    00423   template<>
    00424     struct __make_unsigned<int>
    00425     { typedef unsigned int __type; };
    00426
    00427   template<>
    00428     struct __make_unsigned<long>
    00429     { typedef unsigned long __type; };
    00430
    00431   template<>
    00432     struct __make_unsigned<long long>
    00433     { typedef unsigned long long __type; };
    00434
    00435
    00436   // Select between integral and enum: not possible to be both.
    00437   template<typename _Tp,
    00438        bool _IsInt = is_integral<_Tp>::value,
    00439        bool _IsEnum = is_enum<_Tp>::value>
    00440     struct __make_unsigned_selector;
    00441
    00442   template<typename _Tp>
    00443     struct __make_unsigned_selector<_Tp, true, false>
    00444     {
    00445     private:
    00446       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
    00447       typedef typename __unsignedt::__type __unsigned_type;
    00448       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
    00449
    00450     public:
    00451       typedef typename __cv_unsigned::__type __type;
    00452     };
    00453
    00454   template<typename _Tp>
    00455     struct __make_unsigned_selector<_Tp, false, true>
    00456     {
    00457     private:
    00458       // With -fshort-enums, an enum may be as small as a char.
    00459       typedef unsigned char __smallest;
    00460       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
    00461       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
    00462       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
    00463       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
    00464       typedef typename __cond2::type __cond2_type;
    00465       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
    00466       typedef typename __cond1::type __cond1_type;
    00467
    00468     public:
    00469       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
    00470     };
    00471
    00472   // Given an integral/enum type, return the corresponding unsigned
    00473   // integer type.
    00474   // Primary template.
    00475   /// make_unsigned
    00476   template<typename _Tp>
    00477     struct make_unsigned
    00478     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
    00479
    00480   // Integral, but don't define.
    00481   template<>
    00482     struct make_unsigned<bool>;
    00483
    00484
    00485   // Utility for finding the signed versions of unsigned integral types.
    00486   template<typename _Tp>
    00487     struct __make_signed
    00488     { typedef _Tp __type; };
    00489
    00490   template<>
    00491     struct __make_signed<char>
    00492     { typedef signed char __type; };
    00493
    00494   template<>
    00495     struct __make_signed<unsigned char>
    00496     { typedef signed char __type; };
    00497
    00498   template<>
    00499     struct __make_signed<unsigned short>
    00500     { typedef signed short __type; };
    00501
    00502   template<>
    00503     struct __make_signed<unsigned int>
    00504     { typedef signed int __type; };
    00505
    00506   template<>
    00507     struct __make_signed<unsigned long>
    00508     { typedef signed long __type; };
    00509
    00510   template<>
    00511     struct __make_signed<unsigned long long>
    00512     { typedef signed long long __type; };
    00513
    00514
    00515   // Select between integral and enum: not possible to be both.
    00516   template<typename _Tp,
    00517        bool _IsInt = is_integral<_Tp>::value,
    00518        bool _IsEnum = is_enum<_Tp>::value>
    00519     struct __make_signed_selector;
    00520
    00521   template<typename _Tp>
    00522     struct __make_signed_selector<_Tp, true, false>
    00523     {
    00524     private:
    00525       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
    00526       typedef typename __signedt::__type __signed_type;
    00527       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
    00528
    00529     public:
    00530       typedef typename __cv_signed::__type __type;
    00531     };
    00532
    00533   template<typename _Tp>
    00534     struct __make_signed_selector<_Tp, false, true>
    00535     {
    00536     private:
    00537       // With -fshort-enums, an enum may be as small as a char.
    00538       typedef signed char __smallest;
    00539       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
    00540       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
    00541       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
    00542       typedef conditional<__b2, signed int, signed long> __cond2;
    00543       typedef typename __cond2::type __cond2_type;
    00544       typedef conditional<__b1, signed short, __cond2_type> __cond1;
    00545       typedef typename __cond1::type __cond1_type;
    00546
    00547     public:
    00548       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
    00549     };
    00550
    00551   // Given an integral/enum type, return the corresponding signed
    00552   // integer type.
    00553   // Primary template.
    00554   /// make_signed
    00555   template<typename _Tp>
    00556     struct make_signed
    00557     { typedef typename __make_signed_selector<_Tp>::__type type; };
    00558
    00559   // Integral, but don't define.
    00560   template<>
    00561     struct make_signed<bool>;
    00562
    00563   /// common_type
    00564   template<typename... _Tp>
    00565     struct common_type;
    00566
    00567   template<typename _Tp>
    00568     struct common_type<_Tp>
    00569     {
    00570       static_assert(sizeof(_Tp) > 0, "must be complete type");
    00571       typedef _Tp type;
    00572     };
    00573
    00574   template<typename _Tp, typename _Up>
    00575     class common_type<_Tp, _Up>
    00576     {
    00577       static_assert(sizeof(_Tp) > 0, "must be complete type");
    00578       static_assert(sizeof(_Up) > 0, "must be complete type");
    00579
    00580       static _Tp&& __t();
    00581       static _Up&& __u();
    00582
    00583       // HACK: Prevents optimization of ?: in the decltype
    00584       // expression when the condition is the literal, "true".
    00585       // See, PR36628.
    00586       static bool __true_or_false();
    00587
    00588     public:
    00589       typedef decltype(__true_or_false() ? __t() : __u()) type;
    00590     };
    00591
    00592   template<typename _Tp, typename _Up, typename... _Vp>
    00593     struct common_type<_Tp, _Up, _Vp...>
    00594     {
    00595       typedef typename
    00596         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
    00597     };
    00598
    00599   // @} group metaprogramming
    00600 }
    00601
    00602 #endif  // __GXX_EXPERIMENTAL_CXX0X__
    00603
    00604 #endif  // _GLIBCXX_TYPE_TRAITS
    00605