1 // TR1 type_traits -*- C++ -*- 2 3 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 3, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // Under Section 7 of GPL version 3, you are granted additional 18 // permissions described in the GCC Runtime Library Exception, version 19 // 3.1, as published by the Free Software Foundation. 20 21 // You should have received a copy of the GNU General Public License and 22 // a copy of the GCC Runtime Library Exception along with this program; 23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 // <http://www.gnu.org/licenses/>. 25 26 /** @file tr1/type_traits 27 * This is a TR1 C++ Library header. 28 */ 29 30 #ifndef _GLIBCXX_TR1_TYPE_TRAITS 31 #define _GLIBCXX_TR1_TYPE_TRAITS 1 32 33 #pragma GCC system_header 34 35 #include <bits/c++config.h> 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 namespace tr1 40 { 41 _GLIBCXX_BEGIN_NAMESPACE_VERSION 42 43 /** 44 * @defgroup metaprogramming Type Traits 45 * @ingroup utilities 46 * 47 * Compile time type transformation and information. 48 * @{ 49 */ 50 51 struct __sfinae_types 52 { 53 typedef char __one; 54 typedef struct { char __arr[2]; } __two; 55 }; 56 57 #define _DEFINE_SPEC_0_HELPER \ 58 template<> 59 60 #define _DEFINE_SPEC_1_HELPER \ 61 template<typename _Tp> 62 63 #define _DEFINE_SPEC_2_HELPER \ 64 template<typename _Tp, typename _Cp> 65 66 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 67 _DEFINE_SPEC_##_Order##_HELPER \ 68 struct _Trait<_Type> \ 69 : public integral_constant<bool, _Value> { }; 70 71 // helper classes [4.3]. 72 73 /// integral_constant 74 template<typename _Tp, _Tp __v> 75 struct integral_constant 76 { 77 static const _Tp value = __v; 78 typedef _Tp value_type; 79 typedef integral_constant<_Tp, __v> type; 80 }; 81 82 /// typedef for true_type 83 typedef integral_constant<bool, true> true_type; 84 85 /// typedef for false_type 86 typedef integral_constant<bool, false> false_type; 87 88 template<typename _Tp, _Tp __v> 89 const _Tp integral_constant<_Tp, __v>::value; 90 91 /// remove_cv 92 template<typename> 93 struct remove_cv; 94 95 template<typename> 96 struct __is_void_helper 97 : public false_type { }; 98 _DEFINE_SPEC(0, __is_void_helper, void, true) 99 100 // primary type categories [4.5.1]. 101 102 /// is_void 103 template<typename _Tp> 104 struct is_void 105 : public integral_constant<bool, (__is_void_helper<typename 106 remove_cv<_Tp>::type>::value)> 107 { }; 108 109 template<typename> 110 struct __is_integral_helper 111 : public false_type { }; 112 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 113 _DEFINE_SPEC(0, __is_integral_helper, char, true) 114 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 115 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 116 #ifdef _GLIBCXX_USE_WCHAR_T 117 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 118 #endif 119 _DEFINE_SPEC(0, __is_integral_helper, short, true) 120 _DEFINE_SPEC(0, __is_integral_helper, unsigned short, true) 121 _DEFINE_SPEC(0, __is_integral_helper, int, true) 122 _DEFINE_SPEC(0, __is_integral_helper, unsigned int, true) 123 _DEFINE_SPEC(0, __is_integral_helper, long, true) 124 _DEFINE_SPEC(0, __is_integral_helper, unsigned long, true) 125 _DEFINE_SPEC(0, __is_integral_helper, long long, true) 126 _DEFINE_SPEC(0, __is_integral_helper, unsigned long long, true) 127 128 /// is_integral 129 template<typename _Tp> 130 struct is_integral 131 : public integral_constant<bool, (__is_integral_helper<typename 132 remove_cv<_Tp>::type>::value)> 133 { }; 134 135 template<typename> 136 struct __is_floating_point_helper 137 : public false_type { }; 138 _DEFINE_SPEC(0, __is_floating_point_helper, float, true) 139 _DEFINE_SPEC(0, __is_floating_point_helper, double, true) 140 _DEFINE_SPEC(0, __is_floating_point_helper, long double, true) 141 142 /// is_floating_point 143 template<typename _Tp> 144 struct is_floating_point 145 : public integral_constant<bool, (__is_floating_point_helper<typename 146 remove_cv<_Tp>::type>::value)> 147 { }; 148 149 /// is_array 150 template<typename> 151 struct is_array 152 : public false_type { }; 153 154 template<typename _Tp, std::size_t _Size> 155 struct is_array<_Tp[_Size]> 156 : public true_type { }; 157 158 template<typename _Tp> 159 struct is_array<_Tp[]> 160 : public true_type { }; 161 162 template<typename> 163 struct __is_pointer_helper 164 : public false_type { }; 165 _DEFINE_SPEC(1, __is_pointer_helper, _Tp*, true) 166 167 /// is_pointer 168 template<typename _Tp> 169 struct is_pointer 170 : public integral_constant<bool, (__is_pointer_helper<typename 171 remove_cv<_Tp>::type>::value)> 172 { }; 173 174 /// is_reference 175 template<typename _Tp> 176 struct is_reference; 177 178 /// is_function 179 template<typename _Tp> 180 struct is_function; 181 182 template<typename> 183 struct __is_member_object_pointer_helper 184 : public false_type { }; 185 _DEFINE_SPEC(2, __is_member_object_pointer_helper, _Tp _Cp::*, 186 !is_function<_Tp>::value) 187 188 /// is_member_object_pointer 189 template<typename _Tp> 190 struct is_member_object_pointer 191 : public integral_constant<bool, (__is_member_object_pointer_helper< 192 typename remove_cv<_Tp>::type>::value)> 193 { }; 194 195 template<typename> 196 struct __is_member_function_pointer_helper 197 : public false_type { }; 198 _DEFINE_SPEC(2, __is_member_function_pointer_helper, _Tp _Cp::*, 199 is_function<_Tp>::value) 200 201 /// is_member_function_pointer 202 template<typename _Tp> 203 struct is_member_function_pointer 204 : public integral_constant<bool, (__is_member_function_pointer_helper< 205 typename remove_cv<_Tp>::type>::value)> 206 { }; 207 208 /// is_enum 209 template<typename _Tp> 210 struct is_enum 211 : public integral_constant<bool, __is_enum(_Tp)> 212 { }; 213 214 /// is_union 215 template<typename _Tp> 216 struct is_union 217 : public integral_constant<bool, __is_union(_Tp)> 218 { }; 219 220 /// is_class 221 template<typename _Tp> 222 struct is_class 223 : public integral_constant<bool, __is_class(_Tp)> 224 { }; 225 226 /// is_function 227 template<typename> 228 struct is_function 229 : public false_type { }; 230 template<typename _Res, typename... _ArgTypes> 231 struct is_function<_Res(_ArgTypes...)> 232 : public true_type { }; 233 template<typename _Res, typename... _ArgTypes> 234 struct is_function<_Res(_ArgTypes......)> 235 : public true_type { }; 236 template<typename _Res, typename... _ArgTypes> 237 struct is_function<_Res(_ArgTypes...) const> 238 : public true_type { }; 239 template<typename _Res, typename... _ArgTypes> 240 struct is_function<_Res(_ArgTypes......) const> 241 : public true_type { }; 242 template<typename _Res, typename... _ArgTypes> 243 struct is_function<_Res(_ArgTypes...) volatile> 244 : public true_type { }; 245 template<typename _Res, typename... _ArgTypes> 246 struct is_function<_Res(_ArgTypes......) volatile> 247 : public true_type { }; 248 template<typename _Res, typename... _ArgTypes> 249 struct is_function<_Res(_ArgTypes...) const volatile> 250 : public true_type { }; 251 template<typename _Res, typename... _ArgTypes> 252 struct is_function<_Res(_ArgTypes......) const volatile> 253 : public true_type { }; 254 255 // composite type traits [4.5.2]. 256 257 /// is_arithmetic 258 template<typename _Tp> 259 struct is_arithmetic 260 : public integral_constant<bool, (is_integral<_Tp>::value 261 || is_floating_point<_Tp>::value)> 262 { }; 263 264 /// is_fundamental 265 template<typename _Tp> 266 struct is_fundamental 267 : public integral_constant<bool, (is_arithmetic<_Tp>::value 268 || is_void<_Tp>::value)> 269 { }; 270 271 /// is_object 272 template<typename _Tp> 273 struct is_object 274 : public integral_constant<bool, !(is_function<_Tp>::value 275 || is_reference<_Tp>::value 276 || is_void<_Tp>::value)> 277 { }; 278 279 /// is_member_pointer 280 template<typename _Tp> 281 struct is_member_pointer; 282 283 /// is_scalar 284 template<typename _Tp> 285 struct is_scalar 286 : public integral_constant<bool, (is_arithmetic<_Tp>::value 287 || is_enum<_Tp>::value 288 || is_pointer<_Tp>::value 289 || is_member_pointer<_Tp>::value)> 290 { }; 291 292 /// is_compound 293 template<typename _Tp> 294 struct is_compound 295 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 296 297 /// is_member_pointer 298 template<typename _Tp> 299 struct __is_member_pointer_helper 300 : public false_type { }; 301 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 302 303 template<typename _Tp> 304 struct is_member_pointer 305 : public integral_constant<bool, (__is_member_pointer_helper< 306 typename remove_cv<_Tp>::type>::value)> 307 { }; 308 309 // type properties [4.5.3]. 310 /// is_const 311 template<typename> 312 struct is_const 313 : public false_type { }; 314 315 template<typename _Tp> 316 struct is_const<_Tp const> 317 : public true_type { }; 318 319 /// is_volatile 320 template<typename> 321 struct is_volatile 322 : public false_type { }; 323 324 template<typename _Tp> 325 struct is_volatile<_Tp volatile> 326 : public true_type { }; 327 328 /// is_empty 329 template<typename _Tp> 330 struct is_empty 331 : public integral_constant<bool, __is_empty(_Tp)> 332 { }; 333 334 /// is_polymorphic 335 template<typename _Tp> 336 struct is_polymorphic 337 : public integral_constant<bool, __is_polymorphic(_Tp)> 338 { }; 339 340 /// is_abstract 341 template<typename _Tp> 342 struct is_abstract 343 : public integral_constant<bool, __is_abstract(_Tp)> 344 { }; 345 346 /// has_virtual_destructor 347 template<typename _Tp> 348 struct has_virtual_destructor 349 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 350 { }; 351 352 /// alignment_of 353 template<typename _Tp> 354 struct alignment_of 355 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 356 357 /// rank 358 template<typename> 359 struct rank 360 : public integral_constant<std::size_t, 0> { }; 361 362 template<typename _Tp, std::size_t _Size> 363 struct rank<_Tp[_Size]> 364 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 365 366 template<typename _Tp> 367 struct rank<_Tp[]> 368 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 369 370 /// extent 371 template<typename, unsigned _Uint = 0> 372 struct extent 373 : public integral_constant<std::size_t, 0> { }; 374 375 template<typename _Tp, unsigned _Uint, std::size_t _Size> 376 struct extent<_Tp[_Size], _Uint> 377 : public integral_constant<std::size_t, 378 _Uint == 0 ? _Size : extent<_Tp, 379 _Uint - 1>::value> 380 { }; 381 382 template<typename _Tp, unsigned _Uint> 383 struct extent<_Tp[], _Uint> 384 : public integral_constant<std::size_t, 385 _Uint == 0 ? 0 : extent<_Tp, 386 _Uint - 1>::value> 387 { }; 388 389 // relationships between types [4.6]. 390 391 /// is_same 392 template<typename, typename> 393 struct is_same 394 : public false_type { }; 395 396 template<typename _Tp> 397 struct is_same<_Tp, _Tp> 398 : public true_type { }; 399 400 // const-volatile modifications [4.7.1]. 401 402 /// remove_const 403 template<typename _Tp> 404 struct remove_const 405 { typedef _Tp type; }; 406 407 template<typename _Tp> 408 struct remove_const<_Tp const> 409 { typedef _Tp type; }; 410 411 /// remove_volatile 412 template<typename _Tp> 413 struct remove_volatile 414 { typedef _Tp type; }; 415 416 template<typename _Tp> 417 struct remove_volatile<_Tp volatile> 418 { typedef _Tp type; }; 419 420 /// remove_cv 421 template<typename _Tp> 422 struct remove_cv 423 { 424 typedef typename 425 remove_const<typename remove_volatile<_Tp>::type>::type type; 426 }; 427 428 /// add_const 429 template<typename _Tp> 430 struct add_const 431 { typedef _Tp const type; }; 432 433 /// add_volatile 434 template<typename _Tp> 435 struct add_volatile 436 { typedef _Tp volatile type; }; 437 438 /// add_cv 439 template<typename _Tp> 440 struct add_cv 441 { 442 typedef typename 443 add_const<typename add_volatile<_Tp>::type>::type type; 444 }; 445 446 // array modifications [4.7.3]. 447 448 /// remove_extent 449 template<typename _Tp> 450 struct remove_extent 451 { typedef _Tp type; }; 452 453 template<typename _Tp, std::size_t _Size> 454 struct remove_extent<_Tp[_Size]> 455 { typedef _Tp type; }; 456 457 template<typename _Tp> 458 struct remove_extent<_Tp[]> 459 { typedef _Tp type; }; 460 461 /// remove_all_extents 462 template<typename _Tp> 463 struct remove_all_extents 464 { typedef _Tp type; }; 465 466 template<typename _Tp, std::size_t _Size> 467 struct remove_all_extents<_Tp[_Size]> 468 { typedef typename remove_all_extents<_Tp>::type type; }; 469 470 template<typename _Tp> 471 struct remove_all_extents<_Tp[]> 472 { typedef typename remove_all_extents<_Tp>::type type; }; 473 474 // pointer modifications [4.7.4]. 475 476 template<typename _Tp, typename> 477 struct __remove_pointer_helper 478 { typedef _Tp type; }; 479 480 template<typename _Tp, typename _Up> 481 struct __remove_pointer_helper<_Tp, _Up*> 482 { typedef _Up type; }; 483 484 /// remove_pointer 485 template<typename _Tp> 486 struct remove_pointer 487 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 488 { }; 489 490 template<typename> 491 struct remove_reference; 492 493 /// add_pointer 494 template<typename _Tp> 495 struct add_pointer 496 { typedef typename remove_reference<_Tp>::type* type; }; 497 498 template<typename> 499 struct is_reference 500 : public false_type { }; 501 502 template<typename _Tp> 503 struct is_reference<_Tp&> 504 : public true_type { }; 505 506 template<typename _Tp> 507 struct is_pod 508 : public integral_constant<bool, __is_pod(_Tp) || is_void<_Tp>::value> 509 { }; 510 511 template<typename _Tp> 512 struct has_trivial_constructor 513 : public integral_constant<bool, is_pod<_Tp>::value> 514 { }; 515 516 template<typename _Tp> 517 struct has_trivial_copy 518 : public integral_constant<bool, is_pod<_Tp>::value> 519 { }; 520 521 template<typename _Tp> 522 struct has_trivial_assign 523 : public integral_constant<bool, is_pod<_Tp>::value> 524 { }; 525 526 template<typename _Tp> 527 struct has_trivial_destructor 528 : public integral_constant<bool, is_pod<_Tp>::value> 529 { }; 530 531 template<typename _Tp> 532 struct has_nothrow_constructor 533 : public integral_constant<bool, is_pod<_Tp>::value> 534 { }; 535 536 template<typename _Tp> 537 struct has_nothrow_copy 538 : public integral_constant<bool, is_pod<_Tp>::value> 539 { }; 540 541 template<typename _Tp> 542 struct has_nothrow_assign 543 : public integral_constant<bool, is_pod<_Tp>::value> 544 { }; 545 546 template<typename> 547 struct __is_signed_helper 548 : public false_type { }; 549 _DEFINE_SPEC(0, __is_signed_helper, signed char, true) 550 _DEFINE_SPEC(0, __is_signed_helper, short, true) 551 _DEFINE_SPEC(0, __is_signed_helper, int, true) 552 _DEFINE_SPEC(0, __is_signed_helper, long, true) 553 _DEFINE_SPEC(0, __is_signed_helper, long long, true) 554 555 template<typename _Tp> 556 struct is_signed 557 : public integral_constant<bool, (__is_signed_helper<typename 558 remove_cv<_Tp>::type>::value)> 559 { }; 560 561 template<typename> 562 struct __is_unsigned_helper 563 : public false_type { }; 564 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned char, true) 565 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned short, true) 566 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned int, true) 567 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long, true) 568 _DEFINE_SPEC(0, __is_unsigned_helper, unsigned long long, true) 569 570 template<typename _Tp> 571 struct is_unsigned 572 : public integral_constant<bool, (__is_unsigned_helper<typename 573 remove_cv<_Tp>::type>::value)> 574 { }; 575 576 template<typename _Base, typename _Derived> 577 struct __is_base_of_helper 578 { 579 typedef typename remove_cv<_Base>::type _NoCv_Base; 580 typedef typename remove_cv<_Derived>::type _NoCv_Derived; 581 static const bool __value = (is_same<_Base, _Derived>::value 582 || (__is_base_of(_Base, _Derived) 583 && !is_same<_NoCv_Base, 584 _NoCv_Derived>::value)); 585 }; 586 587 template<typename _Base, typename _Derived> 588 struct is_base_of 589 : public integral_constant<bool, 590 __is_base_of_helper<_Base, _Derived>::__value> 591 { }; 592 593 template<typename _From, typename _To> 594 struct __is_convertible_simple 595 : public __sfinae_types 596 { 597 private: 598 static __one __test(_To); 599 static __two __test(...); 600 static _From __makeFrom(); 601 602 public: 603 static const bool __value = sizeof(__test(__makeFrom())) == 1; 604 }; 605 606 template<typename _Tp> 607 struct add_reference; 608 609 template<typename _Tp> 610 struct __is_int_or_cref 611 { 612 typedef typename remove_reference<_Tp>::type __rr_Tp; 613 static const bool __value = (is_integral<_Tp>::value 614 || (is_integral<__rr_Tp>::value 615 && is_const<__rr_Tp>::value 616 && !is_volatile<__rr_Tp>::value)); 617 }; 618 619 template<typename _From, typename _To, 620 bool = (is_void<_From>::value || is_void<_To>::value 621 || is_function<_To>::value || is_array<_To>::value 622 // This special case is here only to avoid warnings. 623 || (is_floating_point<typename 624 remove_reference<_From>::type>::value 625 && __is_int_or_cref<_To>::__value))> 626 struct __is_convertible_helper 627 { 628 // "An imaginary lvalue of type From...". 629 static const bool __value = (__is_convertible_simple<typename 630 add_reference<_From>::type, _To>::__value); 631 }; 632 633 template<typename _From, typename _To> 634 struct __is_convertible_helper<_From, _To, true> 635 { static const bool __value = (is_void<_To>::value 636 || (__is_int_or_cref<_To>::__value 637 && !is_void<_From>::value)); }; 638 639 template<typename _From, typename _To> 640 struct is_convertible 641 : public integral_constant<bool, 642 __is_convertible_helper<_From, _To>::__value> 643 { }; 644 645 // reference modifications [4.7.2]. 646 template<typename _Tp> 647 struct remove_reference 648 { typedef _Tp type; }; 649 650 template<typename _Tp> 651 struct remove_reference<_Tp&> 652 { typedef _Tp type; }; 653 654 // NB: Careful with reference to void. 655 template<typename _Tp, bool = (is_void<_Tp>::value 656 || is_reference<_Tp>::value)> 657 struct __add_reference_helper 658 { typedef _Tp& type; }; 659 660 template<typename _Tp> 661 struct __add_reference_helper<_Tp, true> 662 { typedef _Tp type; }; 663 664 template<typename _Tp> 665 struct add_reference 666 : public __add_reference_helper<_Tp> 667 { }; 668 669 // other transformations [4.8]. 670 template<std::size_t _Len, std::size_t _Align> 671 struct aligned_storage 672 { 673 union type 674 { 675 unsigned char __data[_Len]; 676 struct __attribute__((__aligned__((_Align)))) { } __align; 677 }; 678 }; 679 680 #undef _DEFINE_SPEC_0_HELPER 681 #undef _DEFINE_SPEC_1_HELPER 682 #undef _DEFINE_SPEC_2_HELPER 683 #undef _DEFINE_SPEC 684 685 _GLIBCXX_END_NAMESPACE_VERSION 686 } 687 } 688 689 #endif // _GLIBCXX_TR1_TYPE_TRAITS 690