# 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