# tr1/type_traits

Go to the documentation of this file.

    00001 // TR1 type_traits -*- C++ -*-
    00002
    00003 // Copyright (C) 2004, 2005, 2006, 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 tr1/type_traits
    00026  *  This is a TR1 C++ Library header.
    00027  */
    00028
    00029 #ifndef _GLIBCXX_TR1_TYPE_TRAITS
    00030 #define _GLIBCXX_TR1_TYPE_TRAITS 1
    00031
    00032 #pragma GCC system_header
    00033
    00034 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
    00035 #  error TR1 header cannot be included from C++0x header
    00036 #endif
    00037
    00038 #include <cstddef>
    00039
    00040 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
    00041 #  include <tr1_impl/type_traits>
    00042 #else
    00043 #  define _GLIBCXX_INCLUDE_AS_TR1
    00044 #  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
    00045 #  define _GLIBCXX_END_NAMESPACE_TR1 }
    00046 #  define _GLIBCXX_TR1 tr1::
    00047 #  include <tr1_impl/type_traits>
    00048 #  undef _GLIBCXX_TR1
    00049 #  undef _GLIBCXX_END_NAMESPACE_TR1
    00050 #  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
    00051 #  undef _GLIBCXX_INCLUDE_AS_TR1
    00052 #endif
    00053
    00054 namespace std
    00055 {
    00056 namespace tr1
    00057 {
    00058 #define _DEFINE_SPEC(_Trait, _Type)    \
    00059   template<>                           \
    00060     struct _Trait<_Type>           \
    00061     : public true_type { };
    00062
    00063   template<typename>
    00064     struct is_reference
    00065     : public false_type { };
    00066
    00067   template<typename _Tp>
    00068     struct is_reference<_Tp&>
    00069     : public true_type { };
    00070
    00071   template<typename _Tp>
    00072     struct is_pod
    00073     : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value>
    00074     { };
    00075
    00076   template<typename _Tp>
    00077     struct has_trivial_constructor
    00078     : public integral_constant<bool, is_pod<_Tp>::value>
    00079     { };
    00080
    00081   template<typename _Tp>
    00082     struct has_trivial_copy
    00083     : public integral_constant<bool, is_pod<_Tp>::value>
    00084     { };
    00085
    00086   template<typename _Tp>
    00087     struct has_trivial_assign
    00088     : public integral_constant<bool, is_pod<_Tp>::value>
    00089     { };
    00090
    00091   template<typename _Tp>
    00092     struct has_trivial_destructor
    00093     : public integral_constant<bool, is_pod<_Tp>::value>
    00094     { };
    00095
    00096   template<typename _Tp>
    00097     struct has_nothrow_constructor
    00098     : public integral_constant<bool, is_pod<_Tp>::value>
    00099     { };
    00100
    00101   template<typename _Tp>
    00102     struct has_nothrow_copy
    00103     : public integral_constant<bool, is_pod<_Tp>::value>
    00104     { };
    00105
    00106   template<typename _Tp>
    00107     struct has_nothrow_assign
    00108     : public integral_constant<bool, is_pod<_Tp>::value>
    00109     { };
    00110
    00111   template<typename>
    00112     struct __is_signed_helper
    00113     : public false_type { };
    00114   _DEFINE_SPEC(__is_signed_helper, signed char)
    00115   _DEFINE_SPEC(__is_signed_helper, short)
    00116   _DEFINE_SPEC(__is_signed_helper, int)
    00117   _DEFINE_SPEC(__is_signed_helper, long)
    00118   _DEFINE_SPEC(__is_signed_helper, long long)
    00119
    00120   template<typename _Tp>
    00121     struct is_signed
    00122     : public integral_constant<bool, (__is_signed_helper<typename
    00123                       remove_cv<_Tp>::type>::value)>
    00124     { };
    00125
    00126   template<typename>
    00127     struct __is_unsigned_helper
    00128     : public false_type { };
    00129   _DEFINE_SPEC(__is_unsigned_helper, unsigned char)
    00130   _DEFINE_SPEC(__is_unsigned_helper, unsigned short)
    00131   _DEFINE_SPEC(__is_unsigned_helper, unsigned int)
    00132   _DEFINE_SPEC(__is_unsigned_helper, unsigned long)
    00133   _DEFINE_SPEC(__is_unsigned_helper, unsigned long long)
    00134
    00135   template<typename _Tp>
    00136     struct is_unsigned
    00137     : public integral_constant<bool, (__is_unsigned_helper<typename
    00138                       remove_cv<_Tp>::type>::value)>
    00139     { };
    00140
    00141   template<typename _Base, typename _Derived>
    00142     struct __is_base_of_helper
    00143     {
    00144       typedef typename remove_cv<_Base>::type    _NoCv_Base;
    00145       typedef typename remove_cv<_Derived>::type _NoCv_Derived;
    00146       static const bool __value = (is_same<_Base, _Derived>::value
    00147                    || (__is_base_of(_Base, _Derived)
    00148                        && !is_same<_NoCv_Base,
    00149                                    _NoCv_Derived>::value));
    00150     };
    00151
    00152   template<typename _Base, typename _Derived>
    00153     struct is_base_of
    00154     : public integral_constant<bool,
    00155                    __is_base_of_helper<_Base, _Derived>::__value>
    00156     { };
    00157
    00158   template<typename _From, typename _To>
    00159     struct __is_convertible_simple
    00160     : public __sfinae_types
    00161     {
    00162     private:
    00163       static __one __test(_To);
    00164       static __two __test(...);
    00165       static _From __makeFrom();
    00166
    00167     public:
    00168       static const bool __value = sizeof(__test(__makeFrom())) == 1;
    00169     };
    00170
    00171   template<typename _Tp>
    00172     struct add_reference;
    00173
    00174   template<typename _Tp>
    00175     struct __is_int_or_cref
    00176     {
    00177       typedef typename remove_reference<_Tp>::type __rr_Tp;
    00178       static const bool __value = (is_integral<_Tp>::value
    00179                    || (is_integral<__rr_Tp>::value
    00180                        && is_const<__rr_Tp>::value
    00181                        && !is_volatile<__rr_Tp>::value));
    00182     };
    00183
    00184   template<typename _From, typename _To,
    00185        bool = (is_void<_From>::value || is_void<_To>::value
    00186            || is_function<_To>::value || is_array<_To>::value
    00187            // This special case is here only to avoid warnings.
    00188            || (is_floating_point<typename
    00189                remove_reference<_From>::type>::value
    00190                && __is_int_or_cref<_To>::__value))>
    00191     struct __is_convertible_helper
    00192     {
    00193       // "An imaginary lvalue of type From...".
    00194       static const bool __value = (__is_convertible_simple<typename
    00195                    add_reference<_From>::type, _To>::__value);
    00196     };
    00197
    00198   template<typename _From, typename _To>
    00199     struct __is_convertible_helper<_From, _To, true>
    00200     { static const bool __value = (is_void<_To>::value
    00201                    || (__is_int_or_cref<_To>::__value
    00202                        && !is_void<_From>::value)); };
    00203
    00204   template<typename _From, typename _To>
    00205     struct is_convertible
    00206     : public integral_constant<bool,
    00207                    __is_convertible_helper<_From, _To>::__value>
    00208     { };
    00209
    00210   // reference modifications [4.7.2].
    00211   template<typename _Tp>
    00212     struct remove_reference
    00213     { typedef _Tp     type; };
    00214
    00215   template<typename _Tp>
    00216     struct remove_reference<_Tp&>
    00217     { typedef _Tp     type; };
    00218
    00219   // NB: Careful with reference to void.
    00220   template<typename _Tp, bool = (is_void<_Tp>::value
    00221                  || is_reference<_Tp>::value)>
    00222     struct __add_reference_helper
    00223     { typedef _Tp&    type; };
    00224
    00225   template<typename _Tp>
    00226     struct __add_reference_helper<_Tp, true>
    00227     { typedef _Tp     type; };
    00228
    00229   template<typename _Tp>
    00230     struct add_reference
    00231     : public __add_reference_helper<_Tp>
    00232     { };
    00233
    00234   // other transformations [4.8].
    00235   template<std::size_t _Len, std::size_t _Align>
    00236     struct aligned_storage
    00237     {
    00238       union type
    00239       {
    00240     unsigned char __data[_Len];
    00241     struct __attribute__((__aligned__((_Align)))) { } __align;
    00242       };
    00243     };
    00244
    00245 #undef _DEFINE_SPEC
    00246 }
    00247 }
    00248
    00249 #endif // _GLIBCXX_TR1_TYPE_TRAITS