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 

Generated on Tue Apr 21 13:13:35 2009 for libstdc++ by  doxygen 1.5.8