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   /**
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_pod
00177   // Could use is_standard_layout && is_trivial instead of the builtin.
00178   template<typename _Tp>
00179     struct is_pod
00180     : public integral_constant<bool, __is_pod(_Tp)>
00181     { };
00182 
00183   /// is_standard_layout
00184   template<typename _Tp>
00185     struct is_standard_layout
00186     : public integral_constant<bool, __is_standard_layout(_Tp)>
00187     { };
00188 
00189   /// has_trivial_default_constructor
00190   template<typename _Tp>
00191     struct has_trivial_default_constructor
00192     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
00193     { };
00194 
00195   /// has_trivial_copy_constructor
00196   template<typename _Tp>
00197     struct has_trivial_copy_constructor
00198     : public integral_constant<bool, __has_trivial_copy(_Tp)>
00199     { };
00200 
00201   /// has_trivial_assign
00202   template<typename _Tp>
00203     struct has_trivial_assign
00204     : public integral_constant<bool, __has_trivial_assign(_Tp)>
00205     { };
00206 
00207   /// has_trivial_destructor
00208   template<typename _Tp>
00209     struct has_trivial_destructor
00210     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
00211     { };
00212 
00213   /// is_trivial
00214   template<typename _Tp>
00215     struct is_trivial
00216     : public integral_constant<bool, __is_trivial(_Tp)>
00217     { };
00218 
00219   /// has_nothrow_default_constructor
00220   template<typename _Tp>
00221     struct has_nothrow_default_constructor
00222     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
00223     { };
00224 
00225   /// has_nothrow_copy_constructor
00226   template<typename _Tp>
00227     struct has_nothrow_copy_constructor
00228     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
00229     { };
00230 
00231   /// has_nothrow_assign
00232   template<typename _Tp>
00233     struct has_nothrow_assign
00234     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
00235     { };
00236 
00237   /// is_base_of
00238   template<typename _Base, typename _Derived>
00239     struct is_base_of
00240     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
00241     { };
00242 
00243   template<typename _Tp>
00244     typename add_rvalue_reference<_Tp>::type declval();
00245 
00246   // Relationships between types.
00247   template<typename _From, typename _To,
00248        bool = (is_void<_From>::value || is_void<_To>::value
00249            || is_function<_To>::value || is_array<_To>::value)>
00250     struct __is_convertible_helper
00251     { static const bool __value = (is_void<_From>::value
00252                    && is_void<_To>::value); };
00253 
00254   template<typename _From, typename _To>
00255     struct __is_convertible_helper<_From, _To, false>
00256     : public __sfinae_types
00257     {
00258     private:
00259       static __one __test(_To);
00260       static __two __test(...);
00261 
00262     public:
00263       static const bool __value = sizeof(__test(declval<_From>())) == 1;
00264     };
00265 
00266   // XXX FIXME
00267   // The C++0x specifications require front-end support, see N2255.
00268   /// is_convertible
00269   template<typename _From, typename _To>
00270     struct is_convertible
00271     : public integral_constant<bool,
00272                    __is_convertible_helper<_From, _To>::__value>
00273     { };
00274 
00275   template<std::size_t _Len>
00276     struct __aligned_storage_msa
00277     { 
00278       union __type
00279       {
00280     unsigned char __data[_Len];
00281     struct __attribute__((__aligned__)) { } __align; 
00282       };
00283     };
00284 
00285   /**
00286    *  @brief Alignment type.
00287    *
00288    *  The value of _Align is a default-alignment which shall be the
00289    *  most stringent alignment requirement for any C++ object type
00290    *  whose size is no greater than _Len (3.9). The member typedef
00291    *  type shall be a POD type suitable for use as uninitialized
00292    *  storage for any object whose size is at most _Len and whose
00293    *  alignment is a divisor of _Align.
00294   */
00295   template<std::size_t _Len, std::size_t _Align =
00296        __alignof__(typename __aligned_storage_msa<_Len>::__type)>
00297     struct aligned_storage
00298     { 
00299       union type
00300       {
00301     unsigned char __data[_Len];
00302     struct __attribute__((__aligned__((_Align)))) { } __align; 
00303       };
00304     };
00305 
00306 
00307   // Define a nested type if some predicate holds.
00308   // Primary template.
00309   /// enable_if
00310   template<bool, typename _Tp = void>
00311     struct enable_if 
00312     { };
00313 
00314   // Partial specialization for true.
00315   template<typename _Tp>
00316     struct enable_if<true, _Tp>
00317     { typedef _Tp type; };
00318 
00319 
00320   // A conditional expression, but for types. If true, first, if false, second.
00321   // Primary template.
00322   /// conditional
00323   template<bool _Cond, typename _Iftrue, typename _Iffalse>
00324     struct conditional
00325     { typedef _Iftrue type; };
00326 
00327   // Partial specialization for false.
00328   template<typename _Iftrue, typename _Iffalse>
00329     struct conditional<false, _Iftrue, _Iffalse>
00330     { typedef _Iffalse type; };
00331 
00332 
00333   // Decay trait for arrays and functions, used for perfect forwarding
00334   // in make_pair, make_tuple, etc.
00335   template<typename _Up, 
00336        bool _IsArray = is_array<_Up>::value,
00337        bool _IsFunction = is_function<_Up>::value> 
00338     struct __decay_selector;
00339 
00340   // NB: DR 705.
00341   template<typename _Up> 
00342     struct __decay_selector<_Up, false, false>
00343     { typedef typename remove_cv<_Up>::type __type; };
00344 
00345   template<typename _Up> 
00346     struct __decay_selector<_Up, true, false>
00347     { typedef typename remove_extent<_Up>::type* __type; };
00348 
00349   template<typename _Up> 
00350     struct __decay_selector<_Up, false, true>
00351     { typedef typename add_pointer<_Up>::type __type; };
00352 
00353   /// decay
00354   template<typename _Tp> 
00355     struct decay 
00356     { 
00357     private:
00358       typedef typename remove_reference<_Tp>::type __remove_type;
00359 
00360     public:
00361       typedef typename __decay_selector<__remove_type>::__type type;
00362     };
00363 
00364 
00365   // Utility for constructing identically cv-qualified types.
00366   template<typename _Unqualified, bool _IsConst, bool _IsVol>
00367     struct __cv_selector;
00368 
00369   template<typename _Unqualified>
00370     struct __cv_selector<_Unqualified, false, false>
00371     { typedef _Unqualified __type; };
00372 
00373   template<typename _Unqualified>
00374     struct __cv_selector<_Unqualified, false, true>
00375     { typedef volatile _Unqualified __type; };
00376 
00377   template<typename _Unqualified>
00378     struct __cv_selector<_Unqualified, true, false>
00379     { typedef const _Unqualified __type; };
00380 
00381   template<typename _Unqualified>
00382     struct __cv_selector<_Unqualified, true, true>
00383     { typedef const volatile _Unqualified __type; };
00384 
00385   template<typename _Qualified, typename _Unqualified,
00386        bool _IsConst = is_const<_Qualified>::value,
00387        bool _IsVol = is_volatile<_Qualified>::value>
00388     struct __match_cv_qualifiers
00389     {
00390     private:
00391       typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match;
00392 
00393     public:
00394       typedef typename __match::__type __type; 
00395     };
00396 
00397 
00398   // Utility for finding the unsigned versions of signed integral types.
00399   template<typename _Tp>
00400     struct __make_unsigned
00401     { typedef _Tp __type; };
00402 
00403   template<>
00404     struct __make_unsigned<char>
00405     { typedef unsigned char __type; };
00406 
00407   template<>
00408     struct __make_unsigned<signed char>
00409     { typedef unsigned char __type; };
00410 
00411   template<>
00412     struct __make_unsigned<short>
00413     { typedef unsigned short __type; };
00414 
00415   template<>
00416     struct __make_unsigned<int>
00417     { typedef unsigned int __type; };
00418 
00419   template<>
00420     struct __make_unsigned<long>
00421     { typedef unsigned long __type; };
00422 
00423   template<>
00424     struct __make_unsigned<long long>
00425     { typedef unsigned long long __type; };
00426 
00427 
00428   // Select between integral and enum: not possible to be both.
00429   template<typename _Tp, 
00430        bool _IsInt = is_integral<_Tp>::value,
00431        bool _IsEnum = is_enum<_Tp>::value>
00432     struct __make_unsigned_selector;
00433   
00434   template<typename _Tp>
00435     struct __make_unsigned_selector<_Tp, true, false>
00436     {
00437     private:
00438       typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
00439       typedef typename __unsignedt::__type __unsigned_type;
00440       typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
00441 
00442     public:
00443       typedef typename __cv_unsigned::__type __type;
00444     };
00445 
00446   template<typename _Tp>
00447     struct __make_unsigned_selector<_Tp, false, true>
00448     {
00449     private:
00450       // With -fshort-enums, an enum may be as small as a char.
00451       typedef unsigned char __smallest;
00452       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
00453       static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
00454       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
00455       typedef conditional<__b2, unsigned int, unsigned long> __cond2;
00456       typedef typename __cond2::type __cond2_type;
00457       typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
00458       typedef typename __cond1::type __cond1_type;
00459 
00460     public:
00461       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
00462     };
00463 
00464   // Given an integral/enum type, return the corresponding unsigned
00465   // integer type.
00466   // Primary template.
00467   /// make_unsigned
00468   template<typename _Tp>
00469     struct make_unsigned 
00470     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
00471 
00472   // Integral, but don't define.
00473   template<>
00474     struct make_unsigned<bool>;
00475 
00476 
00477   // Utility for finding the signed versions of unsigned integral types.
00478   template<typename _Tp>
00479     struct __make_signed
00480     { typedef _Tp __type; };
00481 
00482   template<>
00483     struct __make_signed<char>
00484     { typedef signed char __type; };
00485 
00486   template<>
00487     struct __make_signed<unsigned char>
00488     { typedef signed char __type; };
00489 
00490   template<>
00491     struct __make_signed<unsigned short>
00492     { typedef signed short __type; };
00493 
00494   template<>
00495     struct __make_signed<unsigned int>
00496     { typedef signed int __type; };
00497 
00498   template<>
00499     struct __make_signed<unsigned long>
00500     { typedef signed long __type; };
00501 
00502   template<>
00503     struct __make_signed<unsigned long long>
00504     { typedef signed long long __type; };
00505 
00506 
00507   // Select between integral and enum: not possible to be both.
00508   template<typename _Tp, 
00509        bool _IsInt = is_integral<_Tp>::value,
00510        bool _IsEnum = is_enum<_Tp>::value>
00511     struct __make_signed_selector;
00512   
00513   template<typename _Tp>
00514     struct __make_signed_selector<_Tp, true, false>
00515     {
00516     private:
00517       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
00518       typedef typename __signedt::__type __signed_type;
00519       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
00520 
00521     public:
00522       typedef typename __cv_signed::__type __type;
00523     };
00524 
00525   template<typename _Tp>
00526     struct __make_signed_selector<_Tp, false, true>
00527     {
00528     private:
00529       // With -fshort-enums, an enum may be as small as a char.
00530       typedef signed char __smallest;
00531       static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
00532       static const bool __b1 = sizeof(_Tp) <= sizeof(signed short);
00533       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
00534       typedef conditional<__b2, signed int, signed long> __cond2;
00535       typedef typename __cond2::type __cond2_type;
00536       typedef conditional<__b1, signed short, __cond2_type> __cond1;
00537       typedef typename __cond1::type __cond1_type;
00538 
00539     public:
00540       typedef typename conditional<__b0, __smallest, __cond1_type>::type __type;
00541     };
00542 
00543   // Given an integral/enum type, return the corresponding signed
00544   // integer type.
00545   // Primary template.
00546   /// make_signed
00547   template<typename _Tp>
00548     struct make_signed 
00549     { typedef typename __make_signed_selector<_Tp>::__type type; };
00550 
00551   // Integral, but don't define.
00552   template<>
00553     struct make_signed<bool>;
00554 
00555   /// common_type
00556   template<typename... _Tp>
00557     struct common_type;
00558 
00559   template<typename _Tp>
00560     struct common_type<_Tp>
00561     { typedef _Tp type; };
00562 
00563   template<typename _Tp, typename _Up>
00564     struct common_type<_Tp, _Up>
00565     { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; };
00566 
00567   template<typename _Tp, typename _Up, typename... _Vp>
00568     struct common_type<_Tp, _Up, _Vp...>
00569     {
00570       typedef typename
00571         common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
00572     };
00573   // @} group metaprogramming
00574 
00575   /// declval
00576   template<typename _Tp>
00577     struct __declval_protector
00578     {
00579       static const bool __stop = false;
00580       static typename add_rvalue_reference<_Tp>::type __delegate();
00581     };
00582 
00583   template<typename _Tp>
00584     inline typename add_rvalue_reference<_Tp>::type
00585     declval()
00586     {
00587       static_assert(__declval_protector<_Tp>::__stop,
00588             "declval() must not be used!");
00589       return __declval_protector<_Tp>::__delegate();
00590     }
00591 }
00592 
00593 #endif  // __GXX_EXPERIMENTAL_CXX0X__
00594 
00595 #endif  // _GLIBCXX_TYPE_TRAITS

Generated on 21 Dec 2009 for libstdc++ by  doxygen 1.6.1