1 // TR1 type_traits -*- C++ -*- 2 3 // Copyright (C) 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_impl/type_traits 26 * This is an internal header file, included by other library headers. 27 * You should not attempt to use it directly. 28 */ 29 30 namespace std 31 { 32 _GLIBCXX_BEGIN_NAMESPACE_TR1 33 34 /** 35 * @defgroup metaprogramming Type Traits 36 * @ingroup utilities 37 * 38 * Compile time type transformation and information. 39 * @{ 40 */ 41 42 // For use in __is_convertible_simple. 43 struct __sfinae_types 44 { 45 typedef char __one; 46 typedef struct { char __arr[2]; } __two; 47 }; 48 49 #define _DEFINE_SPEC_0_HELPER \ 50 template<> 51 52 #define _DEFINE_SPEC_1_HELPER \ 53 template<typename _Tp> 54 55 #define _DEFINE_SPEC_2_HELPER \ 56 template<typename _Tp, typename _Cp> 57 58 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 59 _DEFINE_SPEC_##_Order##_HELPER \ 60 struct _Trait<_Type> \ 61 : public integral_constant<bool, _Value> { }; 62 63 // helper classes [4.3]. 64 65 /// integral_constant 66 template<typename _Tp, _Tp __v> 67 struct integral_constant 68 { 69 static const _Tp value = __v; 70 typedef _Tp value_type; 71 typedef integral_constant<_Tp, __v> type; 72 }; 73 74 /// typedef for true_type 75 typedef integral_constant<bool, true> true_type; 76 77 /// typedef for false_type 78 typedef integral_constant<bool, false> false_type; 79 80 template<typename _Tp, _Tp __v> 81 const _Tp integral_constant<_Tp, __v>::value; 82 83 /// remove_cv 84 template<typename> 85 struct remove_cv; 86 87 template<typename> 88 struct __is_void_helper 89 : public false_type { }; 90 _DEFINE_SPEC(0, __is_void_helper, void, true) 91 92 // primary type categories [4.5.1]. 93 94 /// is_void 95 template<typename _Tp> 96 struct is_void 97 : public integral_constant<bool, (__is_void_helper<typename 98 remove_cv<_Tp>::type>::value)> 99 { }; 100 101 template<typename> 102 struct __is_integral_helper 103 : public false_type { }; 104 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 105 _DEFINE_SPEC(0, __is_integral_helper, char, true) 106 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 107 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 108 #ifdef _GLIBCXX_USE_WCHAR_T 109 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 110 #endif 111 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X 112 _DEFINE_SPEC(0, __is_integral_helper, char16_t, true) 113 _DEFINE_SPEC(0, __is_integral_helper, char32_t, true) 114 #endif 115 _DEFINE_SPEC(0, __is_integral_helper, short, true) 116 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) 117 _DEFINE_SPEC(0, __is_integral_helper, int, true) 118 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) 119 _DEFINE_SPEC(0, __is_integral_helper, long, true) 120 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) 121 _DEFINE_SPEC(0, __is_integral_helper, long long, true) 122 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) 123 124 /// is_integral 125 template<typename _Tp> 126 struct is_integral 127 : public integral_constant<bool, (__is_integral_helper<typename 128 remove_cv<_Tp>::type>::value)> 129 { }; 130 131 template<typename> 132 struct __is_floating_point_helper 133 : public false_type { }; 134 _DEFINE_SPEC(0, __is_floating_point_helper, float, true) 135 _DEFINE_SPEC(0, __is_floating_point_helper, double, true) 136 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) 137 138 /// is_floating_point 139 template<typename _Tp> 140 struct is_floating_point 141 : public integral_constant<bool, (__is_floating_point_helper<typename 142 remove_cv<_Tp>::type>::value)> 143 { }; 144 145 /// is_array 146 template<typename> 147 struct is_array 148 : public false_type { }; 149 150 template<typename _Tp, std::size_t _Size> 151 struct is_array<_Tp[_Size]> 152 : public true_type { }; 153 154 template<typename _Tp> 155 struct is_array<_Tp[]> 156 : public true_type { }; 157 158 template<typename> 159 struct __is_pointer_helper 160 : public false_type { }; 161 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) 162 163 /// is_pointer 164 template<typename _Tp> 165 struct is_pointer 166 : public integral_constant<bool, (__is_pointer_helper<typename 167 remove_cv<_Tp>::type>::value)> 168 { }; 169 170 /// is_reference 171 template<typename _Tp> 172 struct is_reference; 173 174 /// is_function 175 template<typename _Tp> 176 struct is_function; 177 178 template<typename> 179 struct __is_member_object_pointer_helper 180 : public false_type { }; 181 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, 182 !is_function<_Tp>::value) 183 184 /// is_member_object_pointer 185 template<typename _Tp> 186 struct is_member_object_pointer 187 : public integral_constant<bool, (__is_member_object_pointer_helper< 188 typename remove_cv<_Tp>::type>::value)> 189 { }; 190 191 template<typename> 192 struct __is_member_function_pointer_helper 193 : public false_type { }; 194 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, 195 is_function<_Tp>::value) 196 197 /// is_member_function_pointer 198 template<typename _Tp> 199 struct is_member_function_pointer 200 : public integral_constant<bool, (__is_member_function_pointer_helper< 201 typename remove_cv<_Tp>::type>::value)> 202 { }; 203 204 /// is_enum 205 template<typename _Tp> 206 struct is_enum 207 : public integral_constant<bool, __is_enum(_Tp)> 208 { }; 209 210 /// is_union 211 template<typename _Tp> 212 struct is_union 213 : public integral_constant<bool, __is_union(_Tp)> 214 { }; 215 216 /// is_class 217 template<typename _Tp> 218 struct is_class 219 : public integral_constant<bool, __is_class(_Tp)> 220 { }; 221 222 /// is_function 223 template<typename> 224 struct is_function 225 : public false_type { }; 226 template<typename _Res, typename... _ArgTypes> 227 struct is_function<_Res(_ArgTypes...)> 228 : public true_type { }; 229 template<typename _Res, typename... _ArgTypes> 230 struct is_function<_Res(_ArgTypes......)> 231 : public true_type { }; 232 template<typename _Res, typename... _ArgTypes> 233 struct is_function<_Res(_ArgTypes...) const> 234 : public true_type { }; 235 template<typename _Res, typename... _ArgTypes> 236 struct is_function<_Res(_ArgTypes......) const> 237 : public true_type { }; 238 template<typename _Res, typename... _ArgTypes> 239 struct is_function<_Res(_ArgTypes...) volatile> 240 : public true_type { }; 241 template<typename _Res, typename... _ArgTypes> 242 struct is_function<_Res(_ArgTypes......) volatile> 243 : public true_type { }; 244 template<typename _Res, typename... _ArgTypes> 245 struct is_function<_Res(_ArgTypes...) const volatile> 246 : public true_type { }; 247 template<typename _Res, typename... _ArgTypes> 248 struct is_function<_Res(_ArgTypes......) const volatile> 249 : public true_type { }; 250 251 // composite type traits [4.5.2]. 252 253 /// is_arithmetic 254 template<typename _Tp> 255 struct is_arithmetic 256 : public integral_constant<bool, (is_integral<_Tp>::value 257 || is_floating_point<_Tp>::value)> 258 { }; 259 260 /// is_fundamental 261 template<typename _Tp> 262 struct is_fundamental 263 : public integral_constant<bool, (is_arithmetic<_Tp>::value 264 || is_void<_Tp>::value)> 265 { }; 266 267 /// is_object 268 template<typename _Tp> 269 struct is_object 270 : public integral_constant<bool, !(is_function<_Tp>::value 271 || is_reference<_Tp>::value 272 || is_void<_Tp>::value)> 273 { }; 274 275 /// is_member_pointer 276 template<typename _Tp> 277 struct is_member_pointer; 278 279 /// is_scalar 280 template<typename _Tp> 281 struct is_scalar 282 : public integral_constant<bool, (is_arithmetic<_Tp>::value 283 || is_enum<_Tp>::value 284 || is_pointer<_Tp>::value 285 || is_member_pointer<_Tp>::value)> 286 { }; 287 288 /// is_compound 289 template<typename _Tp> 290 struct is_compound 291 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 292 293 /// is_member_pointer 294 template<typename _Tp> 295 struct __is_member_pointer_helper 296 : public false_type { }; 297 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 298 299 template<typename _Tp> 300 struct is_member_pointer 301 : public integral_constant<bool, (__is_member_pointer_helper< 302 typename remove_cv<_Tp>::type>::value)> 303 { }; 304 305 // type properties [4.5.3]. 306 /// is_const 307 template<typename> 308 struct is_const 309 : public false_type { }; 310 311 template<typename _Tp> 312 struct is_const<_Tp const> 313 : public true_type { }; 314 315 /// is_volatile 316 template<typename> 317 struct is_volatile 318 : public false_type { }; 319 320 template<typename _Tp> 321 struct is_volatile<_Tp volatile> 322 : public true_type { }; 323 324 /// is_empty 325 template<typename _Tp> 326 struct is_empty 327 : public integral_constant<bool, __is_empty(_Tp)> 328 { }; 329 330 /// is_polymorphic 331 template<typename _Tp> 332 struct is_polymorphic 333 : public integral_constant<bool, __is_polymorphic(_Tp)> 334 { }; 335 336 /// is_abstract 337 template<typename _Tp> 338 struct is_abstract 339 : public integral_constant<bool, __is_abstract(_Tp)> 340 { }; 341 342 /// has_virtual_destructor 343 template<typename _Tp> 344 struct has_virtual_destructor 345 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 346 { }; 347 348 /// alignment_of 349 template<typename _Tp> 350 struct alignment_of 351 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 352 353 /// rank 354 template<typename> 355 struct rank 356 : public integral_constant<std::size_t, 0> { }; 357 358 template<typename _Tp, std::size_t _Size> 359 struct rank<_Tp[_Size]> 360 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 361 362 template<typename _Tp> 363 struct rank<_Tp[]> 364 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 365 366 /// extent 367 template<typename, unsigned _Uint = 0> 368 struct extent 369 : public integral_constant<std::size_t, 0> { }; 370 371 template<typename _Tp, unsigned _Uint, std::size_t _Size> 372 struct extent<_Tp[_Size], _Uint> 373 : public integral_constant<std::size_t, 374 _Uint == 0 ? _Size : extent<_Tp, 375 _Uint - 1>::value> 376 { }; 377 378 template<typename _Tp, unsigned _Uint> 379 struct extent<_Tp[], _Uint> 380 : public integral_constant<std::size_t, 381 _Uint == 0 ? 0 : extent<_Tp, 382 _Uint - 1>::value> 383 { }; 384 385 // relationships between types [4.6]. 386 387 /// is_same 388 template<typename, typename> 389 struct is_same 390 : public false_type { }; 391 392 template<typename _Tp> 393 struct is_same<_Tp, _Tp> 394 : public true_type { }; 395 396 // const-volatile modifications [4.7.1]. 397 398 /// remove_const 399 template<typename _Tp> 400 struct remove_const 401 { typedef _Tp type; }; 402 403 template<typename _Tp> 404 struct remove_const<_Tp const> 405 { typedef _Tp type; }; 406 407 /// remove_volatile 408 template<typename _Tp> 409 struct remove_volatile 410 { typedef _Tp type; }; 411 412 template<typename _Tp> 413 struct remove_volatile<_Tp volatile> 414 { typedef _Tp type; }; 415 416 /// remove_cv 417 template<typename _Tp> 418 struct remove_cv 419 { 420 typedef typename 421 remove_const<typename remove_volatile<_Tp>::type>::type type; 422 }; 423 424 /// add_const 425 template<typename _Tp> 426 struct add_const 427 { typedef _Tp const type; }; 428 429 /// add_volatile 430 template<typename _Tp> 431 struct add_volatile 432 { typedef _Tp volatile type; }; 433 434 /// add_cv 435 template<typename _Tp> 436 struct add_cv 437 { 438 typedef typename 439 add_const<typename add_volatile<_Tp>::type>::type type; 440 }; 441 442 // array modifications [4.7.3]. 443 444 /// remove_extent 445 template<typename _Tp> 446 struct remove_extent 447 { typedef _Tp type; }; 448 449 template<typename _Tp, std::size_t _Size> 450 struct remove_extent<_Tp[_Size]> 451 { typedef _Tp type; }; 452 453 template<typename _Tp> 454 struct remove_extent<_Tp[]> 455 { typedef _Tp type; }; 456 457 /// remove_all_extents 458 template<typename _Tp> 459 struct remove_all_extents 460 { typedef _Tp type; }; 461 462 template<typename _Tp, std::size_t _Size> 463 struct remove_all_extents<_Tp[_Size]> 464 { typedef typename remove_all_extents<_Tp>::type type; }; 465 466 template<typename _Tp> 467 struct remove_all_extents<_Tp[]> 468 { typedef typename remove_all_extents<_Tp>::type type; }; 469 470 // pointer modifications [4.7.4]. 471 472 template<typename _Tp, typename> 473 struct __remove_pointer_helper 474 { typedef _Tp type; }; 475 476 template<typename _Tp, typename _Up> 477 struct __remove_pointer_helper<_Tp, _Up*> 478 { typedef _Up type; }; 479 480 /// remove_pointer 481 template<typename _Tp> 482 struct remove_pointer 483 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 484 { }; 485 486 template<typename> 487 struct remove_reference; 488 489 /// add_pointer 490 template<typename _Tp> 491 struct add_pointer 492 { typedef typename remove_reference<_Tp>::type* type; }; 493 494 #undef _DEFINE_SPEC_0_HELPER 495 #undef _DEFINE_SPEC_1_HELPER 496 #undef _DEFINE_SPEC_2_HELPER 497 #undef _DEFINE_SPEC 498 499 // @} group metaprogramming 500 _GLIBCXX_END_NAMESPACE_TR1 501 } 502