libstdc++
|
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