# tr1/type_traits

Go to the documentation of this file.

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