1 // TR1 type_traits -*- C++ -*- 2 3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file tr1/type_traits 26 * This is a TR1 C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_TR1_TYPE_TRAITS 30 #define _GLIBCXX_TR1_TYPE_TRAITS 1 31 32 #pragma GCC system_header 33 34 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X) 35 # error TR1 header cannot be included from C++0x header 36 #endif 37 38 #include <cstddef> 39 40 #if defined(_GLIBCXX_INCLUDE_AS_TR1) 41 # include <tr1_impl/type_traits> 42 #else 43 # define _GLIBCXX_INCLUDE_AS_TR1 44 # define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 { 45 # define _GLIBCXX_END_NAMESPACE_TR1 } 46 # define _GLIBCXX_TR1 tr1:: 47 # include <tr1_impl/type_traits> 48 # undef _GLIBCXX_TR1 49 # undef _GLIBCXX_END_NAMESPACE_TR1 50 # undef _GLIBCXX_BEGIN_NAMESPACE_TR1 51 # undef _GLIBCXX_INCLUDE_AS_TR1 52 #endif 53 54 namespace std 55 { 56 namespace tr1 57 { 58 #define _DEFINE_SPEC(_Trait, _Type) \ 59 template<> \ 60 struct _Trait<_Type> \ 61 : public true_type { }; 62 63 template<typename> 64 struct is_reference 65 : public false_type { }; 66 67 template<typename _Tp> 68 struct is_reference<_Tp&> 69 : public true_type { }; 70 71 template<typename _Tp> 72 struct is_pod 73 : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value> 74 { }; 75 76 template<typename _Tp> 77 struct has_trivial_constructor 78 : public integral_constant<bool, is_pod<_Tp>::value> 79 { }; 80 81 template<typename _Tp> 82 struct has_trivial_copy 83 : public integral_constant<bool, is_pod<_Tp>::value> 84 { }; 85 86 template<typename _Tp> 87 struct has_trivial_assign 88 : public integral_constant<bool, is_pod<_Tp>::value> 89 { }; 90 91 template<typename _Tp> 92 struct has_trivial_destructor 93 : public integral_constant<bool, is_pod<_Tp>::value> 94 { }; 95 96 template<typename _Tp> 97 struct has_nothrow_constructor 98 : public integral_constant<bool, is_pod<_Tp>::value> 99 { }; 100 101 template<typename _Tp> 102 struct has_nothrow_copy 103 : public integral_constant<bool, is_pod<_Tp>::value> 104 { }; 105 106 template<typename _Tp> 107 struct has_nothrow_assign 108 : public integral_constant<bool, is_pod<_Tp>::value> 109 { }; 110 111 template<typename> 112 struct __is_signed_helper 113 : public false_type { }; 114 _DEFINE_SPEC(__is_signed_helper, signed char) 115 _DEFINE_SPEC(__is_signed_helper, short) 116 _DEFINE_SPEC(__is_signed_helper, int) 117 _DEFINE_SPEC(__is_signed_helper, long) 118 _DEFINE_SPEC(__is_signed_helper, long long) 119 120 template<typename _Tp> 121 struct is_signed 122 : public integral_constant<bool, (__is_signed_helper<typename 123 remove_cv<_Tp>::type>::value)> 124 { }; 125 126 template<typename> 127 struct __is_unsigned_helper 128 : public false_type { }; 129 _DEFINE_SPEC(__is_unsigned_helper, unsigned char) 130 _DEFINE_SPEC(__is_unsigned_helper, unsigned short) 131 _DEFINE_SPEC(__is_unsigned_helper, unsigned int) 132 _DEFINE_SPEC(__is_unsigned_helper, unsigned long) 133 _DEFINE_SPEC(__is_unsigned_helper, unsigned long long) 134 135 template<typename _Tp> 136 struct is_unsigned 137 : public integral_constant<bool, (__is_unsigned_helper<typename 138 remove_cv<_Tp>::type>::value)> 139 { }; 140 141 template<typename _Base, typename _Derived> 142 struct __is_base_of_helper 143 { 144 typedef typename remove_cv<_Base>::type _NoCv_Base; 145 typedef typename remove_cv<_Derived>::type _NoCv_Derived; 146 static const bool __value = (is_same<_Base, _Derived>::value 147 || (__is_base_of(_Base, _Derived) 148 && !is_same<_NoCv_Base, 149 _NoCv_Derived>::value)); 150 }; 151 152 template<typename _Base, typename _Derived> 153 struct is_base_of 154 : public integral_constant<bool, 155 __is_base_of_helper<_Base, _Derived>::__value> 156 { }; 157 158 template<typename _From, typename _To> 159 struct __is_convertible_simple 160 : public __sfinae_types 161 { 162 private: 163 static __one __test(_To); 164 static __two __test(...); 165 static _From __makeFrom(); 166 167 public: 168 static const bool __value = sizeof(__test(__makeFrom())) == 1; 169 }; 170 171 template<typename _Tp> 172 struct add_reference; 173 174 template<typename _Tp> 175 struct __is_int_or_cref 176 { 177 typedef typename remove_reference<_Tp>::type __rr_Tp; 178 static const bool __value = (is_integral<_Tp>::value 179 || (is_integral<__rr_Tp>::value 180 && is_const<__rr_Tp>::value 181 && !is_volatile<__rr_Tp>::value)); 182 }; 183 184 template<typename _From, typename _To, 185 bool = (is_void<_From>::value || is_void<_To>::value 186 || is_function<_To>::value || is_array<_To>::value 187 // This special case is here only to avoid warnings. 188 || (is_floating_point<typename 189 remove_reference<_From>::type>::value 190 && __is_int_or_cref<_To>::__value))> 191 struct __is_convertible_helper 192 { 193 // "An imaginary lvalue of type From...". 194 static const bool __value = (__is_convertible_simple<typename 195 add_reference<_From>::type, _To>::__value); 196 }; 197 198 template<typename _From, typename _To> 199 struct __is_convertible_helper<_From, _To, true> 200 { static const bool __value = (is_void<_To>::value 201 || (__is_int_or_cref<_To>::__value 202 && !is_void<_From>::value)); }; 203 204 template<typename _From, typename _To> 205 struct is_convertible 206 : public integral_constant<bool, 207 __is_convertible_helper<_From, _To>::__value> 208 { }; 209 210 // reference modifications [4.7.2]. 211 template<typename _Tp> 212 struct remove_reference 213 { typedef _Tp type; }; 214 215 template<typename _Tp> 216 struct remove_reference<_Tp&> 217 { typedef _Tp type; }; 218 219 // NB: Careful with reference to void. 220 template<typename _Tp, bool = (is_void<_Tp>::value 221 || is_reference<_Tp>::value)> 222 struct __add_reference_helper 223 { typedef _Tp& type; }; 224 225 template<typename _Tp> 226 struct __add_reference_helper<_Tp, true> 227 { typedef _Tp type; }; 228 229 template<typename _Tp> 230 struct add_reference 231 : public __add_reference_helper<_Tp> 232 { }; 233 234 // other transformations [4.8]. 235 template<std::size_t _Len, std::size_t _Align> 236 struct aligned_storage 237 { 238 union type 239 { 240 unsigned char __data[_Len]; 241 struct __attribute__((__aligned__((_Align)))) { } __align; 242 }; 243 }; 244 245 #undef _DEFINE_SPEC 246 } 247 } 248 249 #endif // _GLIBCXX_TR1_TYPE_TRAITS 250