1 // C++0x type_traits -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009, 2010 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 include/type_traits 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_TYPE_TRAITS 30 #define _GLIBCXX_TYPE_TRAITS 1 31 32 #pragma GCC system_header 33 34 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 35 # include <bits/c++0x_warning.h> 36 #else 37 38 #include <bits/c++config.h> 39 40 namespace std _GLIBCXX_VISIBILITY(default) 41 { 42 _GLIBCXX_BEGIN_NAMESPACE_VERSION 43 44 /** 45 * @addtogroup metaprogramming 46 * @{ 47 */ 48 struct __sfinae_types 49 { 50 typedef char __one; 51 typedef struct { char __arr[2]; } __two; 52 }; 53 54 #define _DEFINE_SPEC_0_HELPER \ 55 template<> 56 57 #define _DEFINE_SPEC_1_HELPER \ 58 template<typename _Tp> 59 60 #define _DEFINE_SPEC_2_HELPER \ 61 template<typename _Tp, typename _Cp> 62 63 #define _DEFINE_SPEC(_Order, _Trait, _Type, _Value) \ 64 _DEFINE_SPEC_##_Order##_HELPER \ 65 struct _Trait<_Type> \ 66 : public integral_constant<bool, _Value> { }; 67 68 // helper classes. 69 70 /// integral_constant 71 template<typename _Tp, _Tp __v> 72 struct integral_constant 73 { 74 static constexpr _Tp value = __v; 75 typedef _Tp value_type; 76 typedef integral_constant<_Tp, __v> type; 77 constexpr operator value_type() { return value; } 78 }; 79 80 /// typedef for true_type 81 typedef integral_constant<bool, true> true_type; 82 83 /// typedef for false_type 84 typedef integral_constant<bool, false> false_type; 85 86 template<typename _Tp, _Tp __v> 87 constexpr _Tp integral_constant<_Tp, __v>::value; 88 89 /// remove_cv 90 template<typename> 91 struct remove_cv; 92 93 template<typename> 94 struct __is_void_helper 95 : public false_type { }; 96 _DEFINE_SPEC(0, __is_void_helper, void, true) 97 98 // primary type categories. 99 100 /// is_void 101 template<typename _Tp> 102 struct is_void 103 : public integral_constant<bool, (__is_void_helper<typename 104 remove_cv<_Tp>::type>::value)> 105 { }; 106 107 template<typename> 108 struct __is_integral_helper 109 : public false_type { }; 110 _DEFINE_SPEC(0, __is_integral_helper, bool, true) 111 _DEFINE_SPEC(0, __is_integral_helper, char, true) 112 _DEFINE_SPEC(0, __is_integral_helper, signed char, true) 113 _DEFINE_SPEC(0, __is_integral_helper, unsigned char, true) 114 #ifdef _GLIBCXX_USE_WCHAR_T 115 _DEFINE_SPEC(0, __is_integral_helper, wchar_t, true) 116 #endif 117 _DEFINE_SPEC(0, __is_integral_helper, char16_t, true) 118 _DEFINE_SPEC(0, __is_integral_helper, char32_t, true) 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 template<typename> 256 struct __is_nullptr_t_helper 257 : public false_type { }; 258 _DEFINE_SPEC(0, __is_nullptr_t_helper, std::nullptr_t, true) 259 260 // __is_nullptr_t (extension). 261 template<typename _Tp> 262 struct __is_nullptr_t 263 : public integral_constant<bool, (__is_nullptr_t_helper<typename 264 remove_cv<_Tp>::type>::value)> 265 { }; 266 267 // composite type traits. 268 269 /// is_arithmetic 270 template<typename _Tp> 271 struct is_arithmetic 272 : public integral_constant<bool, (is_integral<_Tp>::value 273 || is_floating_point<_Tp>::value)> 274 { }; 275 276 /// is_fundamental 277 template<typename _Tp> 278 struct is_fundamental 279 : public integral_constant<bool, (is_arithmetic<_Tp>::value 280 || is_void<_Tp>::value)> 281 { }; 282 283 /// is_object 284 template<typename _Tp> 285 struct is_object 286 : public integral_constant<bool, !(is_function<_Tp>::value 287 || is_reference<_Tp>::value 288 || is_void<_Tp>::value)> 289 { }; 290 291 /// is_member_pointer 292 template<typename _Tp> 293 struct is_member_pointer; 294 295 /// is_scalar 296 template<typename _Tp> 297 struct is_scalar 298 : public integral_constant<bool, (is_arithmetic<_Tp>::value 299 || is_enum<_Tp>::value 300 || is_pointer<_Tp>::value 301 || is_member_pointer<_Tp>::value 302 || __is_nullptr_t<_Tp>::value)> 303 { }; 304 305 /// is_compound 306 template<typename _Tp> 307 struct is_compound 308 : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; 309 310 /// is_member_pointer 311 template<typename _Tp> 312 struct __is_member_pointer_helper 313 : public false_type { }; 314 _DEFINE_SPEC(2, __is_member_pointer_helper, _Tp _Cp::*, true) 315 316 template<typename _Tp> 317 struct is_member_pointer 318 : public integral_constant<bool, (__is_member_pointer_helper< 319 typename remove_cv<_Tp>::type>::value)> 320 { }; 321 322 // type properties. 323 /// is_const 324 template<typename> 325 struct is_const 326 : public false_type { }; 327 328 template<typename _Tp> 329 struct is_const<_Tp const> 330 : public true_type { }; 331 332 /// is_volatile 333 template<typename> 334 struct is_volatile 335 : public false_type { }; 336 337 template<typename _Tp> 338 struct is_volatile<_Tp volatile> 339 : public true_type { }; 340 341 /// is_empty 342 template<typename _Tp> 343 struct is_empty 344 : public integral_constant<bool, __is_empty(_Tp)> 345 { }; 346 347 /// is_polymorphic 348 template<typename _Tp> 349 struct is_polymorphic 350 : public integral_constant<bool, __is_polymorphic(_Tp)> 351 { }; 352 353 /// is_abstract 354 template<typename _Tp> 355 struct is_abstract 356 : public integral_constant<bool, __is_abstract(_Tp)> 357 { }; 358 359 /// has_virtual_destructor 360 template<typename _Tp> 361 struct has_virtual_destructor 362 : public integral_constant<bool, __has_virtual_destructor(_Tp)> 363 { }; 364 365 /// alignment_of 366 template<typename _Tp> 367 struct alignment_of 368 : public integral_constant<std::size_t, __alignof__(_Tp)> { }; 369 370 /// rank 371 template<typename> 372 struct rank 373 : public integral_constant<std::size_t, 0> { }; 374 375 template<typename _Tp, std::size_t _Size> 376 struct rank<_Tp[_Size]> 377 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 378 379 template<typename _Tp> 380 struct rank<_Tp[]> 381 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 382 383 /// extent 384 template<typename, unsigned _Uint = 0> 385 struct extent 386 : public integral_constant<std::size_t, 0> { }; 387 388 template<typename _Tp, unsigned _Uint, std::size_t _Size> 389 struct extent<_Tp[_Size], _Uint> 390 : public integral_constant<std::size_t, 391 _Uint == 0 ? _Size : extent<_Tp, 392 _Uint - 1>::value> 393 { }; 394 395 template<typename _Tp, unsigned _Uint> 396 struct extent<_Tp[], _Uint> 397 : public integral_constant<std::size_t, 398 _Uint == 0 ? 0 : extent<_Tp, 399 _Uint - 1>::value> 400 { }; 401 402 // relationships between types [4.6]. 403 404 /// is_same 405 template<typename, typename> 406 struct is_same 407 : public false_type { }; 408 409 template<typename _Tp> 410 struct is_same<_Tp, _Tp> 411 : public true_type { }; 412 413 // const-volatile modifications [4.7.1]. 414 415 /// remove_const 416 template<typename _Tp> 417 struct remove_const 418 { typedef _Tp type; }; 419 420 template<typename _Tp> 421 struct remove_const<_Tp const> 422 { typedef _Tp type; }; 423 424 /// remove_volatile 425 template<typename _Tp> 426 struct remove_volatile 427 { typedef _Tp type; }; 428 429 template<typename _Tp> 430 struct remove_volatile<_Tp volatile> 431 { typedef _Tp type; }; 432 433 /// remove_cv 434 template<typename _Tp> 435 struct remove_cv 436 { 437 typedef typename 438 remove_const<typename remove_volatile<_Tp>::type>::type type; 439 }; 440 441 /// add_const 442 template<typename _Tp> 443 struct add_const 444 { typedef _Tp const type; }; 445 446 /// add_volatile 447 template<typename _Tp> 448 struct add_volatile 449 { typedef _Tp volatile type; }; 450 451 /// add_cv 452 template<typename _Tp> 453 struct add_cv 454 { 455 typedef typename 456 add_const<typename add_volatile<_Tp>::type>::type type; 457 }; 458 459 // array modifications. 460 461 /// remove_extent 462 template<typename _Tp> 463 struct remove_extent 464 { typedef _Tp type; }; 465 466 template<typename _Tp, std::size_t _Size> 467 struct remove_extent<_Tp[_Size]> 468 { typedef _Tp type; }; 469 470 template<typename _Tp> 471 struct remove_extent<_Tp[]> 472 { typedef _Tp type; }; 473 474 /// remove_all_extents 475 template<typename _Tp> 476 struct remove_all_extents 477 { typedef _Tp type; }; 478 479 template<typename _Tp, std::size_t _Size> 480 struct remove_all_extents<_Tp[_Size]> 481 { typedef typename remove_all_extents<_Tp>::type type; }; 482 483 template<typename _Tp> 484 struct remove_all_extents<_Tp[]> 485 { typedef typename remove_all_extents<_Tp>::type type; }; 486 487 // pointer modifications. 488 489 template<typename _Tp, typename> 490 struct __remove_pointer_helper 491 { typedef _Tp type; }; 492 493 template<typename _Tp, typename _Up> 494 struct __remove_pointer_helper<_Tp, _Up*> 495 { typedef _Up type; }; 496 497 /// remove_pointer 498 template<typename _Tp> 499 struct remove_pointer 500 : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> 501 { }; 502 503 template<typename> 504 struct remove_reference; 505 506 /// add_pointer 507 template<typename _Tp> 508 struct add_pointer 509 { typedef typename remove_reference<_Tp>::type* type; }; 510 511 // Primary classification traits. 512 513 /// is_lvalue_reference 514 template<typename> 515 struct is_lvalue_reference 516 : public false_type { }; 517 518 template<typename _Tp> 519 struct is_lvalue_reference<_Tp&> 520 : public true_type { }; 521 522 /// is_rvalue_reference 523 template<typename> 524 struct is_rvalue_reference 525 : public false_type { }; 526 527 template<typename _Tp> 528 struct is_rvalue_reference<_Tp&&> 529 : public true_type { }; 530 531 // Secondary classification traits. 532 533 /// is_reference 534 template<typename _Tp> 535 struct is_reference 536 : public integral_constant<bool, (is_lvalue_reference<_Tp>::value 537 || is_rvalue_reference<_Tp>::value)> 538 { }; 539 540 // Reference transformations. 541 542 /// remove_reference 543 template<typename _Tp> 544 struct remove_reference 545 { typedef _Tp type; }; 546 547 template<typename _Tp> 548 struct remove_reference<_Tp&> 549 { typedef _Tp type; }; 550 551 template<typename _Tp> 552 struct remove_reference<_Tp&&> 553 { typedef _Tp type; }; 554 555 template<typename _Tp, 556 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value, 557 bool = is_rvalue_reference<_Tp>::value> 558 struct __add_lvalue_reference_helper 559 { typedef _Tp type; }; 560 561 template<typename _Tp> 562 struct __add_lvalue_reference_helper<_Tp, true, false> 563 { typedef _Tp& type; }; 564 565 template<typename _Tp> 566 struct __add_lvalue_reference_helper<_Tp, false, true> 567 { typedef typename remove_reference<_Tp>::type& type; }; 568 569 /// add_lvalue_reference 570 template<typename _Tp> 571 struct add_lvalue_reference 572 : public __add_lvalue_reference_helper<_Tp> 573 { }; 574 575 template<typename _Tp, 576 bool = !is_reference<_Tp>::value && !is_void<_Tp>::value> 577 struct __add_rvalue_reference_helper 578 { typedef _Tp type; }; 579 580 template<typename _Tp> 581 struct __add_rvalue_reference_helper<_Tp, true> 582 { typedef _Tp&& type; }; 583 584 /// add_rvalue_reference 585 template<typename _Tp> 586 struct add_rvalue_reference 587 : public __add_rvalue_reference_helper<_Tp> 588 { }; 589 590 // Scalar properties and transformations. 591 592 template<typename _Tp, 593 bool = is_integral<_Tp>::value, 594 bool = is_floating_point<_Tp>::value> 595 struct __is_signed_helper 596 : public false_type { }; 597 598 template<typename _Tp> 599 struct __is_signed_helper<_Tp, false, true> 600 : public true_type { }; 601 602 template<typename _Tp> 603 struct __is_signed_helper<_Tp, true, false> 604 : public integral_constant<bool, static_cast<bool>(_Tp(-1) < _Tp(0))> 605 { }; 606 607 /// is_signed 608 template<typename _Tp> 609 struct is_signed 610 : public integral_constant<bool, __is_signed_helper<_Tp>::value> 611 { }; 612 613 /// is_unsigned 614 template<typename _Tp> 615 struct is_unsigned 616 : public integral_constant<bool, (is_arithmetic<_Tp>::value 617 && !is_signed<_Tp>::value)> 618 { }; 619 620 // Member introspection. 621 622 /// is_trivial 623 template<typename _Tp> 624 struct is_trivial 625 : public integral_constant<bool, __is_trivial(_Tp)> 626 { }; 627 628 /// is_standard_layout 629 template<typename _Tp> 630 struct is_standard_layout 631 : public integral_constant<bool, __is_standard_layout(_Tp)> 632 { }; 633 634 /// is_pod 635 // Could use is_standard_layout && is_trivial instead of the builtin. 636 template<typename _Tp> 637 struct is_pod 638 : public integral_constant<bool, __is_pod(_Tp)> 639 { }; 640 641 /// is_literal_type 642 template<typename _Tp> 643 struct is_literal_type 644 : public integral_constant<bool, __is_literal_type(_Tp)> 645 { }; 646 647 template<typename _Tp> 648 typename add_rvalue_reference<_Tp>::type declval() noexcept; 649 650 template<typename _Tp, typename... _Args> 651 class __is_constructible_helper 652 : public __sfinae_types 653 { 654 template<typename _Tp1, typename... _Args1> 655 static decltype(_Tp1(declval<_Args1>()...), __one()) __test(int); 656 657 template<typename, typename...> 658 static __two __test(...); 659 660 public: 661 static const bool __value = sizeof(__test<_Tp, _Args...>(0)) == 1; 662 }; 663 664 template<typename _Tp, typename _Arg> 665 class __is_constructible_helper<_Tp, _Arg> 666 : public __sfinae_types 667 { 668 template<typename _Tp1, typename _Arg1> 669 static decltype(static_cast<_Tp1>(declval<_Arg1>()), __one()) 670 __test(int); 671 672 template<typename, typename> 673 static __two __test(...); 674 675 public: 676 static const bool __value = sizeof(__test<_Tp, _Arg>(0)) == 1; 677 }; 678 679 /// is_constructible 680 // XXX FIXME 681 // The C++0x specifications require front-end support, see N2255. 682 template<typename _Tp, typename... _Args> 683 struct is_constructible 684 : public integral_constant<bool, 685 __is_constructible_helper<_Tp, 686 _Args...>::__value> 687 { }; 688 689 template<bool, typename _Tp, typename... _Args> 690 struct __is_nt_constructible_helper 691 { static const bool __value = false; }; 692 693 template<typename _Tp, typename... _Args> 694 struct __is_nt_constructible_helper<true, _Tp, _Args...> 695 { static const bool __value = noexcept(_Tp(declval<_Args>()...)); }; 696 697 template<typename _Tp, typename _Arg> 698 struct __is_nt_constructible_helper<true, _Tp, _Arg> 699 { 700 static const bool __value = noexcept(static_cast<_Tp>(declval<_Arg>())); 701 }; 702 703 /// is_nothrow_constructible 704 template<typename _Tp, typename... _Args> 705 struct is_nothrow_constructible 706 : public integral_constant<bool, 707 __is_nt_constructible_helper<is_constructible<_Tp, _Args...>::value, 708 _Tp, _Args...>::__value> 709 { }; 710 711 /// has_trivial_default_constructor 712 template<typename _Tp> 713 struct has_trivial_default_constructor 714 : public integral_constant<bool, __has_trivial_constructor(_Tp)> 715 { }; 716 717 /// has_trivial_copy_constructor 718 template<typename _Tp> 719 struct has_trivial_copy_constructor 720 : public integral_constant<bool, __has_trivial_copy(_Tp)> 721 { }; 722 723 /// has_trivial_copy_assign 724 template<typename _Tp> 725 struct has_trivial_copy_assign 726 : public integral_constant<bool, __has_trivial_assign(_Tp)> 727 { }; 728 729 /// has_trivial_destructor 730 template<typename _Tp> 731 struct has_trivial_destructor 732 : public integral_constant<bool, __has_trivial_destructor(_Tp)> 733 { }; 734 735 /// has_nothrow_default_constructor 736 template<typename _Tp> 737 struct has_nothrow_default_constructor 738 : public integral_constant<bool, __has_nothrow_constructor(_Tp)> 739 { }; 740 741 /// has_nothrow_copy_constructor 742 template<typename _Tp> 743 struct has_nothrow_copy_constructor 744 : public integral_constant<bool, __has_nothrow_copy(_Tp)> 745 { }; 746 747 /// has_nothrow_copy_assign 748 template<typename _Tp> 749 struct has_nothrow_copy_assign 750 : public integral_constant<bool, __has_nothrow_assign(_Tp)> 751 { }; 752 753 // Relationships between types. 754 755 /// is_base_of 756 template<typename _Base, typename _Derived> 757 struct is_base_of 758 : public integral_constant<bool, __is_base_of(_Base, _Derived)> 759 { }; 760 761 template<typename _From, typename _To, 762 bool = (is_void<_From>::value || is_function<_To>::value 763 || is_array<_To>::value)> 764 struct __is_convertible_helper 765 { static const bool __value = is_void<_To>::value; }; 766 767 template<typename _From, typename _To> 768 class __is_convertible_helper<_From, _To, false> 769 : public __sfinae_types 770 { 771 template<typename _To1> 772 static void __test_aux(_To1); 773 774 template<typename _From1, typename _To1> 775 static decltype(__test_aux<_To1>(std::declval<_From1>()), __one()) 776 __test(int); 777 778 template<typename, typename> 779 static __two __test(...); 780 781 public: 782 static const bool __value = sizeof(__test<_From, _To>(0)) == 1; 783 }; 784 785 /// is_convertible 786 // XXX FIXME 787 // The C++0x specifications require front-end support, see N2255. 788 template<typename _From, typename _To> 789 struct is_convertible 790 : public integral_constant<bool, 791 __is_convertible_helper<_From, _To>::__value> 792 { }; 793 794 /// is_explicitly_convertible 795 template<typename _From, typename _To> 796 struct is_explicitly_convertible 797 : public is_constructible<_To, _From> 798 { }; 799 800 template<std::size_t _Len> 801 struct __aligned_storage_msa 802 { 803 union __type 804 { 805 unsigned char __data[_Len]; 806 struct __attribute__((__aligned__)) { } __align; 807 }; 808 }; 809 810 /** 811 * @brief Alignment type. 812 * 813 * The value of _Align is a default-alignment which shall be the 814 * most stringent alignment requirement for any C++ object type 815 * whose size is no greater than _Len (3.9). The member typedef 816 * type shall be a POD type suitable for use as uninitialized 817 * storage for any object whose size is at most _Len and whose 818 * alignment is a divisor of _Align. 819 */ 820 template<std::size_t _Len, std::size_t _Align = 821 __alignof__(typename __aligned_storage_msa<_Len>::__type)> 822 struct aligned_storage 823 { 824 union type 825 { 826 unsigned char __data[_Len]; 827 struct __attribute__((__aligned__((_Align)))) { } __align; 828 }; 829 }; 830 831 832 // Define a nested type if some predicate holds. 833 // Primary template. 834 /// enable_if 835 template<bool, typename _Tp = void> 836 struct enable_if 837 { }; 838 839 // Partial specialization for true. 840 template<typename _Tp> 841 struct enable_if<true, _Tp> 842 { typedef _Tp type; }; 843 844 845 // A conditional expression, but for types. If true, first, if false, second. 846 // Primary template. 847 /// conditional 848 template<bool _Cond, typename _Iftrue, typename _Iffalse> 849 struct conditional 850 { typedef _Iftrue type; }; 851 852 // Partial specialization for false. 853 template<typename _Iftrue, typename _Iffalse> 854 struct conditional<false, _Iftrue, _Iffalse> 855 { typedef _Iffalse type; }; 856 857 858 // Decay trait for arrays and functions, used for perfect forwarding 859 // in make_pair, make_tuple, etc. 860 template<typename _Up, 861 bool _IsArray = is_array<_Up>::value, 862 bool _IsFunction = is_function<_Up>::value> 863 struct __decay_selector; 864 865 // NB: DR 705. 866 template<typename _Up> 867 struct __decay_selector<_Up, false, false> 868 { typedef typename remove_cv<_Up>::type __type; }; 869 870 template<typename _Up> 871 struct __decay_selector<_Up, true, false> 872 { typedef typename remove_extent<_Up>::type* __type; }; 873 874 template<typename _Up> 875 struct __decay_selector<_Up, false, true> 876 { typedef typename add_pointer<_Up>::type __type; }; 877 878 /// decay 879 template<typename _Tp> 880 class decay 881 { 882 typedef typename remove_reference<_Tp>::type __remove_type; 883 884 public: 885 typedef typename __decay_selector<__remove_type>::__type type; 886 }; 887 888 template<typename _Tp> 889 class reference_wrapper; 890 891 // Helper which adds a reference to a type when given a reference_wrapper 892 template<typename _Tp> 893 struct __strip_reference_wrapper 894 { 895 typedef _Tp __type; 896 }; 897 898 template<typename _Tp> 899 struct __strip_reference_wrapper<reference_wrapper<_Tp> > 900 { 901 typedef _Tp& __type; 902 }; 903 904 template<typename _Tp> 905 struct __strip_reference_wrapper<const reference_wrapper<_Tp> > 906 { 907 typedef _Tp& __type; 908 }; 909 910 template<typename _Tp> 911 struct __decay_and_strip 912 { 913 typedef typename __strip_reference_wrapper< 914 typename decay<_Tp>::type>::__type __type; 915 }; 916 917 918 // Utility for constructing identically cv-qualified types. 919 template<typename _Unqualified, bool _IsConst, bool _IsVol> 920 struct __cv_selector; 921 922 template<typename _Unqualified> 923 struct __cv_selector<_Unqualified, false, false> 924 { typedef _Unqualified __type; }; 925 926 template<typename _Unqualified> 927 struct __cv_selector<_Unqualified, false, true> 928 { typedef volatile _Unqualified __type; }; 929 930 template<typename _Unqualified> 931 struct __cv_selector<_Unqualified, true, false> 932 { typedef const _Unqualified __type; }; 933 934 template<typename _Unqualified> 935 struct __cv_selector<_Unqualified, true, true> 936 { typedef const volatile _Unqualified __type; }; 937 938 template<typename _Qualified, typename _Unqualified, 939 bool _IsConst = is_const<_Qualified>::value, 940 bool _IsVol = is_volatile<_Qualified>::value> 941 class __match_cv_qualifiers 942 { 943 typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; 944 945 public: 946 typedef typename __match::__type __type; 947 }; 948 949 950 // Utility for finding the unsigned versions of signed integral types. 951 template<typename _Tp> 952 struct __make_unsigned 953 { typedef _Tp __type; }; 954 955 template<> 956 struct __make_unsigned<char> 957 { typedef unsigned char __type; }; 958 959 template<> 960 struct __make_unsigned<signed char> 961 { typedef unsigned char __type; }; 962 963 template<> 964 struct __make_unsigned<short> 965 { typedef unsigned short __type; }; 966 967 template<> 968 struct __make_unsigned<int> 969 { typedef unsigned int __type; }; 970 971 template<> 972 struct __make_unsigned<long> 973 { typedef unsigned long __type; }; 974 975 template<> 976 struct __make_unsigned<long long> 977 { typedef unsigned long long __type; }; 978 979 980 // Select between integral and enum: not possible to be both. 981 template<typename _Tp, 982 bool _IsInt = is_integral<_Tp>::value, 983 bool _IsEnum = is_enum<_Tp>::value> 984 class __make_unsigned_selector; 985 986 template<typename _Tp> 987 class __make_unsigned_selector<_Tp, true, false> 988 { 989 typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; 990 typedef typename __unsignedt::__type __unsigned_type; 991 typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; 992 993 public: 994 typedef typename __cv_unsigned::__type __type; 995 }; 996 997 template<typename _Tp> 998 class __make_unsigned_selector<_Tp, false, true> 999 { 1000 // With -fshort-enums, an enum may be as small as a char. 1001 typedef unsigned char __smallest; 1002 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 1003 static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); 1004 static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); 1005 typedef conditional<__b2, unsigned int, unsigned long> __cond2; 1006 typedef typename __cond2::type __cond2_type; 1007 typedef conditional<__b1, unsigned short, __cond2_type> __cond1; 1008 typedef typename __cond1::type __cond1_type; 1009 1010 public: 1011 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 1012 }; 1013 1014 // Given an integral/enum type, return the corresponding unsigned 1015 // integer type. 1016 // Primary template. 1017 /// make_unsigned 1018 template<typename _Tp> 1019 struct make_unsigned 1020 { typedef typename __make_unsigned_selector<_Tp>::__type type; }; 1021 1022 // Integral, but don't define. 1023 template<> 1024 struct make_unsigned<bool>; 1025 1026 1027 // Utility for finding the signed versions of unsigned integral types. 1028 template<typename _Tp> 1029 struct __make_signed 1030 { typedef _Tp __type; }; 1031 1032 template<> 1033 struct __make_signed<char> 1034 { typedef signed char __type; }; 1035 1036 template<> 1037 struct __make_signed<unsigned char> 1038 { typedef signed char __type; }; 1039 1040 template<> 1041 struct __make_signed<unsigned short> 1042 { typedef signed short __type; }; 1043 1044 template<> 1045 struct __make_signed<unsigned int> 1046 { typedef signed int __type; }; 1047 1048 template<> 1049 struct __make_signed<unsigned long> 1050 { typedef signed long __type; }; 1051 1052 template<> 1053 struct __make_signed<unsigned long long> 1054 { typedef signed long long __type; }; 1055 1056 1057 // Select between integral and enum: not possible to be both. 1058 template<typename _Tp, 1059 bool _IsInt = is_integral<_Tp>::value, 1060 bool _IsEnum = is_enum<_Tp>::value> 1061 class __make_signed_selector; 1062 1063 template<typename _Tp> 1064 class __make_signed_selector<_Tp, true, false> 1065 { 1066 typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; 1067 typedef typename __signedt::__type __signed_type; 1068 typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; 1069 1070 public: 1071 typedef typename __cv_signed::__type __type; 1072 }; 1073 1074 template<typename _Tp> 1075 class __make_signed_selector<_Tp, false, true> 1076 { 1077 // With -fshort-enums, an enum may be as small as a char. 1078 typedef signed char __smallest; 1079 static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); 1080 static const bool __b1 = sizeof(_Tp) <= sizeof(signed short); 1081 static const bool __b2 = sizeof(_Tp) <= sizeof(signed int); 1082 typedef conditional<__b2, signed int, signed long> __cond2; 1083 typedef typename __cond2::type __cond2_type; 1084 typedef conditional<__b1, signed short, __cond2_type> __cond1; 1085 typedef typename __cond1::type __cond1_type; 1086 1087 public: 1088 typedef typename conditional<__b0, __smallest, __cond1_type>::type __type; 1089 }; 1090 1091 // Given an integral/enum type, return the corresponding signed 1092 // integer type. 1093 // Primary template. 1094 /// make_signed 1095 template<typename _Tp> 1096 struct make_signed 1097 { typedef typename __make_signed_selector<_Tp>::__type type; }; 1098 1099 // Integral, but don't define. 1100 template<> 1101 struct make_signed<bool>; 1102 1103 /// common_type 1104 template<typename... _Tp> 1105 struct common_type; 1106 1107 template<typename _Tp> 1108 struct common_type<_Tp> 1109 { typedef _Tp type; }; 1110 1111 template<typename _Tp, typename _Up> 1112 struct common_type<_Tp, _Up> 1113 { typedef decltype(true ? declval<_Tp>() : declval<_Up>()) type; }; 1114 1115 template<typename _Tp, typename _Up, typename... _Vp> 1116 struct common_type<_Tp, _Up, _Vp...> 1117 { 1118 typedef typename 1119 common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; 1120 }; 1121 1122 /// declval 1123 template<typename _Tp> 1124 struct __declval_protector 1125 { 1126 static const bool __stop = false; 1127 static typename add_rvalue_reference<_Tp>::type __delegate(); 1128 }; 1129 1130 template<typename _Tp> 1131 inline typename add_rvalue_reference<_Tp>::type 1132 declval() noexcept 1133 { 1134 static_assert(__declval_protector<_Tp>::__stop, 1135 "declval() must not be used!"); 1136 return __declval_protector<_Tp>::__delegate(); 1137 } 1138 1139 /// result_of 1140 template<typename _Signature> 1141 class result_of; 1142 1143 template<typename _MemPtr, typename _Arg> 1144 struct _Result_of_memobj; 1145 1146 template<typename _Res, typename _Class, typename _Arg> 1147 struct _Result_of_memobj<_Res _Class::*, _Arg> 1148 { 1149 private: 1150 typedef _Res _Class::* _Func; 1151 1152 template<typename _Tp> 1153 static _Tp _S_get(const _Class&); 1154 template<typename _Tp> 1155 static decltype(*std::declval<_Tp>()) _S_get(...); 1156 1157 public: 1158 typedef 1159 decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 1160 __type; 1161 }; 1162 1163 template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 1164 struct _Result_of_memfun; 1165 1166 template<typename _Res, typename _Class, typename _Arg, typename... _Args> 1167 struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...> 1168 { 1169 private: 1170 typedef _Res _Class::* _Func; 1171 1172 template<typename _Tp> 1173 static _Tp _S_get(const _Class&); 1174 template<typename _Tp> 1175 static decltype(*std::declval<_Tp>()) _S_get(...); 1176 1177 public: 1178 typedef 1179 decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>()) 1180 (std::declval<_Args>()...) ) 1181 __type; 1182 }; 1183 1184 template<bool, bool, typename _Functor, typename... _ArgTypes> 1185 struct _Result_of_impl; 1186 1187 template<typename _Functor, typename... _ArgTypes> 1188 struct _Result_of_impl<false, false, _Functor, _ArgTypes...> 1189 { 1190 typedef 1191 decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) ) 1192 __type; 1193 }; 1194 1195 template<typename _MemPtr, typename _Arg> 1196 struct _Result_of_impl<true, false, _MemPtr, _Arg> 1197 : _Result_of_memobj<typename remove_reference<_MemPtr>::type, _Arg> 1198 { 1199 typedef typename _Result_of_memobj< 1200 typename remove_reference<_MemPtr>::type, _Arg>::__type 1201 __type; 1202 }; 1203 1204 template<typename _MemPtr, typename _Arg, typename... _ArgTypes> 1205 struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...> 1206 : _Result_of_memfun<typename remove_reference<_MemPtr>::type, _Arg, 1207 _ArgTypes...> 1208 { 1209 typedef typename _Result_of_memfun< 1210 typename remove_reference<_MemPtr>::type, _Arg, _ArgTypes...>::__type 1211 __type; 1212 }; 1213 1214 template<typename _Functor, typename... _ArgTypes> 1215 struct result_of<_Functor(_ArgTypes...)> 1216 : _Result_of_impl<is_member_object_pointer< 1217 typename remove_reference<_Functor>::type >::value, 1218 is_member_function_pointer< 1219 typename remove_reference<_Functor>::type >::value, 1220 _Functor, _ArgTypes...> 1221 { 1222 typedef typename _Result_of_impl< 1223 is_member_object_pointer< 1224 typename remove_reference<_Functor>::type >::value, 1225 is_member_function_pointer< 1226 typename remove_reference<_Functor>::type >::value, 1227 _Functor, _ArgTypes...>::__type 1228 type; 1229 }; 1230 1231 /** 1232 * Use SFINAE to determine if the type _Tp has a publicly-accessible 1233 * member type _NTYPE. 1234 */ 1235 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ 1236 template<typename _Tp> \ 1237 class __has_##_NTYPE##_helper \ 1238 : __sfinae_types \ 1239 { \ 1240 template<typename _Up> \ 1241 struct _Wrap_type \ 1242 { }; \ 1243 \ 1244 template<typename _Up> \ 1245 static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \ 1246 \ 1247 template<typename _Up> \ 1248 static __two __test(...); \ 1249 \ 1250 public: \ 1251 static const bool value = sizeof(__test<_Tp>(0)) == 1; \ 1252 }; \ 1253 \ 1254 template<typename _Tp> \ 1255 struct __has_##_NTYPE \ 1256 : integral_constant<bool, __has_##_NTYPE##_helper \ 1257 <typename remove_cv<_Tp>::type>::value> \ 1258 { }; 1259 1260 #undef _DEFINE_SPEC_0_HELPER 1261 #undef _DEFINE_SPEC_1_HELPER 1262 #undef _DEFINE_SPEC_2_HELPER 1263 #undef _DEFINE_SPEC 1264 1265 // @} group metaprogramming 1266 _GLIBCXX_END_NAMESPACE_VERSION 1267 } // namespace 1268 1269 #endif // __GXX_EXPERIMENTAL_CXX0X__ 1270 1271 #endif // _GLIBCXX_TYPE_TRAITS 1272