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