type_traits

Go to the documentation of this file.
00001 // <type_traits> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
00017 // along with this library; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
00019 // Boston, MA 02110-1301, USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 /** @file include/type_traits
00031  *  This is a Standard C++ Library header.
00032  */
00033 
00034 #ifndef _GLIBCXX_CXX0X_TYPE_TRAITS
00035 #define _GLIBCXX_CXX0X_TYPE_TRAITS 1
00036 
00037 #pragma GCC system_header
00038 
00039 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00040 # include <c++0x_warning.h>
00041 #endif
00042 
00043 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
00044 #  error C++0x header cannot be included from TR1 header
00045 #endif
00046 
00047 #include <cstddef>
00048 
00049 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
00050 #  include <tr1_impl/type_traits>
00051 #else
00052 #  define _GLIBCXX_INCLUDE_AS_CXX0X
00053 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1
00054 #  define _GLIBCXX_END_NAMESPACE_TR1
00055 #  define _GLIBCXX_TR1
00056 #  include <tr1_impl/type_traits>
00057 #  undef _GLIBCXX_TR1
00058 #  undef _GLIBCXX_END_NAMESPACE_TR1
00059 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
00060 #  undef _GLIBCXX_INCLUDE_AS_CXX0X
00061 #endif
00062 
00063 namespace std
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_object<_Tp>::value || is_function<_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_object<_Tp>::value || is_function<_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, _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   template<typename _Tp>
00178     struct is_pod
00179     : public integral_constant<bool, __is_pod(_Tp)>
00180     { };
00181 
00182   /// has_trivial_default_constructor
00183   template<typename _Tp>
00184     struct has_trivial_default_constructor
00185     : public integral_constant<bool, __has_trivial_constructor(_Tp)>
00186     { };
00187 
00188   /// has_trivial_copy_constructor
00189   template<typename _Tp>
00190     struct has_trivial_copy_constructor
00191     : public integral_constant<bool, __has_trivial_copy(_Tp)>
00192     { };
00193 
00194   /// has_trivial_assign
00195   template<typename _Tp>
00196     struct has_trivial_assign
00197     : public integral_constant<bool, __has_trivial_assign(_Tp)>
00198     { };
00199 
00200   /// has_trivial_destructor
00201   template<typename _Tp>
00202     struct has_trivial_destructor
00203     : public integral_constant<bool, __has_trivial_destructor(_Tp)>
00204     { };
00205 
00206   /// has_nothrow_default_destructor
00207   template<typename _Tp>
00208     struct has_nothrow_default_constructor
00209     : public integral_constant<bool, __has_nothrow_constructor(_Tp)>
00210     { };
00211 
00212   /// has_nothrow_copy_destructor
00213   template<typename _Tp>
00214     struct has_nothrow_copy_constructor
00215     : public integral_constant<bool, __has_nothrow_copy(_Tp)>
00216     { };
00217 
00218   /// has_nothrow_assign
00219   template<typename _Tp>
00220     struct has_nothrow_assign
00221     : public integral_constant<bool, __has_nothrow_assign(_Tp)>
00222     { };
00223 
00224   /// is_base_of
00225   template<typename _Base, typename _Derived>
00226     struct is_base_of
00227     : public integral_constant<bool, __is_base_of(_Base, _Derived)>
00228     { };
00229 
00230   // Relationships between types.
00231   template<typename _From, typename _To>
00232     struct __is_convertible_simple
00233     : public __sfinae_types
00234     {
00235     private:
00236       static __one __test(_To);
00237       static __two __test(...);
00238       static _From __makeFrom();
00239     
00240     public:
00241       static const bool __value = sizeof(__test(__makeFrom())) == 1;
00242     };
00243 
00244   template<typename _Tp>
00245     struct __is_int_or_cref
00246     {
00247       typedef typename remove_reference<_Tp>::type __rr_Tp;
00248       static const bool __value = (is_integral<_Tp>::value
00249                    || (is_integral<__rr_Tp>::value
00250                        && is_const<__rr_Tp>::value
00251                        && !is_volatile<__rr_Tp>::value));
00252     };
00253 
00254   template<typename _From, typename _To,
00255        bool = (is_void<_From>::value || is_void<_To>::value
00256            || is_function<_To>::value || is_array<_To>::value
00257            // This special case is here only to avoid warnings.
00258            || (is_floating_point<typename
00259                remove_reference<_From>::type>::value
00260                && __is_int_or_cref<_To>::__value))>
00261     struct __is_convertible_helper
00262     {
00263       // "An imaginary lvalue of type From...".
00264       static const bool __value = (__is_convertible_simple<typename
00265                    add_lvalue_reference<_From>::type,
00266                    _To>::__value);
00267     };
00268 
00269   template<typename _From, typename _To>
00270     struct __is_convertible_helper<_From, _To, true>
00271     { static const bool __value = (is_void<_To>::value
00272                    || (__is_int_or_cref<_To>::__value
00273                        && !is_void<_From>::value)); };
00274 
00275   // XXX FIXME
00276   // The C++0x specifications are different, see N2255.
00277   /// is_convertible
00278   template<typename _From, typename _To>
00279     struct is_convertible
00280     : public integral_constant<bool,
00281                    __is_convertible_helper<_From, _To>::__value>
00282     { };
00283 
00284   template<std::size_t _Len>
00285     struct __aligned_storage_msa
00286     { 
00287       union __type
00288       {
00289     unsigned char __data[_Len];
00290     struct __attribute__((__aligned__)) { } __align; 
00291       };
00292     };
00293 
00294   /**
00295    *  @brief Alignment type.
00296    *
00297    *  The value of _Align is a default-alignment which shall be the
00298    *  most stringent alignment requirement for any C++ object type
00299    *  whose size is no greater than _Len (3.9). The member typedef
00300    *  type shall be a POD type suitable for use as uninitialized
00301    *  storage for any object whose size is at most _Len and whose
00302    *  alignment is a divisor of _Align.
00303   */
00304   template<std::size_t _Len, std::size_t _Align =
00305        __alignof__(typename __aligned_storage_msa<_Len>::__type)>
00306     struct aligned_storage
00307     { 
00308       union type
00309       {
00310     unsigned char __data[_Len];
00311     struct __attribute__((__aligned__((_Align)))) { } __align; 
00312       };
00313     };
00314 
00315 
00316   // Define a nested type if some predicate holds.
00317   /// Primary template.
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. 
00329   // If true, first, if false, second.
00330   /// Primary template.
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       // GNU enums start with sizeof short.
00459       typedef unsigned short __smallest;
00460       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
00461       static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
00462       typedef conditional<__b2, unsigned int, unsigned long> __cond;
00463       typedef typename __cond::type __cond_type;
00464 
00465     public:
00466       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
00467     };
00468 
00469   // Given an integral/enum type, return the corresponding unsigned
00470   // integer type.
00471   /// Primary template.
00472   template<typename _Tp>
00473     struct make_unsigned 
00474     { typedef typename __make_unsigned_selector<_Tp>::__type type; };
00475 
00476   // Integral, but don't define.
00477   template<>
00478     struct make_unsigned<bool>;
00479 
00480 
00481   // Utility for finding the signed versions of unsigned integral types.
00482   template<typename _Tp>
00483     struct __make_signed
00484     { typedef _Tp __type; };
00485 
00486   template<>
00487     struct __make_signed<char>
00488     { typedef signed char __type; };
00489 
00490   template<>
00491     struct __make_signed<unsigned char>
00492     { typedef signed char __type; };
00493 
00494   template<>
00495     struct __make_signed<unsigned short>
00496     { typedef signed short __type; };
00497 
00498   template<>
00499     struct __make_signed<unsigned int>
00500     { typedef signed int __type; };
00501 
00502   template<>
00503     struct __make_signed<unsigned long>
00504     { typedef signed long __type; };
00505 
00506   template<>
00507     struct __make_signed<unsigned long long>
00508     { typedef signed long long __type; };
00509 
00510 
00511   // Select between integral and enum: not possible to be both.
00512   template<typename _Tp, 
00513        bool _IsInt = is_integral<_Tp>::value,
00514        bool _IsEnum = is_enum<_Tp>::value>
00515     struct __make_signed_selector;
00516   
00517   template<typename _Tp>
00518     struct __make_signed_selector<_Tp, true, false>
00519     {
00520     private:
00521       typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
00522       typedef typename __signedt::__type __signed_type;
00523       typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
00524 
00525     public:
00526       typedef typename __cv_signed::__type __type;
00527     };
00528 
00529   template<typename _Tp>
00530     struct __make_signed_selector<_Tp, false, true>
00531     {
00532     private:
00533       // GNU enums start with sizeof short.
00534       typedef signed short __smallest;
00535       static const bool __b1 = sizeof(_Tp) <= sizeof(__smallest);
00536       static const bool __b2 = sizeof(_Tp) <= sizeof(signed int);
00537       typedef conditional<__b2, signed int, signed long> __cond;
00538       typedef typename __cond::type __cond_type;
00539 
00540     public:
00541       typedef typename conditional<__b1, __smallest, __cond_type>::type __type;
00542     };
00543 
00544   // Given an integral/enum type, return the corresponding signed
00545   // integer type.
00546   /// Primary template.
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 
00556 #endif  // _GLIBCXX_CXX0X_TYPE_TRAITS 
00557 

Generated on Sat Oct 25 05:09:17 2008 for libstdc++ by  doxygen 1.5.6