Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/type_traits
1 // C++11 <type_traits> -*- C++ -*- 2 3 // Copyright (C) 2007-2025 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 #ifdef _GLIBCXX_SYSHDR 33 #pragma GCC system_header 34 #endif 35 36 #if __cplusplus < 201103L 37 # include <bits/c++0x_warning.h> 38 #else 39 40 #include <bits/c++config.h> 41 42 #define __glibcxx_want_bool_constant 43 #define __glibcxx_want_bounded_array_traits 44 #define __glibcxx_want_common_reference 45 #define __glibcxx_want_has_unique_object_representations 46 #define __glibcxx_want_integral_constant_callable 47 #define __glibcxx_want_is_aggregate 48 #define __glibcxx_want_is_constant_evaluated 49 #define __glibcxx_want_is_final 50 #define __glibcxx_want_is_invocable 51 #define __glibcxx_want_is_layout_compatible 52 #define __glibcxx_want_is_nothrow_convertible 53 #define __glibcxx_want_is_null_pointer 54 #define __glibcxx_want_is_pointer_interconvertible 55 #define __glibcxx_want_is_scoped_enum 56 #define __glibcxx_want_is_swappable 57 #define __glibcxx_want_is_virtual_base_of 58 #define __glibcxx_want_logical_traits 59 #define __glibcxx_want_reference_from_temporary 60 #define __glibcxx_want_remove_cvref 61 #define __glibcxx_want_result_of_sfinae 62 #define __glibcxx_want_transformation_trait_aliases 63 #define __glibcxx_want_type_identity 64 #define __glibcxx_want_type_trait_variable_templates 65 #define __glibcxx_want_unwrap_ref 66 #define __glibcxx_want_void_t 67 #include <bits/version.h> 68 69 extern "C++" 70 { 71 namespace std _GLIBCXX_VISIBILITY(default) 72 { 73 _GLIBCXX_BEGIN_NAMESPACE_VERSION 74 75 template<typename _Tp> 76 class reference_wrapper; 77 78 /** 79 * @defgroup metaprogramming Metaprogramming 80 * @ingroup utilities 81 * 82 * Template utilities for compile-time introspection and modification, 83 * including type classification traits, type property inspection traits 84 * and type transformation traits. 85 * 86 * @since C++11 87 * 88 * @{ 89 */ 90 91 /// integral_constant 92 template<typename _Tp, _Tp __v> 93 struct integral_constant 94 { 95 static constexpr _Tp value = __v; 96 using value_type = _Tp; 97 using type = integral_constant<_Tp, __v>; 98 constexpr operator value_type() const noexcept { return value; } 99 100 #ifdef __cpp_lib_integral_constant_callable // C++ >= 14 101 constexpr value_type operator()() const noexcept { return value; } 102 #endif 103 }; 104 105 #if ! __cpp_inline_variables 106 template<typename _Tp, _Tp __v> 107 constexpr _Tp integral_constant<_Tp, __v>::value; 108 #endif 109 110 /// @cond undocumented 111 /// bool_constant for C++11 112 template<bool __v> 113 using __bool_constant = integral_constant<bool, __v>; 114 /// @endcond 115 116 /// The type used as a compile-time boolean with true value. 117 using true_type = __bool_constant<true>; 118 119 /// The type used as a compile-time boolean with false value. 120 using false_type = __bool_constant<false>; 121 122 #ifdef __cpp_lib_bool_constant // C++ >= 17 123 /// Alias template for compile-time boolean constant types. 124 /// @since C++17 125 template<bool __v> 126 using bool_constant = __bool_constant<__v>; 127 #endif 128 129 // Metaprogramming helper types. 130 131 // Primary template. 132 /// Define a member typedef `type` only if a boolean constant is true. 133 template<bool, typename _Tp = void> 134 struct enable_if 135 { }; 136 137 // Partial specialization for true. 138 template<typename _Tp> 139 struct enable_if<true, _Tp> 140 { using type = _Tp; }; 141 142 // __enable_if_t (std::enable_if_t for C++11) 143 template<bool _Cond, typename _Tp = void> 144 using __enable_if_t = typename enable_if<_Cond, _Tp>::type; 145 146 template<bool> 147 struct __conditional 148 { 149 template<typename _Tp, typename> 150 using type = _Tp; 151 }; 152 153 template<> 154 struct __conditional<false> 155 { 156 template<typename, typename _Up> 157 using type = _Up; 158 }; 159 160 // More efficient version of std::conditional_t for internal use (and C++11) 161 template<bool _Cond, typename _If, typename _Else> 162 using __conditional_t 163 = typename __conditional<_Cond>::template type<_If, _Else>; 164 165 /// @cond undocumented 166 template <typename _Type> 167 struct __type_identity 168 { using type = _Type; }; 169 170 template<typename _Tp> 171 using __type_identity_t = typename __type_identity<_Tp>::type; 172 173 namespace __detail 174 { 175 // A variadic alias template that resolves to its first argument. 176 template<typename _Tp, typename...> 177 using __first_t = _Tp; 178 179 // These are deliberately not defined. 180 template<typename... _Bn> 181 auto __or_fn(int) -> __first_t<false_type, 182 __enable_if_t<!bool(_Bn::value)>...>; 183 184 template<typename... _Bn> 185 auto __or_fn(...) -> true_type; 186 187 template<typename... _Bn> 188 auto __and_fn(int) -> __first_t<true_type, 189 __enable_if_t<bool(_Bn::value)>...>; 190 191 template<typename... _Bn> 192 auto __and_fn(...) -> false_type; 193 } // namespace detail 194 195 // Like C++17 std::dis/conjunction, but usable in C++11 and resolves 196 // to either true_type or false_type which allows for a more efficient 197 // implementation that avoids recursive class template instantiation. 198 template<typename... _Bn> 199 struct __or_ 200 : decltype(__detail::__or_fn<_Bn...>(0)) 201 { }; 202 203 template<typename... _Bn> 204 struct __and_ 205 : decltype(__detail::__and_fn<_Bn...>(0)) 206 { }; 207 208 template<typename _Pp> 209 struct __not_ 210 : __bool_constant<!bool(_Pp::value)> 211 { }; 212 /// @endcond 213 214 #ifdef __cpp_lib_logical_traits // C++ >= 17 215 216 /// @cond undocumented 217 template<typename... _Bn> 218 inline constexpr bool __or_v = __or_<_Bn...>::value; 219 template<typename... _Bn> 220 inline constexpr bool __and_v = __and_<_Bn...>::value; 221 222 namespace __detail 223 { 224 template<typename /* = void */, typename _B1, typename... _Bn> 225 struct __disjunction_impl 226 { using type = _B1; }; 227 228 template<typename _B1, typename _B2, typename... _Bn> 229 struct __disjunction_impl<__enable_if_t<!bool(_B1::value)>, _B1, _B2, _Bn...> 230 { using type = typename __disjunction_impl<void, _B2, _Bn...>::type; }; 231 232 template<typename /* = void */, typename _B1, typename... _Bn> 233 struct __conjunction_impl 234 { using type = _B1; }; 235 236 template<typename _B1, typename _B2, typename... _Bn> 237 struct __conjunction_impl<__enable_if_t<bool(_B1::value)>, _B1, _B2, _Bn...> 238 { using type = typename __conjunction_impl<void, _B2, _Bn...>::type; }; 239 } // namespace __detail 240 /// @endcond 241 242 template<typename... _Bn> 243 struct conjunction 244 : __detail::__conjunction_impl<void, _Bn...>::type 245 { }; 246 247 template<> 248 struct conjunction<> 249 : true_type 250 { }; 251 252 template<typename... _Bn> 253 struct disjunction 254 : __detail::__disjunction_impl<void, _Bn...>::type 255 { }; 256 257 template<> 258 struct disjunction<> 259 : false_type 260 { }; 261 262 template<typename _Pp> 263 struct negation 264 : __not_<_Pp>::type 265 { }; 266 267 /** @ingroup variable_templates 268 * @{ 269 */ 270 template<typename... _Bn> 271 inline constexpr bool conjunction_v = conjunction<_Bn...>::value; 272 273 template<typename... _Bn> 274 inline constexpr bool disjunction_v = disjunction<_Bn...>::value; 275 276 template<typename _Pp> 277 inline constexpr bool negation_v = negation<_Pp>::value; 278 /// @} 279 280 #endif // __cpp_lib_logical_traits 281 282 // Forward declarations 283 template<typename> 284 struct is_reference; 285 template<typename> 286 struct is_function; 287 template<typename> 288 struct is_void; 289 template<typename> 290 struct remove_cv; 291 template<typename> 292 struct is_const; 293 294 /// @cond undocumented 295 template<typename> 296 struct __is_array_unknown_bounds; 297 298 // Helper functions that return false_type for incomplete classes, 299 // incomplete unions and arrays of known bound from those. 300 301 template <typename _Tp, size_t = sizeof(_Tp)> 302 constexpr true_type __is_complete_or_unbounded(__type_identity<_Tp>) 303 { return {}; } 304 305 template <typename _TypeIdentity, 306 typename _NestedType = typename _TypeIdentity::type> 307 constexpr typename __or_< 308 is_reference<_NestedType>, 309 is_function<_NestedType>, 310 is_void<_NestedType>, 311 __is_array_unknown_bounds<_NestedType> 312 >::type __is_complete_or_unbounded(_TypeIdentity) 313 { return {}; } 314 315 // __remove_cv_t (std::remove_cv_t for C++11). 316 template<typename _Tp> 317 using __remove_cv_t = typename remove_cv<_Tp>::type; 318 /// @endcond 319 320 // Primary type categories. 321 322 /// is_void 323 template<typename _Tp> 324 struct is_void 325 : public false_type { }; 326 327 template<> 328 struct is_void<void> 329 : public true_type { }; 330 331 template<> 332 struct is_void<const void> 333 : public true_type { }; 334 335 template<> 336 struct is_void<volatile void> 337 : public true_type { }; 338 339 template<> 340 struct is_void<const volatile void> 341 : public true_type { }; 342 343 /// @cond undocumented 344 template<typename> 345 struct __is_integral_helper 346 : public false_type { }; 347 348 template<> 349 struct __is_integral_helper<bool> 350 : public true_type { }; 351 352 template<> 353 struct __is_integral_helper<char> 354 : public true_type { }; 355 356 template<> 357 struct __is_integral_helper<signed char> 358 : public true_type { }; 359 360 template<> 361 struct __is_integral_helper<unsigned char> 362 : public true_type { }; 363 364 // We want is_integral<wchar_t> to be true (and make_signed/unsigned to work) 365 // even when libc doesn't provide working <wchar.h> and related functions, 366 // so don't check _GLIBCXX_USE_WCHAR_T here. 367 template<> 368 struct __is_integral_helper<wchar_t> 369 : public true_type { }; 370 371 #ifdef _GLIBCXX_USE_CHAR8_T 372 template<> 373 struct __is_integral_helper<char8_t> 374 : public true_type { }; 375 #endif 376 377 template<> 378 struct __is_integral_helper<char16_t> 379 : public true_type { }; 380 381 template<> 382 struct __is_integral_helper<char32_t> 383 : public true_type { }; 384 385 template<> 386 struct __is_integral_helper<short> 387 : public true_type { }; 388 389 template<> 390 struct __is_integral_helper<unsigned short> 391 : public true_type { }; 392 393 template<> 394 struct __is_integral_helper<int> 395 : public true_type { }; 396 397 template<> 398 struct __is_integral_helper<unsigned int> 399 : public true_type { }; 400 401 template<> 402 struct __is_integral_helper<long> 403 : public true_type { }; 404 405 template<> 406 struct __is_integral_helper<unsigned long> 407 : public true_type { }; 408 409 template<> 410 struct __is_integral_helper<long long> 411 : public true_type { }; 412 413 template<> 414 struct __is_integral_helper<unsigned long long> 415 : public true_type { }; 416 417 // Conditionalizing on __STRICT_ANSI__ here will break any port that 418 // uses one of these types for size_t. 419 #if defined(__GLIBCXX_TYPE_INT_N_0) 420 __extension__ 421 template<> 422 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> 423 : public true_type { }; 424 425 __extension__ 426 template<> 427 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0> 428 : public true_type { }; 429 #endif 430 #if defined(__GLIBCXX_TYPE_INT_N_1) 431 __extension__ 432 template<> 433 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> 434 : public true_type { }; 435 436 __extension__ 437 template<> 438 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1> 439 : public true_type { }; 440 #endif 441 #if defined(__GLIBCXX_TYPE_INT_N_2) 442 __extension__ 443 template<> 444 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> 445 : public true_type { }; 446 447 __extension__ 448 template<> 449 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2> 450 : public true_type { }; 451 #endif 452 #if defined(__GLIBCXX_TYPE_INT_N_3) 453 __extension__ 454 template<> 455 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> 456 : public true_type { }; 457 458 __extension__ 459 template<> 460 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3> 461 : public true_type { }; 462 #endif 463 /// @endcond 464 465 /// is_integral 466 template<typename _Tp> 467 struct is_integral 468 : public __is_integral_helper<__remove_cv_t<_Tp>>::type 469 { }; 470 471 /// @cond undocumented 472 template<typename> 473 struct __is_floating_point_helper 474 : public false_type { }; 475 476 template<> 477 struct __is_floating_point_helper<float> 478 : public true_type { }; 479 480 template<> 481 struct __is_floating_point_helper<double> 482 : public true_type { }; 483 484 template<> 485 struct __is_floating_point_helper<long double> 486 : public true_type { }; 487 488 #ifdef __STDCPP_FLOAT16_T__ 489 template<> 490 struct __is_floating_point_helper<_Float16> 491 : public true_type { }; 492 #endif 493 494 #ifdef __STDCPP_FLOAT32_T__ 495 template<> 496 struct __is_floating_point_helper<_Float32> 497 : public true_type { }; 498 #endif 499 500 #ifdef __STDCPP_FLOAT64_T__ 501 template<> 502 struct __is_floating_point_helper<_Float64> 503 : public true_type { }; 504 #endif 505 506 #ifdef __STDCPP_FLOAT128_T__ 507 template<> 508 struct __is_floating_point_helper<_Float128> 509 : public true_type { }; 510 #endif 511 512 #ifdef __STDCPP_BFLOAT16_T__ 513 template<> 514 struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t> 515 : public true_type { }; 516 #endif 517 518 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) && !defined(__CUDACC__) 519 template<> 520 struct __is_floating_point_helper<__float128> 521 : public true_type { }; 522 #endif 523 /// @endcond 524 525 /// is_floating_point 526 template<typename _Tp> 527 struct is_floating_point 528 : public __is_floating_point_helper<__remove_cv_t<_Tp>>::type 529 { }; 530 531 /// is_array 532 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) 533 template<typename _Tp> 534 struct is_array 535 : public __bool_constant<__is_array(_Tp)> 536 { }; 537 #else 538 template<typename> 539 struct is_array 540 : public false_type { }; 541 542 template<typename _Tp, std::size_t _Size> 543 struct is_array<_Tp[_Size]> 544 : public true_type { }; 545 546 template<typename _Tp> 547 struct is_array<_Tp[]> 548 : public true_type { }; 549 #endif 550 551 /// is_pointer 552 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer) 553 template<typename _Tp> 554 struct is_pointer 555 : public __bool_constant<__is_pointer(_Tp)> 556 { }; 557 #else 558 template<typename _Tp> 559 struct is_pointer 560 : public false_type { }; 561 562 template<typename _Tp> 563 struct is_pointer<_Tp*> 564 : public true_type { }; 565 566 template<typename _Tp> 567 struct is_pointer<_Tp* const> 568 : public true_type { }; 569 570 template<typename _Tp> 571 struct is_pointer<_Tp* volatile> 572 : public true_type { }; 573 574 template<typename _Tp> 575 struct is_pointer<_Tp* const volatile> 576 : public true_type { }; 577 #endif 578 579 /// is_lvalue_reference 580 template<typename> 581 struct is_lvalue_reference 582 : public false_type { }; 583 584 template<typename _Tp> 585 struct is_lvalue_reference<_Tp&> 586 : public true_type { }; 587 588 /// is_rvalue_reference 589 template<typename> 590 struct is_rvalue_reference 591 : public false_type { }; 592 593 template<typename _Tp> 594 struct is_rvalue_reference<_Tp&&> 595 : public true_type { }; 596 597 /// is_member_object_pointer 598 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) 599 template<typename _Tp> 600 struct is_member_object_pointer 601 : public __bool_constant<__is_member_object_pointer(_Tp)> 602 { }; 603 #else 604 template<typename> 605 struct __is_member_object_pointer_helper 606 : public false_type { }; 607 608 template<typename _Tp, typename _Cp> 609 struct __is_member_object_pointer_helper<_Tp _Cp::*> 610 : public __not_<is_function<_Tp>>::type { }; 611 612 613 template<typename _Tp> 614 struct is_member_object_pointer 615 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type 616 { }; 617 #endif 618 619 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) 620 /// is_member_function_pointer 621 template<typename _Tp> 622 struct is_member_function_pointer 623 : public __bool_constant<__is_member_function_pointer(_Tp)> 624 { }; 625 #else 626 template<typename> 627 struct __is_member_function_pointer_helper 628 : public false_type { }; 629 630 template<typename _Tp, typename _Cp> 631 struct __is_member_function_pointer_helper<_Tp _Cp::*> 632 : public is_function<_Tp>::type { }; 633 634 /// is_member_function_pointer 635 template<typename _Tp> 636 struct is_member_function_pointer 637 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type 638 { }; 639 #endif 640 641 /// is_enum 642 template<typename _Tp> 643 struct is_enum 644 : public __bool_constant<__is_enum(_Tp)> 645 { }; 646 647 /// is_union 648 template<typename _Tp> 649 struct is_union 650 : public __bool_constant<__is_union(_Tp)> 651 { }; 652 653 /// is_class 654 template<typename _Tp> 655 struct is_class 656 : public __bool_constant<__is_class(_Tp)> 657 { }; 658 659 /// is_function 660 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) 661 template<typename _Tp> 662 struct is_function 663 : public __bool_constant<__is_function(_Tp)> 664 { }; 665 #else 666 template<typename _Tp> 667 struct is_function 668 : public __bool_constant<!is_const<const _Tp>::value> { }; 669 670 template<typename _Tp> 671 struct is_function<_Tp&> 672 : public false_type { }; 673 674 template<typename _Tp> 675 struct is_function<_Tp&&> 676 : public false_type { }; 677 #endif 678 679 #ifdef __cpp_lib_is_null_pointer // C++ >= 11 680 /// is_null_pointer (LWG 2247). 681 template<typename _Tp> 682 struct is_null_pointer 683 : public false_type { }; 684 685 template<> 686 struct is_null_pointer<std::nullptr_t> 687 : public true_type { }; 688 689 template<> 690 struct is_null_pointer<const std::nullptr_t> 691 : public true_type { }; 692 693 template<> 694 struct is_null_pointer<volatile std::nullptr_t> 695 : public true_type { }; 696 697 template<> 698 struct is_null_pointer<const volatile std::nullptr_t> 699 : public true_type { }; 700 701 /// __is_nullptr_t (deprecated extension). 702 /// @deprecated Non-standard. Use `is_null_pointer` instead. 703 template<typename _Tp> 704 struct __is_nullptr_t 705 : public is_null_pointer<_Tp> 706 { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer"); 707 #endif // __cpp_lib_is_null_pointer 708 709 // Composite type categories. 710 711 /// is_reference 712 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) 713 template<typename _Tp> 714 struct is_reference 715 : public __bool_constant<__is_reference(_Tp)> 716 { }; 717 #else 718 template<typename _Tp> 719 struct is_reference 720 : public false_type 721 { }; 722 723 template<typename _Tp> 724 struct is_reference<_Tp&> 725 : public true_type 726 { }; 727 728 template<typename _Tp> 729 struct is_reference<_Tp&&> 730 : public true_type 731 { }; 732 #endif 733 734 /// is_arithmetic 735 template<typename _Tp> 736 struct is_arithmetic 737 : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type 738 { }; 739 740 /// is_fundamental 741 template<typename _Tp> 742 struct is_fundamental 743 : public __or_<is_arithmetic<_Tp>, is_void<_Tp>, 744 is_null_pointer<_Tp>>::type 745 { }; 746 747 /// is_object 748 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) 749 template<typename _Tp> 750 struct is_object 751 : public __bool_constant<__is_object(_Tp)> 752 { }; 753 #else 754 template<typename _Tp> 755 struct is_object 756 : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>, 757 is_void<_Tp>>>::type 758 { }; 759 #endif 760 761 template<typename> 762 struct is_member_pointer; 763 764 /// is_scalar 765 template<typename _Tp> 766 struct is_scalar 767 : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>, 768 is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type 769 { }; 770 771 /// is_compound 772 template<typename _Tp> 773 struct is_compound 774 : public __bool_constant<!is_fundamental<_Tp>::value> { }; 775 776 /// is_member_pointer 777 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) 778 template<typename _Tp> 779 struct is_member_pointer 780 : public __bool_constant<__is_member_pointer(_Tp)> 781 { }; 782 #else 783 /// @cond undocumented 784 template<typename _Tp> 785 struct __is_member_pointer_helper 786 : public false_type { }; 787 788 template<typename _Tp, typename _Cp> 789 struct __is_member_pointer_helper<_Tp _Cp::*> 790 : public true_type { }; 791 /// @endcond 792 793 template<typename _Tp> 794 struct is_member_pointer 795 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type 796 { }; 797 #endif 798 799 template<typename, typename> 800 struct is_same; 801 802 /// @cond undocumented 803 template<typename _Tp, typename... _Types> 804 using __is_one_of = __or_<is_same<_Tp, _Types>...>; 805 806 // Check if a type is one of the signed integer types. 807 __extension__ 808 template<typename _Tp> 809 using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>, 810 signed char, signed short, signed int, signed long, 811 signed long long 812 #if defined(__GLIBCXX_TYPE_INT_N_0) 813 , signed __GLIBCXX_TYPE_INT_N_0 814 #endif 815 #if defined(__GLIBCXX_TYPE_INT_N_1) 816 , signed __GLIBCXX_TYPE_INT_N_1 817 #endif 818 #if defined(__GLIBCXX_TYPE_INT_N_2) 819 , signed __GLIBCXX_TYPE_INT_N_2 820 #endif 821 #if defined(__GLIBCXX_TYPE_INT_N_3) 822 , signed __GLIBCXX_TYPE_INT_N_3 823 #endif 824 >; 825 826 // Check if a type is one of the unsigned integer types. 827 __extension__ 828 template<typename _Tp> 829 using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>, 830 unsigned char, unsigned short, unsigned int, unsigned long, 831 unsigned long long 832 #if defined(__GLIBCXX_TYPE_INT_N_0) 833 , unsigned __GLIBCXX_TYPE_INT_N_0 834 #endif 835 #if defined(__GLIBCXX_TYPE_INT_N_1) 836 , unsigned __GLIBCXX_TYPE_INT_N_1 837 #endif 838 #if defined(__GLIBCXX_TYPE_INT_N_2) 839 , unsigned __GLIBCXX_TYPE_INT_N_2 840 #endif 841 #if defined(__GLIBCXX_TYPE_INT_N_3) 842 , unsigned __GLIBCXX_TYPE_INT_N_3 843 #endif 844 >; 845 846 // Check if a type is one of the signed or unsigned integer types. 847 template<typename _Tp> 848 using __is_standard_integer 849 = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>; 850 851 // __void_t (std::void_t for C++11) 852 template<typename...> using __void_t = void; 853 /// @endcond 854 855 // Type properties. 856 857 /// is_const 858 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const) 859 template<typename _Tp> 860 struct is_const 861 : public __bool_constant<__is_const(_Tp)> 862 { }; 863 #else 864 template<typename> 865 struct is_const 866 : public false_type { }; 867 868 template<typename _Tp> 869 struct is_const<_Tp const> 870 : public true_type { }; 871 #endif 872 873 /// is_volatile 874 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile) 875 template<typename _Tp> 876 struct is_volatile 877 : public __bool_constant<__is_volatile(_Tp)> 878 { }; 879 #else 880 template<typename> 881 struct is_volatile 882 : public false_type { }; 883 884 template<typename _Tp> 885 struct is_volatile<_Tp volatile> 886 : public true_type { }; 887 #endif 888 889 /** is_trivial 890 * @deprecated Deprecated in C++26. 891 * Use a combination of one or more more specialized type traits instead, 892 * such as `is_trivially_default_constructible`, 893 * `is_trivially_copy_constructible`, `is_trivially_copy_assignable`, 894 * etc., depending on the exact check(s) needed. 895 */ 896 template<typename _Tp> 897 struct 898 _GLIBCXX26_DEPRECATED_SUGGEST("is_trivially_default_constructible && is_trivially_copyable") 899 is_trivial 900 : public __bool_constant<__is_trivial(_Tp)> 901 { 902 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 903 "template argument must be a complete class or an unbounded array"); 904 }; 905 906 /// is_trivially_copyable 907 template<typename _Tp> 908 struct is_trivially_copyable 909 : public __bool_constant<__is_trivially_copyable(_Tp)> 910 { 911 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 912 "template argument must be a complete class or an unbounded array"); 913 }; 914 915 /// is_standard_layout 916 template<typename _Tp> 917 struct is_standard_layout 918 : public __bool_constant<__is_standard_layout(_Tp)> 919 { 920 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 921 "template argument must be a complete class or an unbounded array"); 922 }; 923 924 /** is_pod 925 * @deprecated Deprecated in C++20. 926 * Use `is_standard_layout && is_trivial` instead. 927 */ 928 // Could use is_standard_layout && is_trivial instead of the builtin. 929 template<typename _Tp> 930 struct 931 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") 932 is_pod 933 : public __bool_constant<__is_pod(_Tp)> 934 { 935 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 936 "template argument must be a complete class or an unbounded array"); 937 }; 938 939 /** is_literal_type 940 * @deprecated Deprecated in C++17, removed in C++20. 941 * The idea of a literal type isn't useful. 942 */ 943 template<typename _Tp> 944 struct 945 _GLIBCXX17_DEPRECATED 946 is_literal_type 947 : public __bool_constant<__is_literal_type(_Tp)> 948 { 949 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 950 "template argument must be a complete class or an unbounded array"); 951 }; 952 953 /// is_empty 954 template<typename _Tp> 955 struct is_empty 956 : public __bool_constant<__is_empty(_Tp)> 957 { }; 958 959 /// is_polymorphic 960 template<typename _Tp> 961 struct is_polymorphic 962 : public __bool_constant<__is_polymorphic(_Tp)> 963 { }; 964 965 #ifdef __cpp_lib_is_final // C++ >= 14 966 /// is_final 967 /// @since C++14 968 template<typename _Tp> 969 struct is_final 970 : public __bool_constant<__is_final(_Tp)> 971 { }; 972 #endif 973 974 /// is_abstract 975 template<typename _Tp> 976 struct is_abstract 977 : public __bool_constant<__is_abstract(_Tp)> 978 { }; 979 980 /// @cond undocumented 981 template<typename _Tp, 982 bool = is_arithmetic<_Tp>::value> 983 struct __is_signed_helper 984 : public false_type { }; 985 986 template<typename _Tp> 987 struct __is_signed_helper<_Tp, true> 988 : public __bool_constant<_Tp(-1) < _Tp(0)> 989 { }; 990 /// @endcond 991 992 /// is_signed 993 template<typename _Tp> 994 struct is_signed 995 : public __is_signed_helper<_Tp>::type 996 { }; 997 998 /// is_unsigned 999 template<typename _Tp> 1000 struct is_unsigned 1001 : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type 1002 { }; 1003 1004 /// @cond undocumented 1005 template<typename _Tp, typename _Up = _Tp&&> 1006 _Up 1007 __declval(int); 1008 1009 template<typename _Tp> 1010 _Tp 1011 __declval(long); 1012 /// @endcond 1013 1014 template<typename _Tp> 1015 auto declval() noexcept -> decltype(__declval<_Tp>(0)); 1016 1017 template<typename> 1018 struct remove_all_extents; 1019 1020 /// @cond undocumented 1021 template<typename _Tp> 1022 struct __is_array_known_bounds 1023 : public false_type 1024 { }; 1025 1026 template<typename _Tp, size_t _Size> 1027 struct __is_array_known_bounds<_Tp[_Size]> 1028 : public true_type 1029 { }; 1030 1031 template<typename _Tp> 1032 struct __is_array_unknown_bounds 1033 : public false_type 1034 { }; 1035 1036 template<typename _Tp> 1037 struct __is_array_unknown_bounds<_Tp[]> 1038 : public true_type 1039 { }; 1040 1041 // Destructible and constructible type properties. 1042 1043 // In N3290 is_destructible does not say anything about function 1044 // types and abstract types, see LWG 2049. This implementation 1045 // describes function types as non-destructible and all complete 1046 // object types as destructible, iff the explicit destructor 1047 // call expression is wellformed. 1048 struct __do_is_destructible_impl 1049 { 1050 template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())> 1051 static true_type __test(int); 1052 1053 template<typename> 1054 static false_type __test(...); 1055 }; 1056 1057 template<typename _Tp> 1058 struct __is_destructible_impl 1059 : public __do_is_destructible_impl 1060 { 1061 using type = decltype(__test<_Tp>(0)); 1062 }; 1063 1064 template<typename _Tp, 1065 bool = __or_<is_void<_Tp>, 1066 __is_array_unknown_bounds<_Tp>, 1067 is_function<_Tp>>::value, 1068 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value> 1069 struct __is_destructible_safe; 1070 1071 template<typename _Tp> 1072 struct __is_destructible_safe<_Tp, false, false> 1073 : public __is_destructible_impl<typename 1074 remove_all_extents<_Tp>::type>::type 1075 { }; 1076 1077 template<typename _Tp> 1078 struct __is_destructible_safe<_Tp, true, false> 1079 : public false_type { }; 1080 1081 template<typename _Tp> 1082 struct __is_destructible_safe<_Tp, false, true> 1083 : public true_type { }; 1084 /// @endcond 1085 1086 /// is_destructible 1087 template<typename _Tp> 1088 struct is_destructible 1089 : public __is_destructible_safe<_Tp>::type 1090 { 1091 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1092 "template argument must be a complete class or an unbounded array"); 1093 }; 1094 1095 /// @cond undocumented 1096 1097 // is_nothrow_destructible requires that is_destructible is 1098 // satisfied as well. We realize that by mimicing the 1099 // implementation of is_destructible but refer to noexcept(expr) 1100 // instead of decltype(expr). 1101 struct __do_is_nt_destructible_impl 1102 { 1103 template<typename _Tp> 1104 static __bool_constant<noexcept(declval<_Tp&>().~_Tp())> 1105 __test(int); 1106 1107 template<typename> 1108 static false_type __test(...); 1109 }; 1110 1111 template<typename _Tp> 1112 struct __is_nt_destructible_impl 1113 : public __do_is_nt_destructible_impl 1114 { 1115 using type = decltype(__test<_Tp>(0)); 1116 }; 1117 1118 template<typename _Tp, 1119 bool = __or_<is_void<_Tp>, 1120 __is_array_unknown_bounds<_Tp>, 1121 is_function<_Tp>>::value, 1122 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value> 1123 struct __is_nt_destructible_safe; 1124 1125 template<typename _Tp> 1126 struct __is_nt_destructible_safe<_Tp, false, false> 1127 : public __is_nt_destructible_impl<typename 1128 remove_all_extents<_Tp>::type>::type 1129 { }; 1130 1131 template<typename _Tp> 1132 struct __is_nt_destructible_safe<_Tp, true, false> 1133 : public false_type { }; 1134 1135 template<typename _Tp> 1136 struct __is_nt_destructible_safe<_Tp, false, true> 1137 : public true_type { }; 1138 /// @endcond 1139 1140 /// is_nothrow_destructible 1141 template<typename _Tp> 1142 struct is_nothrow_destructible 1143 : public __is_nt_destructible_safe<_Tp>::type 1144 { 1145 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1146 "template argument must be a complete class or an unbounded array"); 1147 }; 1148 1149 /// @cond undocumented 1150 template<typename _Tp, typename... _Args> 1151 using __is_constructible_impl 1152 = __bool_constant<__is_constructible(_Tp, _Args...)>; 1153 /// @endcond 1154 1155 /// is_constructible 1156 template<typename _Tp, typename... _Args> 1157 struct is_constructible 1158 : public __is_constructible_impl<_Tp, _Args...> 1159 { 1160 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1161 "template argument must be a complete class or an unbounded array"); 1162 }; 1163 1164 /// is_default_constructible 1165 template<typename _Tp> 1166 struct is_default_constructible 1167 : public __is_constructible_impl<_Tp> 1168 { 1169 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1170 "template argument must be a complete class or an unbounded array"); 1171 }; 1172 1173 /// @cond undocumented 1174 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference) 1175 template<typename _Tp> 1176 using __add_lval_ref_t = __add_lvalue_reference(_Tp); 1177 #else 1178 template<typename _Tp, typename = void> 1179 struct __add_lvalue_reference_helper 1180 { using type = _Tp; }; 1181 1182 template<typename _Tp> 1183 struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>> 1184 { using type = _Tp&; }; 1185 1186 template<typename _Tp> 1187 using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type; 1188 #endif 1189 /// @endcond 1190 1191 /// is_copy_constructible 1192 template<typename _Tp> 1193 struct is_copy_constructible 1194 : public __is_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>> 1195 { 1196 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1197 "template argument must be a complete class or an unbounded array"); 1198 }; 1199 1200 /// @cond undocumented 1201 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference) 1202 template<typename _Tp> 1203 using __add_rval_ref_t = __add_rvalue_reference(_Tp); 1204 #else 1205 template<typename _Tp, typename = void> 1206 struct __add_rvalue_reference_helper 1207 { using type = _Tp; }; 1208 1209 template<typename _Tp> 1210 struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>> 1211 { using type = _Tp&&; }; 1212 1213 template<typename _Tp> 1214 using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type; 1215 #endif 1216 /// @endcond 1217 1218 /// is_move_constructible 1219 template<typename _Tp> 1220 struct is_move_constructible 1221 : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> 1222 { 1223 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1224 "template argument must be a complete class or an unbounded array"); 1225 }; 1226 1227 /// @cond undocumented 1228 template<typename _Tp, typename... _Args> 1229 using __is_nothrow_constructible_impl 1230 = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>; 1231 /// @endcond 1232 1233 /// is_nothrow_constructible 1234 template<typename _Tp, typename... _Args> 1235 struct is_nothrow_constructible 1236 : public __is_nothrow_constructible_impl<_Tp, _Args...> 1237 { 1238 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1239 "template argument must be a complete class or an unbounded array"); 1240 }; 1241 1242 /// is_nothrow_default_constructible 1243 template<typename _Tp> 1244 struct is_nothrow_default_constructible 1245 : public __is_nothrow_constructible_impl<_Tp> 1246 { 1247 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1248 "template argument must be a complete class or an unbounded array"); 1249 }; 1250 1251 /// is_nothrow_copy_constructible 1252 template<typename _Tp> 1253 struct is_nothrow_copy_constructible 1254 : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>> 1255 { 1256 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1257 "template argument must be a complete class or an unbounded array"); 1258 }; 1259 1260 /// is_nothrow_move_constructible 1261 template<typename _Tp> 1262 struct is_nothrow_move_constructible 1263 : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> 1264 { 1265 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1266 "template argument must be a complete class or an unbounded array"); 1267 }; 1268 1269 /// @cond undocumented 1270 template<typename _Tp, typename _Up> 1271 using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>; 1272 /// @endcond 1273 1274 /// is_assignable 1275 template<typename _Tp, typename _Up> 1276 struct is_assignable 1277 : public __is_assignable_impl<_Tp, _Up> 1278 { 1279 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1280 "template argument must be a complete class or an unbounded array"); 1281 }; 1282 1283 /// is_copy_assignable 1284 template<typename _Tp> 1285 struct is_copy_assignable 1286 : public __is_assignable_impl<__add_lval_ref_t<_Tp>, 1287 __add_lval_ref_t<const _Tp>> 1288 { 1289 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1290 "template argument must be a complete class or an unbounded array"); 1291 }; 1292 1293 /// is_move_assignable 1294 template<typename _Tp> 1295 struct is_move_assignable 1296 : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>> 1297 { 1298 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1299 "template argument must be a complete class or an unbounded array"); 1300 }; 1301 1302 /// @cond undocumented 1303 template<typename _Tp, typename _Up> 1304 using __is_nothrow_assignable_impl 1305 = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>; 1306 /// @endcond 1307 1308 /// is_nothrow_assignable 1309 template<typename _Tp, typename _Up> 1310 struct is_nothrow_assignable 1311 : public __is_nothrow_assignable_impl<_Tp, _Up> 1312 { 1313 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1314 "template argument must be a complete class or an unbounded array"); 1315 }; 1316 1317 /// is_nothrow_copy_assignable 1318 template<typename _Tp> 1319 struct is_nothrow_copy_assignable 1320 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, 1321 __add_lval_ref_t<const _Tp>> 1322 { 1323 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1324 "template argument must be a complete class or an unbounded array"); 1325 }; 1326 1327 /// is_nothrow_move_assignable 1328 template<typename _Tp> 1329 struct is_nothrow_move_assignable 1330 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>, 1331 __add_rval_ref_t<_Tp>> 1332 { 1333 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1334 "template argument must be a complete class or an unbounded array"); 1335 }; 1336 1337 /// @cond undocumented 1338 template<typename _Tp, typename... _Args> 1339 using __is_trivially_constructible_impl 1340 = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>; 1341 /// @endcond 1342 1343 /// is_trivially_constructible 1344 template<typename _Tp, typename... _Args> 1345 struct is_trivially_constructible 1346 : public __is_trivially_constructible_impl<_Tp, _Args...> 1347 { 1348 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1349 "template argument must be a complete class or an unbounded array"); 1350 }; 1351 1352 /// is_trivially_default_constructible 1353 template<typename _Tp> 1354 struct is_trivially_default_constructible 1355 : public __is_trivially_constructible_impl<_Tp> 1356 { 1357 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1358 "template argument must be a complete class or an unbounded array"); 1359 }; 1360 1361 #if __cpp_variable_templates && __cpp_concepts 1362 template<typename _Tp> 1363 constexpr bool __is_implicitly_default_constructible_v 1364 = requires (void(&__f)(_Tp)) { __f({}); }; 1365 1366 template<typename _Tp> 1367 struct __is_implicitly_default_constructible 1368 : __bool_constant<__is_implicitly_default_constructible_v<_Tp>> 1369 { }; 1370 #else 1371 struct __do_is_implicitly_default_constructible_impl 1372 { 1373 template <typename _Tp> 1374 static void __helper(const _Tp&); 1375 1376 template <typename _Tp> 1377 static true_type __test(const _Tp&, 1378 decltype(__helper<const _Tp&>({}))* = 0); 1379 1380 static false_type __test(...); 1381 }; 1382 1383 template<typename _Tp> 1384 struct __is_implicitly_default_constructible_impl 1385 : public __do_is_implicitly_default_constructible_impl 1386 { 1387 using type = decltype(__test(declval<_Tp>())); 1388 }; 1389 1390 template<typename _Tp> 1391 struct __is_implicitly_default_constructible_safe 1392 : public __is_implicitly_default_constructible_impl<_Tp>::type 1393 { }; 1394 1395 template <typename _Tp> 1396 struct __is_implicitly_default_constructible 1397 : public __and_<__is_constructible_impl<_Tp>, 1398 __is_implicitly_default_constructible_safe<_Tp>>::type 1399 { }; 1400 #endif 1401 1402 /// is_trivially_copy_constructible 1403 template<typename _Tp> 1404 struct is_trivially_copy_constructible 1405 : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>> 1406 { 1407 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1408 "template argument must be a complete class or an unbounded array"); 1409 }; 1410 1411 /// is_trivially_move_constructible 1412 template<typename _Tp> 1413 struct is_trivially_move_constructible 1414 : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>> 1415 { 1416 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1417 "template argument must be a complete class or an unbounded array"); 1418 }; 1419 1420 /// @cond undocumented 1421 template<typename _Tp, typename _Up> 1422 using __is_trivially_assignable_impl 1423 = __bool_constant<__is_trivially_assignable(_Tp, _Up)>; 1424 /// @endcond 1425 1426 /// is_trivially_assignable 1427 template<typename _Tp, typename _Up> 1428 struct is_trivially_assignable 1429 : public __is_trivially_assignable_impl<_Tp, _Up> 1430 { 1431 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1432 "template argument must be a complete class or an unbounded array"); 1433 }; 1434 1435 /// is_trivially_copy_assignable 1436 template<typename _Tp> 1437 struct is_trivially_copy_assignable 1438 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, 1439 __add_lval_ref_t<const _Tp>> 1440 { 1441 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1442 "template argument must be a complete class or an unbounded array"); 1443 }; 1444 1445 /// is_trivially_move_assignable 1446 template<typename _Tp> 1447 struct is_trivially_move_assignable 1448 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>, 1449 __add_rval_ref_t<_Tp>> 1450 { 1451 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1452 "template argument must be a complete class or an unbounded array"); 1453 }; 1454 1455 /// is_trivially_destructible 1456 template<typename _Tp> 1457 struct is_trivially_destructible 1458 : public __and_<__is_destructible_safe<_Tp>, 1459 __bool_constant<__has_trivial_destructor(_Tp)>>::type 1460 { 1461 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1462 "template argument must be a complete class or an unbounded array"); 1463 }; 1464 1465 1466 /// has_virtual_destructor 1467 template<typename _Tp> 1468 struct has_virtual_destructor 1469 : public __bool_constant<__has_virtual_destructor(_Tp)> 1470 { 1471 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1472 "template argument must be a complete class or an unbounded array"); 1473 }; 1474 1475 1476 // type property queries. 1477 1478 /// alignment_of 1479 template<typename _Tp> 1480 struct alignment_of 1481 : public integral_constant<std::size_t, alignof(_Tp)> 1482 { 1483 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 1484 "template argument must be a complete class or an unbounded array"); 1485 }; 1486 1487 /// rank 1488 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank) \ 1489 && (!defined(__clang__) || __clang_major__ >= 20) // PR118559 1490 template<typename _Tp> 1491 struct rank 1492 : public integral_constant<std::size_t, __array_rank(_Tp)> { }; 1493 #else 1494 template<typename> 1495 struct rank 1496 : public integral_constant<std::size_t, 0> { }; 1497 1498 template<typename _Tp, std::size_t _Size> 1499 struct rank<_Tp[_Size]> 1500 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 1501 1502 template<typename _Tp> 1503 struct rank<_Tp[]> 1504 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; 1505 #endif 1506 1507 /// extent 1508 template<typename, unsigned _Uint = 0> 1509 struct extent 1510 : public integral_constant<size_t, 0> { }; 1511 1512 template<typename _Tp, size_t _Size> 1513 struct extent<_Tp[_Size], 0> 1514 : public integral_constant<size_t, _Size> { }; 1515 1516 template<typename _Tp, unsigned _Uint, size_t _Size> 1517 struct extent<_Tp[_Size], _Uint> 1518 : public extent<_Tp, _Uint - 1>::type { }; 1519 1520 template<typename _Tp> 1521 struct extent<_Tp[], 0> 1522 : public integral_constant<size_t, 0> { }; 1523 1524 template<typename _Tp, unsigned _Uint> 1525 struct extent<_Tp[], _Uint> 1526 : public extent<_Tp, _Uint - 1>::type { }; 1527 1528 1529 // Type relations. 1530 1531 /// is_same 1532 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same) 1533 template<typename _Tp, typename _Up> 1534 struct is_same 1535 : public __bool_constant<__is_same(_Tp, _Up)> 1536 { }; 1537 #else 1538 template<typename _Tp, typename _Up> 1539 struct is_same 1540 : public false_type 1541 { }; 1542 1543 template<typename _Tp> 1544 struct is_same<_Tp, _Tp> 1545 : public true_type 1546 { }; 1547 #endif 1548 1549 /// is_base_of 1550 template<typename _Base, typename _Derived> 1551 struct is_base_of 1552 : public __bool_constant<__is_base_of(_Base, _Derived)> 1553 { }; 1554 1555 #ifdef __cpp_lib_is_virtual_base_of // C++ >= 26 1556 /// is_virtual_base_of 1557 /// @since C++26 1558 template<typename _Base, typename _Derived> 1559 struct is_virtual_base_of 1560 : public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)> 1561 { }; 1562 #endif 1563 1564 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) 1565 template<typename _From, typename _To> 1566 struct is_convertible 1567 : public __bool_constant<__is_convertible(_From, _To)> 1568 { }; 1569 #else 1570 template<typename _From, typename _To, 1571 bool = __or_<is_void<_From>, is_function<_To>, 1572 is_array<_To>>::value> 1573 struct __is_convertible_helper 1574 { 1575 using type = typename is_void<_To>::type; 1576 }; 1577 1578 #pragma GCC diagnostic push 1579 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" 1580 template<typename _From, typename _To> 1581 class __is_convertible_helper<_From, _To, false> 1582 { 1583 template<typename _To1> 1584 static void __test_aux(_To1) noexcept; 1585 1586 template<typename _From1, typename _To1, 1587 typename = decltype(__test_aux<_To1>(std::declval<_From1>()))> 1588 static true_type 1589 __test(int); 1590 1591 template<typename, typename> 1592 static false_type 1593 __test(...); 1594 1595 public: 1596 using type = decltype(__test<_From, _To>(0)); 1597 }; 1598 #pragma GCC diagnostic pop 1599 1600 /// is_convertible 1601 template<typename _From, typename _To> 1602 struct is_convertible 1603 : public __is_convertible_helper<_From, _To>::type 1604 { }; 1605 #endif 1606 1607 // helper trait for unique_ptr<T[]>, shared_ptr<T[]>, and span<T, N> 1608 template<typename _ToElementType, typename _FromElementType> 1609 using __is_array_convertible 1610 = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>; 1611 1612 #ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20 1613 1614 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible) 1615 /// is_nothrow_convertible_v 1616 template<typename _From, typename _To> 1617 inline constexpr bool is_nothrow_convertible_v 1618 = __is_nothrow_convertible(_From, _To); 1619 1620 /// is_nothrow_convertible 1621 template<typename _From, typename _To> 1622 struct is_nothrow_convertible 1623 : public bool_constant<is_nothrow_convertible_v<_From, _To>> 1624 { }; 1625 #else 1626 template<typename _From, typename _To, 1627 bool = __or_<is_void<_From>, is_function<_To>, 1628 is_array<_To>>::value> 1629 struct __is_nt_convertible_helper 1630 : is_void<_To> 1631 { }; 1632 1633 #pragma GCC diagnostic push 1634 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" 1635 template<typename _From, typename _To> 1636 class __is_nt_convertible_helper<_From, _To, false> 1637 { 1638 template<typename _To1> 1639 static void __test_aux(_To1) noexcept; 1640 1641 template<typename _From1, typename _To1> 1642 static 1643 __bool_constant<noexcept(__test_aux<_To1>(std::declval<_From1>()))> 1644 __test(int); 1645 1646 template<typename, typename> 1647 static false_type 1648 __test(...); 1649 1650 public: 1651 using type = decltype(__test<_From, _To>(0)); 1652 }; 1653 #pragma GCC diagnostic pop 1654 1655 /// is_nothrow_convertible 1656 template<typename _From, typename _To> 1657 struct is_nothrow_convertible 1658 : public __is_nt_convertible_helper<_From, _To>::type 1659 { }; 1660 1661 /// is_nothrow_convertible_v 1662 template<typename _From, typename _To> 1663 inline constexpr bool is_nothrow_convertible_v 1664 = is_nothrow_convertible<_From, _To>::value; 1665 #endif 1666 #endif // __cpp_lib_is_nothrow_convertible 1667 1668 #pragma GCC diagnostic push 1669 #pragma GCC diagnostic ignored "-Wc++14-extensions" // for variable templates 1670 template<typename _Tp, typename... _Args> 1671 struct __is_nothrow_new_constructible_impl 1672 : __bool_constant< 1673 noexcept(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...)) 1674 > 1675 { }; 1676 1677 template<typename _Tp, typename... _Args> 1678 _GLIBCXX17_INLINE constexpr bool __is_nothrow_new_constructible 1679 = __and_<is_constructible<_Tp, _Args...>, 1680 __is_nothrow_new_constructible_impl<_Tp, _Args...>>::value; 1681 #pragma GCC diagnostic pop 1682 1683 // Const-volatile modifications. 1684 1685 /// remove_const 1686 template<typename _Tp> 1687 struct remove_const 1688 { using type = _Tp; }; 1689 1690 template<typename _Tp> 1691 struct remove_const<_Tp const> 1692 { using type = _Tp; }; 1693 1694 /// remove_volatile 1695 template<typename _Tp> 1696 struct remove_volatile 1697 { using type = _Tp; }; 1698 1699 template<typename _Tp> 1700 struct remove_volatile<_Tp volatile> 1701 { using type = _Tp; }; 1702 1703 /// remove_cv 1704 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv) 1705 template<typename _Tp> 1706 struct remove_cv 1707 { using type = __remove_cv(_Tp); }; 1708 #else 1709 template<typename _Tp> 1710 struct remove_cv 1711 { using type = _Tp; }; 1712 1713 template<typename _Tp> 1714 struct remove_cv<const _Tp> 1715 { using type = _Tp; }; 1716 1717 template<typename _Tp> 1718 struct remove_cv<volatile _Tp> 1719 { using type = _Tp; }; 1720 1721 template<typename _Tp> 1722 struct remove_cv<const volatile _Tp> 1723 { using type = _Tp; }; 1724 #endif 1725 1726 /// add_const 1727 template<typename _Tp> 1728 struct add_const 1729 { using type = _Tp const; }; 1730 1731 /// add_volatile 1732 template<typename _Tp> 1733 struct add_volatile 1734 { using type = _Tp volatile; }; 1735 1736 /// add_cv 1737 template<typename _Tp> 1738 struct add_cv 1739 { using type = _Tp const volatile; }; 1740 1741 #ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14 1742 /// Alias template for remove_const 1743 template<typename _Tp> 1744 using remove_const_t = typename remove_const<_Tp>::type; 1745 1746 /// Alias template for remove_volatile 1747 template<typename _Tp> 1748 using remove_volatile_t = typename remove_volatile<_Tp>::type; 1749 1750 /// Alias template for remove_cv 1751 template<typename _Tp> 1752 using remove_cv_t = typename remove_cv<_Tp>::type; 1753 1754 /// Alias template for add_const 1755 template<typename _Tp> 1756 using add_const_t = typename add_const<_Tp>::type; 1757 1758 /// Alias template for add_volatile 1759 template<typename _Tp> 1760 using add_volatile_t = typename add_volatile<_Tp>::type; 1761 1762 /// Alias template for add_cv 1763 template<typename _Tp> 1764 using add_cv_t = typename add_cv<_Tp>::type; 1765 #endif 1766 1767 // Reference transformations. 1768 1769 /// remove_reference 1770 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference) 1771 template<typename _Tp> 1772 struct remove_reference 1773 { using type = __remove_reference(_Tp); }; 1774 #else 1775 template<typename _Tp> 1776 struct remove_reference 1777 { using type = _Tp; }; 1778 1779 template<typename _Tp> 1780 struct remove_reference<_Tp&> 1781 { using type = _Tp; }; 1782 1783 template<typename _Tp> 1784 struct remove_reference<_Tp&&> 1785 { using type = _Tp; }; 1786 #endif 1787 1788 /// add_lvalue_reference 1789 template<typename _Tp> 1790 struct add_lvalue_reference 1791 { using type = __add_lval_ref_t<_Tp>; }; 1792 1793 /// add_rvalue_reference 1794 template<typename _Tp> 1795 struct add_rvalue_reference 1796 { using type = __add_rval_ref_t<_Tp>; }; 1797 1798 #if __cplusplus > 201103L 1799 /// Alias template for remove_reference 1800 template<typename _Tp> 1801 using remove_reference_t = typename remove_reference<_Tp>::type; 1802 1803 /// Alias template for add_lvalue_reference 1804 template<typename _Tp> 1805 using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; 1806 1807 /// Alias template for add_rvalue_reference 1808 template<typename _Tp> 1809 using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; 1810 #endif 1811 1812 // Sign modifications. 1813 1814 /// @cond undocumented 1815 1816 // Utility for constructing identically cv-qualified types. 1817 template<typename _Unqualified, bool _IsConst, bool _IsVol> 1818 struct __cv_selector; 1819 1820 template<typename _Unqualified> 1821 struct __cv_selector<_Unqualified, false, false> 1822 { using __type = _Unqualified; }; 1823 1824 template<typename _Unqualified> 1825 struct __cv_selector<_Unqualified, false, true> 1826 { using __type = volatile _Unqualified; }; 1827 1828 template<typename _Unqualified> 1829 struct __cv_selector<_Unqualified, true, false> 1830 { using __type = const _Unqualified; }; 1831 1832 template<typename _Unqualified> 1833 struct __cv_selector<_Unqualified, true, true> 1834 { using __type = const volatile _Unqualified; }; 1835 1836 template<typename _Qualified, typename _Unqualified, 1837 bool _IsConst = is_const<_Qualified>::value, 1838 bool _IsVol = is_volatile<_Qualified>::value> 1839 class __match_cv_qualifiers 1840 { 1841 using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>; 1842 1843 public: 1844 using __type = typename __match::__type; 1845 }; 1846 1847 // Utility for finding the unsigned versions of signed integral types. 1848 template<typename _Tp> 1849 struct __make_unsigned 1850 { using __type = _Tp; }; 1851 1852 template<> 1853 struct __make_unsigned<char> 1854 { using __type = unsigned char; }; 1855 1856 template<> 1857 struct __make_unsigned<signed char> 1858 { using __type = unsigned char; }; 1859 1860 template<> 1861 struct __make_unsigned<short> 1862 { using __type = unsigned short; }; 1863 1864 template<> 1865 struct __make_unsigned<int> 1866 { using __type = unsigned int; }; 1867 1868 template<> 1869 struct __make_unsigned<long> 1870 { using __type = unsigned long; }; 1871 1872 template<> 1873 struct __make_unsigned<long long> 1874 { using __type = unsigned long long; }; 1875 1876 #if defined(__GLIBCXX_TYPE_INT_N_0) 1877 __extension__ 1878 template<> 1879 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> 1880 { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; }; 1881 #endif 1882 #if defined(__GLIBCXX_TYPE_INT_N_1) 1883 __extension__ 1884 template<> 1885 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> 1886 { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; }; 1887 #endif 1888 #if defined(__GLIBCXX_TYPE_INT_N_2) 1889 __extension__ 1890 template<> 1891 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> 1892 { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; }; 1893 #endif 1894 #if defined(__GLIBCXX_TYPE_INT_N_3) 1895 __extension__ 1896 template<> 1897 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> 1898 { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; }; 1899 #endif 1900 1901 // Select between integral and enum: not possible to be both. 1902 template<typename _Tp, 1903 bool _IsInt = is_integral<_Tp>::value, 1904 bool _IsEnum = __is_enum(_Tp)> 1905 class __make_unsigned_selector; 1906 1907 template<typename _Tp> 1908 class __make_unsigned_selector<_Tp, true, false> 1909 { 1910 using __unsigned_type 1911 = typename __make_unsigned<__remove_cv_t<_Tp>>::__type; 1912 1913 public: 1914 using __type 1915 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; 1916 }; 1917 1918 class __make_unsigned_selector_base 1919 { 1920 protected: 1921 template<typename...> struct _List { }; 1922 1923 template<typename _Tp, typename... _Up> 1924 struct _List<_Tp, _Up...> : _List<_Up...> 1925 { static constexpr size_t __size = sizeof(_Tp); }; 1926 1927 template<size_t _Sz, typename _Tp, bool = (_Sz <= _Tp::__size)> 1928 struct __select; 1929 1930 template<size_t _Sz, typename _Uint, typename... _UInts> 1931 struct __select<_Sz, _List<_Uint, _UInts...>, true> 1932 { using __type = _Uint; }; 1933 1934 template<size_t _Sz, typename _Uint, typename... _UInts> 1935 struct __select<_Sz, _List<_Uint, _UInts...>, false> 1936 : __select<_Sz, _List<_UInts...>> 1937 { }; 1938 }; 1939 1940 // Choose unsigned integer type with the smallest rank and same size as _Tp 1941 template<typename _Tp> 1942 class __make_unsigned_selector<_Tp, false, true> 1943 : __make_unsigned_selector_base 1944 { 1945 // With -fshort-enums, an enum may be as small as a char. 1946 using _UInts = _List<unsigned char, unsigned short, unsigned int, 1947 unsigned long, unsigned long long>; 1948 1949 using __unsigned_type = typename __select<sizeof(_Tp), _UInts>::__type; 1950 1951 public: 1952 using __type 1953 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; 1954 }; 1955 1956 // wchar_t, char8_t, char16_t and char32_t are integral types but are 1957 // neither signed integer types nor unsigned integer types, so must be 1958 // transformed to the unsigned integer type with the smallest rank. 1959 // Use the partial specialization for enumeration types to do that. 1960 template<> 1961 struct __make_unsigned<wchar_t> 1962 { 1963 using __type 1964 = typename __make_unsigned_selector<wchar_t, false, true>::__type; 1965 }; 1966 1967 #ifdef _GLIBCXX_USE_CHAR8_T 1968 template<> 1969 struct __make_unsigned<char8_t> 1970 { 1971 using __type 1972 = typename __make_unsigned_selector<char8_t, false, true>::__type; 1973 }; 1974 #endif 1975 1976 template<> 1977 struct __make_unsigned<char16_t> 1978 { 1979 using __type 1980 = typename __make_unsigned_selector<char16_t, false, true>::__type; 1981 }; 1982 1983 template<> 1984 struct __make_unsigned<char32_t> 1985 { 1986 using __type 1987 = typename __make_unsigned_selector<char32_t, false, true>::__type; 1988 }; 1989 /// @endcond 1990 1991 // Given an integral/enum type, return the corresponding unsigned 1992 // integer type. 1993 // Primary template. 1994 /// make_unsigned 1995 template<typename _Tp> 1996 struct make_unsigned 1997 { using type = typename __make_unsigned_selector<_Tp>::__type; }; 1998 1999 // Integral, but don't define. 2000 template<> struct make_unsigned<bool>; 2001 template<> struct make_unsigned<bool const>; 2002 template<> struct make_unsigned<bool volatile>; 2003 template<> struct make_unsigned<bool const volatile>; 2004 2005 /// @cond undocumented 2006 2007 // Utility for finding the signed versions of unsigned integral types. 2008 template<typename _Tp> 2009 struct __make_signed 2010 { using __type = _Tp; }; 2011 2012 template<> 2013 struct __make_signed<char> 2014 { using __type = signed char; }; 2015 2016 template<> 2017 struct __make_signed<unsigned char> 2018 { using __type = signed char; }; 2019 2020 template<> 2021 struct __make_signed<unsigned short> 2022 { using __type = signed short; }; 2023 2024 template<> 2025 struct __make_signed<unsigned int> 2026 { using __type = signed int; }; 2027 2028 template<> 2029 struct __make_signed<unsigned long> 2030 { using __type = signed long; }; 2031 2032 template<> 2033 struct __make_signed<unsigned long long> 2034 { using __type = signed long long; }; 2035 2036 #if defined(__GLIBCXX_TYPE_INT_N_0) 2037 __extension__ 2038 template<> 2039 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0> 2040 { using __type = __GLIBCXX_TYPE_INT_N_0; }; 2041 #endif 2042 #if defined(__GLIBCXX_TYPE_INT_N_1) 2043 __extension__ 2044 template<> 2045 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1> 2046 { using __type = __GLIBCXX_TYPE_INT_N_1; }; 2047 #endif 2048 #if defined(__GLIBCXX_TYPE_INT_N_2) 2049 __extension__ 2050 template<> 2051 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2> 2052 { using __type = __GLIBCXX_TYPE_INT_N_2; }; 2053 #endif 2054 #if defined(__GLIBCXX_TYPE_INT_N_3) 2055 __extension__ 2056 template<> 2057 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3> 2058 { using __type = __GLIBCXX_TYPE_INT_N_3; }; 2059 #endif 2060 2061 // Select between integral and enum: not possible to be both. 2062 template<typename _Tp, 2063 bool _IsInt = is_integral<_Tp>::value, 2064 bool _IsEnum = __is_enum(_Tp)> 2065 class __make_signed_selector; 2066 2067 template<typename _Tp> 2068 class __make_signed_selector<_Tp, true, false> 2069 { 2070 using __signed_type 2071 = typename __make_signed<__remove_cv_t<_Tp>>::__type; 2072 2073 public: 2074 using __type 2075 = typename __match_cv_qualifiers<_Tp, __signed_type>::__type; 2076 }; 2077 2078 // Choose signed integer type with the smallest rank and same size as _Tp 2079 template<typename _Tp> 2080 class __make_signed_selector<_Tp, false, true> 2081 { 2082 using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type; 2083 2084 public: 2085 using __type = typename __make_signed_selector<__unsigned_type>::__type; 2086 }; 2087 2088 // wchar_t, char16_t and char32_t are integral types but are neither 2089 // signed integer types nor unsigned integer types, so must be 2090 // transformed to the signed integer type with the smallest rank. 2091 // Use the partial specialization for enumeration types to do that. 2092 template<> 2093 struct __make_signed<wchar_t> 2094 { 2095 using __type 2096 = typename __make_signed_selector<wchar_t, false, true>::__type; 2097 }; 2098 2099 #if defined(_GLIBCXX_USE_CHAR8_T) 2100 template<> 2101 struct __make_signed<char8_t> 2102 { 2103 using __type 2104 = typename __make_signed_selector<char8_t, false, true>::__type; 2105 }; 2106 #endif 2107 2108 template<> 2109 struct __make_signed<char16_t> 2110 { 2111 using __type 2112 = typename __make_signed_selector<char16_t, false, true>::__type; 2113 }; 2114 2115 template<> 2116 struct __make_signed<char32_t> 2117 { 2118 using __type 2119 = typename __make_signed_selector<char32_t, false, true>::__type; 2120 }; 2121 /// @endcond 2122 2123 // Given an integral/enum type, return the corresponding signed 2124 // integer type. 2125 // Primary template. 2126 /// make_signed 2127 template<typename _Tp> 2128 struct make_signed 2129 { using type = typename __make_signed_selector<_Tp>::__type; }; 2130 2131 // Integral, but don't define. 2132 template<> struct make_signed<bool>; 2133 template<> struct make_signed<bool const>; 2134 template<> struct make_signed<bool volatile>; 2135 template<> struct make_signed<bool const volatile>; 2136 2137 #if __cplusplus > 201103L 2138 /// Alias template for make_signed 2139 template<typename _Tp> 2140 using make_signed_t = typename make_signed<_Tp>::type; 2141 2142 /// Alias template for make_unsigned 2143 template<typename _Tp> 2144 using make_unsigned_t = typename make_unsigned<_Tp>::type; 2145 #endif 2146 2147 // Array modifications. 2148 2149 /// remove_extent 2150 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent) 2151 template<typename _Tp> 2152 struct remove_extent 2153 { using type = __remove_extent(_Tp); }; 2154 #else 2155 template<typename _Tp> 2156 struct remove_extent 2157 { using type = _Tp; }; 2158 2159 template<typename _Tp, std::size_t _Size> 2160 struct remove_extent<_Tp[_Size]> 2161 { using type = _Tp; }; 2162 2163 template<typename _Tp> 2164 struct remove_extent<_Tp[]> 2165 { using type = _Tp; }; 2166 #endif 2167 2168 /// remove_all_extents 2169 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents) 2170 template<typename _Tp> 2171 struct remove_all_extents 2172 { using type = __remove_all_extents(_Tp); }; 2173 #else 2174 template<typename _Tp> 2175 struct remove_all_extents 2176 { using type = _Tp; }; 2177 2178 template<typename _Tp, std::size_t _Size> 2179 struct remove_all_extents<_Tp[_Size]> 2180 { using type = typename remove_all_extents<_Tp>::type; }; 2181 2182 template<typename _Tp> 2183 struct remove_all_extents<_Tp[]> 2184 { using type = typename remove_all_extents<_Tp>::type; }; 2185 #endif 2186 2187 #if __cplusplus > 201103L 2188 /// Alias template for remove_extent 2189 template<typename _Tp> 2190 using remove_extent_t = typename remove_extent<_Tp>::type; 2191 2192 /// Alias template for remove_all_extents 2193 template<typename _Tp> 2194 using remove_all_extents_t = typename remove_all_extents<_Tp>::type; 2195 #endif 2196 2197 // Pointer modifications. 2198 2199 /// remove_pointer 2200 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer) 2201 template<typename _Tp> 2202 struct remove_pointer 2203 { using type = __remove_pointer(_Tp); }; 2204 #else 2205 template<typename _Tp, typename> 2206 struct __remove_pointer_helper 2207 { using type = _Tp; }; 2208 2209 template<typename _Tp, typename _Up> 2210 struct __remove_pointer_helper<_Tp, _Up*> 2211 { using type = _Up; }; 2212 2213 template<typename _Tp> 2214 struct remove_pointer 2215 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>> 2216 { }; 2217 #endif 2218 2219 /// add_pointer 2220 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer) 2221 template<typename _Tp> 2222 struct add_pointer 2223 { using type = __add_pointer(_Tp); }; 2224 #else 2225 template<typename _Tp, typename = void> 2226 struct __add_pointer_helper 2227 { using type = _Tp; }; 2228 2229 template<typename _Tp> 2230 struct __add_pointer_helper<_Tp, __void_t<_Tp*>> 2231 { using type = _Tp*; }; 2232 2233 template<typename _Tp> 2234 struct add_pointer 2235 : public __add_pointer_helper<_Tp> 2236 { }; 2237 2238 template<typename _Tp> 2239 struct add_pointer<_Tp&> 2240 { using type = _Tp*; }; 2241 2242 template<typename _Tp> 2243 struct add_pointer<_Tp&&> 2244 { using type = _Tp*; }; 2245 #endif 2246 2247 #if __cplusplus > 201103L 2248 /// Alias template for remove_pointer 2249 template<typename _Tp> 2250 using remove_pointer_t = typename remove_pointer<_Tp>::type; 2251 2252 /// Alias template for add_pointer 2253 template<typename _Tp> 2254 using add_pointer_t = typename add_pointer<_Tp>::type; 2255 #endif 2256 2257 /// @cond undocumented 2258 2259 // Aligned to maximum fundamental alignment 2260 struct __attribute__((__aligned__)) __aligned_storage_max_align_t 2261 { }; 2262 2263 constexpr size_t 2264 __aligned_storage_default_alignment([[__maybe_unused__]] size_t __len) 2265 { 2266 #if _GLIBCXX_INLINE_VERSION 2267 using _Max_align 2268 = integral_constant<size_t, alignof(__aligned_storage_max_align_t)>; 2269 2270 return __len > (_Max_align::value / 2) 2271 ? _Max_align::value 2272 # if _GLIBCXX_USE_BUILTIN_TRAIT(__builtin_clzg) 2273 : 1 << (__SIZE_WIDTH__ - __builtin_clzg(__len - 1u)); 2274 # else 2275 : 1 << (__LLONG_WIDTH__ - __builtin_clzll(__len - 1ull)); 2276 # endif 2277 #else 2278 // Returning a fixed value is incorrect, but kept for ABI compatibility. 2279 // XXX GLIBCXX_ABI Deprecated 2280 return alignof(__aligned_storage_max_align_t); 2281 #endif 2282 } 2283 /// @endcond 2284 2285 /** 2286 * @brief Aligned storage 2287 * 2288 * The member typedef `type` is be a POD type suitable for use as 2289 * uninitialized storage for any object whose size is at most `_Len` 2290 * and whose alignment is a divisor of `_Align`. 2291 * 2292 * It is important to use the nested `type` as uninitialized storage, 2293 * not the `std::aligned_storage` type itself which is an empty class 2294 * with 1-byte alignment. So this is correct: 2295 * 2296 * `typename std::aligned_storage<sizeof(X), alignof(X)>::type m_xobj;` 2297 * 2298 * This is wrong: 2299 * 2300 * `std::aligned_storage<sizeof(X), alignof(X)> m_xobj;` 2301 * 2302 * In C++14 and later `std::aligned_storage_t<sizeof(X), alignof(X)>` 2303 * can be used to refer to the `type` member typedef. 2304 * 2305 * The default value of _Align is supposed to be the most stringent 2306 * fundamental alignment requirement for any C++ object type whose size 2307 * is no greater than `_Len` (see [basic.align] in the C++ standard). 2308 * 2309 * @bug In this implementation the default value for _Align is always the 2310 * maximum fundamental alignment, i.e. `alignof(max_align_t)`, which is 2311 * incorrect. It should be an alignment value no greater than `_Len`. 2312 * 2313 * @deprecated Deprecated in C++23. Uses can be replaced by an 2314 * array `std::byte[_Len]` declared with `alignas(_Align)`. 2315 */ 2316 template<size_t _Len, 2317 size_t _Align = __aligned_storage_default_alignment(_Len)> 2318 struct 2319 _GLIBCXX23_DEPRECATED 2320 aligned_storage 2321 { 2322 struct type 2323 { 2324 alignas(_Align) unsigned char __data[_Len]; 2325 }; 2326 }; 2327 2328 template <typename... _Types> 2329 struct __strictest_alignment 2330 { 2331 static const size_t _S_alignment = 0; 2332 static const size_t _S_size = 0; 2333 }; 2334 2335 template <typename _Tp, typename... _Types> 2336 struct __strictest_alignment<_Tp, _Types...> 2337 { 2338 static const size_t _S_alignment = 2339 alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment 2340 ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment; 2341 static const size_t _S_size = 2342 sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size 2343 ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; 2344 }; 2345 2346 #pragma GCC diagnostic push 2347 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 2348 2349 /** 2350 * @brief Provide aligned storage for types. 2351 * 2352 * [meta.trans.other] 2353 * 2354 * Provides aligned storage for any of the provided types of at 2355 * least size _Len. 2356 * 2357 * @see aligned_storage 2358 * 2359 * @deprecated Deprecated in C++23. 2360 */ 2361 template <size_t _Len, typename... _Types> 2362 struct 2363 _GLIBCXX23_DEPRECATED 2364 aligned_union 2365 { 2366 private: 2367 static_assert(sizeof...(_Types) != 0, "At least one type is required"); 2368 2369 using __strictest = __strictest_alignment<_Types...>; 2370 static const size_t _S_len = _Len > __strictest::_S_size 2371 ? _Len : __strictest::_S_size; 2372 public: 2373 /// The value of the strictest alignment of _Types. 2374 static const size_t alignment_value = __strictest::_S_alignment; 2375 /// The storage. 2376 using type = typename aligned_storage<_S_len, alignment_value>::type; 2377 }; 2378 2379 template <size_t _Len, typename... _Types> 2380 const size_t aligned_union<_Len, _Types...>::alignment_value; 2381 #pragma GCC diagnostic pop 2382 2383 /// @cond undocumented 2384 2385 #if _GLIBCXX_USE_BUILTIN_TRAIT(__decay) 2386 template<typename _Tp> 2387 struct decay 2388 { using type = __decay(_Tp); }; 2389 #else 2390 // Decay trait for arrays and functions, used for perfect forwarding 2391 // in make_pair, make_tuple, etc. 2392 template<typename _Up> 2393 struct __decay_selector 2394 : __conditional_t<is_const<const _Up>::value, // false for functions 2395 remove_cv<_Up>, // N.B. DR 705. 2396 add_pointer<_Up>> // function decays to pointer 2397 { }; 2398 2399 template<typename _Up, size_t _Nm> 2400 struct __decay_selector<_Up[_Nm]> 2401 { using type = _Up*; }; 2402 2403 template<typename _Up> 2404 struct __decay_selector<_Up[]> 2405 { using type = _Up*; }; 2406 2407 /// @endcond 2408 2409 /// decay 2410 template<typename _Tp> 2411 struct decay 2412 { using type = typename __decay_selector<_Tp>::type; }; 2413 2414 template<typename _Tp> 2415 struct decay<_Tp&> 2416 { using type = typename __decay_selector<_Tp>::type; }; 2417 2418 template<typename _Tp> 2419 struct decay<_Tp&&> 2420 { using type = typename __decay_selector<_Tp>::type; }; 2421 #endif 2422 2423 /// @cond undocumented 2424 2425 // Helper which adds a reference to a type when given a reference_wrapper 2426 template<typename _Tp> 2427 struct __strip_reference_wrapper 2428 { 2429 using __type = _Tp; 2430 }; 2431 2432 template<typename _Tp> 2433 struct __strip_reference_wrapper<reference_wrapper<_Tp> > 2434 { 2435 using __type = _Tp&; 2436 }; 2437 2438 // __decay_t (std::decay_t for C++11). 2439 template<typename _Tp> 2440 using __decay_t = typename decay<_Tp>::type; 2441 2442 template<typename _Tp> 2443 using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>; 2444 /// @endcond 2445 2446 /// @cond undocumented 2447 2448 // Helper for SFINAE constraints 2449 template<typename... _Cond> 2450 using _Require = __enable_if_t<__and_<_Cond...>::value>; 2451 2452 // __remove_cvref_t (std::remove_cvref_t for C++11). 2453 template<typename _Tp> 2454 using __remove_cvref_t 2455 = typename remove_cv<typename remove_reference<_Tp>::type>::type; 2456 /// @endcond 2457 2458 // Primary template. 2459 /// Define a member typedef @c type to one of two argument types. 2460 template<bool _Cond, typename _Iftrue, typename _Iffalse> 2461 struct conditional 2462 { using type = _Iftrue; }; 2463 2464 // Partial specialization for false. 2465 template<typename _Iftrue, typename _Iffalse> 2466 struct conditional<false, _Iftrue, _Iffalse> 2467 { using type = _Iffalse; }; 2468 2469 /// common_type 2470 template<typename... _Tp> 2471 struct common_type; 2472 2473 // Sfinae-friendly common_type implementation: 2474 2475 /// @cond undocumented 2476 2477 // For several sfinae-friendly trait implementations we transport both the 2478 // result information (as the member type) and the failure information (no 2479 // member type). This is very similar to std::enable_if, but we cannot use 2480 // that, because we need to derive from them as an implementation detail. 2481 2482 template<typename _Tp> 2483 struct __success_type 2484 { using type = _Tp; }; 2485 2486 struct __failure_type 2487 { }; 2488 2489 struct __do_common_type_impl 2490 { 2491 template<typename _Tp, typename _Up> 2492 using __cond_t 2493 = decltype(true ? std::declval<_Tp>() : std::declval<_Up>()); 2494 2495 // if decay_t<decltype(false ? declval<D1>() : declval<D2>())> 2496 // denotes a valid type, let C denote that type. 2497 template<typename _Tp, typename _Up> 2498 static __success_type<__decay_t<__cond_t<_Tp, _Up>>> 2499 _S_test(int); 2500 2501 #if __cplusplus > 201703L 2502 // Otherwise, if COND-RES(CREF(D1), CREF(D2)) denotes a type, 2503 // let C denote the type decay_t<COND-RES(CREF(D1), CREF(D2))>. 2504 template<typename _Tp, typename _Up> 2505 static __success_type<__remove_cvref_t<__cond_t<const _Tp&, const _Up&>>> 2506 _S_test_2(int); 2507 #endif 2508 2509 template<typename, typename> 2510 static __failure_type 2511 _S_test_2(...); 2512 2513 template<typename _Tp, typename _Up> 2514 static decltype(_S_test_2<_Tp, _Up>(0)) 2515 _S_test(...); 2516 }; 2517 2518 // If sizeof...(T) is zero, there shall be no member type. 2519 template<> 2520 struct common_type<> 2521 { }; 2522 2523 // If sizeof...(T) is one, the same type, if any, as common_type_t<T0, T0>. 2524 template<typename _Tp0> 2525 struct common_type<_Tp0> 2526 : public common_type<_Tp0, _Tp0> 2527 { }; 2528 2529 // If sizeof...(T) is two, ... 2530 template<typename _Tp1, typename _Tp2, 2531 typename _Dp1 = __decay_t<_Tp1>, typename _Dp2 = __decay_t<_Tp2>> 2532 struct __common_type_impl 2533 { 2534 // If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false, 2535 // let C denote the same type, if any, as common_type_t<D1, D2>. 2536 using type = common_type<_Dp1, _Dp2>; 2537 }; 2538 2539 template<typename _Tp1, typename _Tp2> 2540 struct __common_type_impl<_Tp1, _Tp2, _Tp1, _Tp2> 2541 : private __do_common_type_impl 2542 { 2543 // Otherwise, if decay_t<decltype(false ? declval<D1>() : declval<D2>())> 2544 // denotes a valid type, let C denote that type. 2545 using type = decltype(_S_test<_Tp1, _Tp2>(0)); 2546 }; 2547 2548 // If sizeof...(T) is two, ... 2549 template<typename _Tp1, typename _Tp2> 2550 struct common_type<_Tp1, _Tp2> 2551 : public __common_type_impl<_Tp1, _Tp2>::type 2552 { }; 2553 2554 template<typename...> 2555 struct __common_type_pack 2556 { }; 2557 2558 template<typename, typename, typename = void> 2559 struct __common_type_fold; 2560 2561 // If sizeof...(T) is greater than two, ... 2562 template<typename _Tp1, typename _Tp2, typename... _Rp> 2563 struct common_type<_Tp1, _Tp2, _Rp...> 2564 : public __common_type_fold<common_type<_Tp1, _Tp2>, 2565 __common_type_pack<_Rp...>> 2566 { }; 2567 2568 // Let C denote the same type, if any, as common_type_t<T1, T2>. 2569 // If there is such a type C, type shall denote the same type, if any, 2570 // as common_type_t<C, R...>. 2571 template<typename _CTp, typename... _Rp> 2572 struct __common_type_fold<_CTp, __common_type_pack<_Rp...>, 2573 __void_t<typename _CTp::type>> 2574 : public common_type<typename _CTp::type, _Rp...> 2575 { }; 2576 2577 // Otherwise, there shall be no member type. 2578 template<typename _CTp, typename _Rp> 2579 struct __common_type_fold<_CTp, _Rp, void> 2580 { }; 2581 2582 template<typename _Tp, bool = __is_enum(_Tp)> 2583 struct __underlying_type_impl 2584 { 2585 using type = __underlying_type(_Tp); 2586 }; 2587 2588 template<typename _Tp> 2589 struct __underlying_type_impl<_Tp, false> 2590 { }; 2591 /// @endcond 2592 2593 /// The underlying type of an enum. 2594 template<typename _Tp> 2595 struct underlying_type 2596 : public __underlying_type_impl<_Tp> 2597 { }; 2598 2599 /// @cond undocumented 2600 template<typename _Tp> 2601 struct __declval_protector 2602 { 2603 static const bool __stop = false; 2604 }; 2605 /// @endcond 2606 2607 /** Utility to simplify expressions used in unevaluated operands 2608 * @since C++11 2609 * @ingroup utilities 2610 */ 2611 template<typename _Tp> 2612 auto declval() noexcept -> decltype(__declval<_Tp>(0)) 2613 { 2614 static_assert(__declval_protector<_Tp>::__stop, 2615 "declval() must not be used!"); 2616 return __declval<_Tp>(0); 2617 } 2618 2619 /// result_of 2620 template<typename _Signature> 2621 struct result_of; 2622 2623 // Sfinae-friendly result_of implementation: 2624 2625 /// @cond undocumented 2626 struct __invoke_memfun_ref { }; 2627 struct __invoke_memfun_deref { }; 2628 struct __invoke_memobj_ref { }; 2629 struct __invoke_memobj_deref { }; 2630 struct __invoke_other { }; 2631 2632 // Associate a tag type with a specialization of __success_type. 2633 template<typename _Tp, typename _Tag> 2634 struct __result_of_success : __success_type<_Tp> 2635 { using __invoke_type = _Tag; }; 2636 2637 // [func.require] paragraph 1 bullet 1: 2638 struct __result_of_memfun_ref_impl 2639 { 2640 template<typename _Fp, typename _Tp1, typename... _Args> 2641 static __result_of_success<decltype( 2642 (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...) 2643 ), __invoke_memfun_ref> _S_test(int); 2644 2645 template<typename...> 2646 static __failure_type _S_test(...); 2647 }; 2648 2649 template<typename _MemPtr, typename _Arg, typename... _Args> 2650 struct __result_of_memfun_ref 2651 : private __result_of_memfun_ref_impl 2652 { 2653 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); 2654 }; 2655 2656 // [func.require] paragraph 1 bullet 2: 2657 struct __result_of_memfun_deref_impl 2658 { 2659 template<typename _Fp, typename _Tp1, typename... _Args> 2660 static __result_of_success<decltype( 2661 ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...) 2662 ), __invoke_memfun_deref> _S_test(int); 2663 2664 template<typename...> 2665 static __failure_type _S_test(...); 2666 }; 2667 2668 template<typename _MemPtr, typename _Arg, typename... _Args> 2669 struct __result_of_memfun_deref 2670 : private __result_of_memfun_deref_impl 2671 { 2672 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0)); 2673 }; 2674 2675 // [func.require] paragraph 1 bullet 3: 2676 struct __result_of_memobj_ref_impl 2677 { 2678 template<typename _Fp, typename _Tp1> 2679 static __result_of_success<decltype( 2680 std::declval<_Tp1>().*std::declval<_Fp>() 2681 ), __invoke_memobj_ref> _S_test(int); 2682 2683 template<typename, typename> 2684 static __failure_type _S_test(...); 2685 }; 2686 2687 template<typename _MemPtr, typename _Arg> 2688 struct __result_of_memobj_ref 2689 : private __result_of_memobj_ref_impl 2690 { 2691 using type = decltype(_S_test<_MemPtr, _Arg>(0)); 2692 }; 2693 2694 // [func.require] paragraph 1 bullet 4: 2695 struct __result_of_memobj_deref_impl 2696 { 2697 template<typename _Fp, typename _Tp1> 2698 static __result_of_success<decltype( 2699 (*std::declval<_Tp1>()).*std::declval<_Fp>() 2700 ), __invoke_memobj_deref> _S_test(int); 2701 2702 template<typename, typename> 2703 static __failure_type _S_test(...); 2704 }; 2705 2706 template<typename _MemPtr, typename _Arg> 2707 struct __result_of_memobj_deref 2708 : private __result_of_memobj_deref_impl 2709 { 2710 using type = decltype(_S_test<_MemPtr, _Arg>(0)); 2711 }; 2712 2713 template<typename _MemPtr, typename _Arg> 2714 struct __result_of_memobj; 2715 2716 template<typename _Res, typename _Class, typename _Arg> 2717 struct __result_of_memobj<_Res _Class::*, _Arg> 2718 { 2719 using _Argval = __remove_cvref_t<_Arg>; 2720 using _MemPtr = _Res _Class::*; 2721 using type = typename __conditional_t<__or_<is_same<_Argval, _Class>, 2722 is_base_of<_Class, _Argval>>::value, 2723 __result_of_memobj_ref<_MemPtr, _Arg>, 2724 __result_of_memobj_deref<_MemPtr, _Arg> 2725 >::type; 2726 }; 2727 2728 template<typename _MemPtr, typename _Arg, typename... _Args> 2729 struct __result_of_memfun; 2730 2731 template<typename _Res, typename _Class, typename _Arg, typename... _Args> 2732 struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> 2733 { 2734 using _Argval = typename remove_reference<_Arg>::type; 2735 using _MemPtr = _Res _Class::*; 2736 using type = typename __conditional_t<is_base_of<_Class, _Argval>::value, 2737 __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, 2738 __result_of_memfun_deref<_MemPtr, _Arg, _Args...> 2739 >::type; 2740 }; 2741 2742 // _GLIBCXX_RESOLVE_LIB_DEFECTS 2743 // 2219. INVOKE-ing a pointer to member with a reference_wrapper 2744 // as the object expression 2745 2746 // Used by result_of, invoke etc. to unwrap a reference_wrapper. 2747 template<typename _Tp, typename _Up = __remove_cvref_t<_Tp>> 2748 struct __inv_unwrap 2749 { 2750 using type = _Tp; 2751 }; 2752 2753 template<typename _Tp, typename _Up> 2754 struct __inv_unwrap<_Tp, reference_wrapper<_Up>> 2755 { 2756 using type = _Up&; 2757 }; 2758 2759 template<bool, bool, typename _Functor, typename... _ArgTypes> 2760 struct __result_of_impl 2761 { 2762 using type = __failure_type; 2763 }; 2764 2765 template<typename _MemPtr, typename _Arg> 2766 struct __result_of_impl<true, false, _MemPtr, _Arg> 2767 : public __result_of_memobj<__decay_t<_MemPtr>, 2768 typename __inv_unwrap<_Arg>::type> 2769 { }; 2770 2771 template<typename _MemPtr, typename _Arg, typename... _Args> 2772 struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...> 2773 : public __result_of_memfun<__decay_t<_MemPtr>, 2774 typename __inv_unwrap<_Arg>::type, _Args...> 2775 { }; 2776 2777 // [func.require] paragraph 1 bullet 5: 2778 struct __result_of_other_impl 2779 { 2780 template<typename _Fn, typename... _Args> 2781 static __result_of_success<decltype( 2782 std::declval<_Fn>()(std::declval<_Args>()...) 2783 ), __invoke_other> _S_test(int); 2784 2785 template<typename...> 2786 static __failure_type _S_test(...); 2787 }; 2788 2789 template<typename _Functor, typename... _ArgTypes> 2790 struct __result_of_impl<false, false, _Functor, _ArgTypes...> 2791 : private __result_of_other_impl 2792 { 2793 using type = decltype(_S_test<_Functor, _ArgTypes...>(0)); 2794 }; 2795 2796 // __invoke_result (std::invoke_result for C++11) 2797 template<typename _Functor, typename... _ArgTypes> 2798 struct __invoke_result 2799 : public __result_of_impl< 2800 is_member_object_pointer< 2801 typename remove_reference<_Functor>::type 2802 >::value, 2803 is_member_function_pointer< 2804 typename remove_reference<_Functor>::type 2805 >::value, 2806 _Functor, _ArgTypes... 2807 >::type 2808 { }; 2809 2810 // __invoke_result_t (std::invoke_result_t for C++11) 2811 template<typename _Fn, typename... _Args> 2812 using __invoke_result_t = typename __invoke_result<_Fn, _Args...>::type; 2813 /// @endcond 2814 2815 template<typename _Functor, typename... _ArgTypes> 2816 struct result_of<_Functor(_ArgTypes...)> 2817 : public __invoke_result<_Functor, _ArgTypes...> 2818 { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result"); 2819 2820 #if __cplusplus >= 201402L 2821 #pragma GCC diagnostic push 2822 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 2823 /// Alias template for aligned_storage 2824 template<size_t _Len, 2825 size_t _Align = __aligned_storage_default_alignment(_Len)> 2826 using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type; 2827 2828 template <size_t _Len, typename... _Types> 2829 using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type; 2830 #pragma GCC diagnostic pop 2831 2832 /// Alias template for decay 2833 template<typename _Tp> 2834 using decay_t = typename decay<_Tp>::type; 2835 2836 /// Alias template for enable_if 2837 template<bool _Cond, typename _Tp = void> 2838 using enable_if_t = typename enable_if<_Cond, _Tp>::type; 2839 2840 /// Alias template for conditional 2841 template<bool _Cond, typename _Iftrue, typename _Iffalse> 2842 using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type; 2843 2844 /// Alias template for common_type 2845 template<typename... _Tp> 2846 using common_type_t = typename common_type<_Tp...>::type; 2847 2848 /// Alias template for underlying_type 2849 template<typename _Tp> 2850 using underlying_type_t = typename underlying_type<_Tp>::type; 2851 2852 /// Alias template for result_of 2853 template<typename _Tp> 2854 using result_of_t = typename result_of<_Tp>::type; 2855 #endif // C++14 2856 2857 #ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11 2858 /// A metafunction that always yields void, used for detecting valid types. 2859 template<typename...> using void_t = void; 2860 #endif 2861 2862 /// @cond undocumented 2863 2864 // Detection idiom. 2865 // Detect whether _Op<_Args...> is a valid type, use default _Def if not. 2866 2867 #if __cpp_concepts 2868 // Implementation of the detection idiom (negative case). 2869 template<typename _Def, template<typename...> class _Op, typename... _Args> 2870 struct __detected_or 2871 { 2872 using type = _Def; 2873 using __is_detected = false_type; 2874 }; 2875 2876 // Implementation of the detection idiom (positive case). 2877 template<typename _Def, template<typename...> class _Op, typename... _Args> 2878 requires requires { typename _Op<_Args...>; } 2879 struct __detected_or<_Def, _Op, _Args...> 2880 { 2881 using type = _Op<_Args...>; 2882 using __is_detected = true_type; 2883 }; 2884 #else 2885 /// Implementation of the detection idiom (negative case). 2886 template<typename _Default, typename _AlwaysVoid, 2887 template<typename...> class _Op, typename... _Args> 2888 struct __detector 2889 { 2890 using type = _Default; 2891 using __is_detected = false_type; 2892 }; 2893 2894 /// Implementation of the detection idiom (positive case). 2895 template<typename _Default, template<typename...> class _Op, 2896 typename... _Args> 2897 struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> 2898 { 2899 using type = _Op<_Args...>; 2900 using __is_detected = true_type; 2901 }; 2902 2903 template<typename _Default, template<typename...> class _Op, 2904 typename... _Args> 2905 using __detected_or = __detector<_Default, void, _Op, _Args...>; 2906 #endif // __cpp_concepts 2907 2908 // _Op<_Args...> if that is a valid type, otherwise _Default. 2909 template<typename _Default, template<typename...> class _Op, 2910 typename... _Args> 2911 using __detected_or_t 2912 = typename __detected_or<_Default, _Op, _Args...>::type; 2913 2914 /** 2915 * Use SFINAE to determine if the type _Tp has a publicly-accessible 2916 * member type _NTYPE. 2917 */ 2918 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ 2919 template<typename _Tp, typename = __void_t<>> \ 2920 struct __has_##_NTYPE \ 2921 : false_type \ 2922 { }; \ 2923 template<typename _Tp> \ 2924 struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \ 2925 : true_type \ 2926 { }; 2927 2928 template <typename _Tp> 2929 struct __is_swappable; 2930 2931 template <typename _Tp> 2932 struct __is_nothrow_swappable; 2933 2934 template<typename> 2935 struct __is_tuple_like_impl : false_type 2936 { }; 2937 2938 // Internal type trait that allows us to sfinae-protect tuple_cat. 2939 template<typename _Tp> 2940 struct __is_tuple_like 2941 : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type 2942 { }; 2943 /// @endcond 2944 2945 template<typename _Tp> 2946 _GLIBCXX20_CONSTEXPR 2947 inline 2948 _Require<__not_<__is_tuple_like<_Tp>>, 2949 is_move_constructible<_Tp>, 2950 is_move_assignable<_Tp>> 2951 swap(_Tp&, _Tp&) 2952 noexcept(__and_<is_nothrow_move_constructible<_Tp>, 2953 is_nothrow_move_assignable<_Tp>>::value); 2954 2955 template<typename _Tp, size_t _Nm> 2956 _GLIBCXX20_CONSTEXPR 2957 inline 2958 __enable_if_t<__is_swappable<_Tp>::value> 2959 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) 2960 noexcept(__is_nothrow_swappable<_Tp>::value); 2961 2962 /// @cond undocumented 2963 namespace __swappable_details { 2964 using std::swap; 2965 2966 struct __do_is_swappable_impl 2967 { 2968 template<typename _Tp, typename 2969 = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))> 2970 static true_type __test(int); 2971 2972 template<typename> 2973 static false_type __test(...); 2974 }; 2975 2976 struct __do_is_nothrow_swappable_impl 2977 { 2978 template<typename _Tp> 2979 static __bool_constant< 2980 noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())) 2981 > __test(int); 2982 2983 template<typename> 2984 static false_type __test(...); 2985 }; 2986 2987 } // namespace __swappable_details 2988 2989 template<typename _Tp> 2990 struct __is_swappable_impl 2991 : public __swappable_details::__do_is_swappable_impl 2992 { 2993 using type = decltype(__test<_Tp>(0)); 2994 }; 2995 2996 template<typename _Tp> 2997 struct __is_nothrow_swappable_impl 2998 : public __swappable_details::__do_is_nothrow_swappable_impl 2999 { 3000 using type = decltype(__test<_Tp>(0)); 3001 }; 3002 3003 template<typename _Tp> 3004 struct __is_swappable 3005 : public __is_swappable_impl<_Tp>::type 3006 { }; 3007 3008 template<typename _Tp> 3009 struct __is_nothrow_swappable 3010 : public __is_nothrow_swappable_impl<_Tp>::type 3011 { }; 3012 /// @endcond 3013 3014 #ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11 3015 /// Metafunctions used for detecting swappable types: p0185r1 3016 3017 /// is_swappable 3018 template<typename _Tp> 3019 struct is_swappable 3020 : public __is_swappable_impl<_Tp>::type 3021 { 3022 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 3023 "template argument must be a complete class or an unbounded array"); 3024 }; 3025 3026 /// is_nothrow_swappable 3027 template<typename _Tp> 3028 struct is_nothrow_swappable 3029 : public __is_nothrow_swappable_impl<_Tp>::type 3030 { 3031 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 3032 "template argument must be a complete class or an unbounded array"); 3033 }; 3034 3035 #if __cplusplus >= 201402L 3036 /// is_swappable_v 3037 template<typename _Tp> 3038 _GLIBCXX17_INLINE constexpr bool is_swappable_v = 3039 is_swappable<_Tp>::value; 3040 3041 /// is_nothrow_swappable_v 3042 template<typename _Tp> 3043 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v = 3044 is_nothrow_swappable<_Tp>::value; 3045 #endif // __cplusplus >= 201402L 3046 3047 /// @cond undocumented 3048 namespace __swappable_with_details { 3049 using std::swap; 3050 3051 struct __do_is_swappable_with_impl 3052 { 3053 template<typename _Tp, typename _Up, typename 3054 = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())), 3055 typename 3056 = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))> 3057 static true_type __test(int); 3058 3059 template<typename, typename> 3060 static false_type __test(...); 3061 }; 3062 3063 struct __do_is_nothrow_swappable_with_impl 3064 { 3065 template<typename _Tp, typename _Up> 3066 static __bool_constant< 3067 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())) 3068 && 3069 noexcept(swap(std::declval<_Up>(), std::declval<_Tp>())) 3070 > __test(int); 3071 3072 template<typename, typename> 3073 static false_type __test(...); 3074 }; 3075 3076 } // namespace __swappable_with_details 3077 3078 template<typename _Tp, typename _Up> 3079 struct __is_swappable_with_impl 3080 : public __swappable_with_details::__do_is_swappable_with_impl 3081 { 3082 using type = decltype(__test<_Tp, _Up>(0)); 3083 }; 3084 3085 // Optimization for the homogenous lvalue case, not required: 3086 template<typename _Tp> 3087 struct __is_swappable_with_impl<_Tp&, _Tp&> 3088 : public __swappable_details::__do_is_swappable_impl 3089 { 3090 using type = decltype(__test<_Tp&>(0)); 3091 }; 3092 3093 template<typename _Tp, typename _Up> 3094 struct __is_nothrow_swappable_with_impl 3095 : public __swappable_with_details::__do_is_nothrow_swappable_with_impl 3096 { 3097 using type = decltype(__test<_Tp, _Up>(0)); 3098 }; 3099 3100 // Optimization for the homogenous lvalue case, not required: 3101 template<typename _Tp> 3102 struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> 3103 : public __swappable_details::__do_is_nothrow_swappable_impl 3104 { 3105 using type = decltype(__test<_Tp&>(0)); 3106 }; 3107 /// @endcond 3108 3109 /// is_swappable_with 3110 template<typename _Tp, typename _Up> 3111 struct is_swappable_with 3112 : public __is_swappable_with_impl<_Tp, _Up>::type 3113 { 3114 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 3115 "first template argument must be a complete class or an unbounded array"); 3116 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), 3117 "second template argument must be a complete class or an unbounded array"); 3118 }; 3119 3120 /// is_nothrow_swappable_with 3121 template<typename _Tp, typename _Up> 3122 struct is_nothrow_swappable_with 3123 : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type 3124 { 3125 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 3126 "first template argument must be a complete class or an unbounded array"); 3127 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}), 3128 "second template argument must be a complete class or an unbounded array"); 3129 }; 3130 3131 #if __cplusplus >= 201402L 3132 /// is_swappable_with_v 3133 template<typename _Tp, typename _Up> 3134 _GLIBCXX17_INLINE constexpr bool is_swappable_with_v = 3135 is_swappable_with<_Tp, _Up>::value; 3136 3137 /// is_nothrow_swappable_with_v 3138 template<typename _Tp, typename _Up> 3139 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v = 3140 is_nothrow_swappable_with<_Tp, _Up>::value; 3141 #endif // __cplusplus >= 201402L 3142 3143 #endif // __cpp_lib_is_swappable 3144 3145 /// @cond undocumented 3146 3147 // __is_invocable (std::is_invocable for C++11) 3148 3149 // The primary template is used for invalid INVOKE expressions. 3150 template<typename _Result, typename _Ret, 3151 bool = is_void<_Ret>::value, typename = void> 3152 struct __is_invocable_impl 3153 : false_type 3154 { 3155 using __nothrow_conv = false_type; // For is_nothrow_invocable_r 3156 }; 3157 3158 // Used for valid INVOKE and INVOKE<void> expressions. 3159 template<typename _Result, typename _Ret> 3160 struct __is_invocable_impl<_Result, _Ret, 3161 /* is_void<_Ret> = */ true, 3162 __void_t<typename _Result::type>> 3163 : true_type 3164 { 3165 using __nothrow_conv = true_type; // For is_nothrow_invocable_r 3166 }; 3167 3168 #pragma GCC diagnostic push 3169 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" 3170 // Used for INVOKE<R> expressions to check the implicit conversion to R. 3171 template<typename _Result, typename _Ret> 3172 struct __is_invocable_impl<_Result, _Ret, 3173 /* is_void<_Ret> = */ false, 3174 __void_t<typename _Result::type>> 3175 { 3176 private: 3177 // The type of the INVOKE expression. 3178 using _Res_t = typename _Result::type; 3179 3180 // Unlike declval, this doesn't add_rvalue_reference, so it respects 3181 // guaranteed copy elision. 3182 static _Res_t _S_get() noexcept; 3183 3184 // Used to check if _Res_t can implicitly convert to _Tp. 3185 template<typename _Tp> 3186 static void _S_conv(__type_identity_t<_Tp>) noexcept; 3187 3188 // This overload is viable if INVOKE(f, args...) can convert to _Tp. 3189 template<typename _Tp, 3190 bool _Nothrow = noexcept(_S_conv<_Tp>(_S_get())), 3191 typename = decltype(_S_conv<_Tp>(_S_get())), 3192 #if __has_builtin(__reference_converts_from_temporary) 3193 bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t) 3194 #else 3195 bool _Dangle = false 3196 #endif 3197 > 3198 static __bool_constant<_Nothrow && !_Dangle> 3199 _S_test(int); 3200 3201 template<typename _Tp, bool = false> 3202 static false_type 3203 _S_test(...); 3204 3205 public: 3206 // For is_invocable_r 3207 using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1)); 3208 3209 // For is_nothrow_invocable_r 3210 using __nothrow_conv = decltype(_S_test<_Ret>(1)); 3211 }; 3212 #pragma GCC diagnostic pop 3213 3214 template<typename _Fn, typename... _ArgTypes> 3215 struct __is_invocable 3216 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type 3217 { }; 3218 3219 template<typename _Fn, typename _Tp, typename... _Args> 3220 constexpr bool __call_is_nt(__invoke_memfun_ref) 3221 { 3222 using _Up = typename __inv_unwrap<_Tp>::type; 3223 return noexcept((std::declval<_Up>().*std::declval<_Fn>())( 3224 std::declval<_Args>()...)); 3225 } 3226 3227 template<typename _Fn, typename _Tp, typename... _Args> 3228 constexpr bool __call_is_nt(__invoke_memfun_deref) 3229 { 3230 return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())( 3231 std::declval<_Args>()...)); 3232 } 3233 3234 template<typename _Fn, typename _Tp> 3235 constexpr bool __call_is_nt(__invoke_memobj_ref) 3236 { 3237 using _Up = typename __inv_unwrap<_Tp>::type; 3238 return noexcept(std::declval<_Up>().*std::declval<_Fn>()); 3239 } 3240 3241 template<typename _Fn, typename _Tp> 3242 constexpr bool __call_is_nt(__invoke_memobj_deref) 3243 { 3244 return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>()); 3245 } 3246 3247 template<typename _Fn, typename... _Args> 3248 constexpr bool __call_is_nt(__invoke_other) 3249 { 3250 return noexcept(std::declval<_Fn>()(std::declval<_Args>()...)); 3251 } 3252 3253 template<typename _Result, typename _Fn, typename... _Args> 3254 struct __call_is_nothrow 3255 : __bool_constant< 3256 std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{}) 3257 > 3258 { }; 3259 3260 template<typename _Fn, typename... _Args> 3261 using __call_is_nothrow_ 3262 = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>; 3263 3264 // __is_nothrow_invocable (std::is_nothrow_invocable for C++11) 3265 template<typename _Fn, typename... _Args> 3266 struct __is_nothrow_invocable 3267 : __and_<__is_invocable<_Fn, _Args...>, 3268 __call_is_nothrow_<_Fn, _Args...>>::type 3269 { }; 3270 3271 #pragma GCC diagnostic push 3272 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" 3273 struct __nonesuchbase {}; 3274 struct __nonesuch : private __nonesuchbase { 3275 ~__nonesuch() = delete; 3276 __nonesuch(__nonesuch const&) = delete; 3277 void operator=(__nonesuch const&) = delete; 3278 }; 3279 #pragma GCC diagnostic pop 3280 /// @endcond 3281 3282 #ifdef __cpp_lib_is_invocable // C++ >= 17 3283 /// std::invoke_result 3284 template<typename _Functor, typename... _ArgTypes> 3285 struct invoke_result 3286 : public __invoke_result<_Functor, _ArgTypes...> 3287 { 3288 static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}), 3289 "_Functor must be a complete class or an unbounded array"); 3290 static_assert((std::__is_complete_or_unbounded( 3291 __type_identity<_ArgTypes>{}) && ...), 3292 "each argument type must be a complete class or an unbounded array"); 3293 }; 3294 3295 /// std::invoke_result_t 3296 template<typename _Fn, typename... _Args> 3297 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; 3298 3299 /// std::is_invocable 3300 template<typename _Fn, typename... _ArgTypes> 3301 struct is_invocable 3302 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable) 3303 : public __bool_constant<__is_invocable(_Fn, _ArgTypes...)> 3304 #else 3305 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type 3306 #endif 3307 { 3308 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), 3309 "_Fn must be a complete class or an unbounded array"); 3310 static_assert((std::__is_complete_or_unbounded( 3311 __type_identity<_ArgTypes>{}) && ...), 3312 "each argument type must be a complete class or an unbounded array"); 3313 }; 3314 3315 /// std::is_invocable_r 3316 template<typename _Ret, typename _Fn, typename... _ArgTypes> 3317 struct is_invocable_r 3318 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type 3319 { 3320 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), 3321 "_Fn must be a complete class or an unbounded array"); 3322 static_assert((std::__is_complete_or_unbounded( 3323 __type_identity<_ArgTypes>{}) && ...), 3324 "each argument type must be a complete class or an unbounded array"); 3325 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), 3326 "_Ret must be a complete class or an unbounded array"); 3327 }; 3328 3329 /// std::is_nothrow_invocable 3330 template<typename _Fn, typename... _ArgTypes> 3331 struct is_nothrow_invocable 3332 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable) 3333 : public __bool_constant<__is_nothrow_invocable(_Fn, _ArgTypes...)> 3334 #else 3335 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>, 3336 __call_is_nothrow_<_Fn, _ArgTypes...>>::type 3337 #endif 3338 { 3339 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), 3340 "_Fn must be a complete class or an unbounded array"); 3341 static_assert((std::__is_complete_or_unbounded( 3342 __type_identity<_ArgTypes>{}) && ...), 3343 "each argument type must be a complete class or an unbounded array"); 3344 }; 3345 3346 /// @cond undocumented 3347 // This checks that the INVOKE<R> expression is well-formed and that the 3348 // conversion to R does not throw. It does *not* check whether the INVOKE 3349 // expression itself can throw. That is done by __call_is_nothrow_ instead. 3350 template<typename _Result, typename _Ret> 3351 using __is_nt_invocable_impl 3352 = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv; 3353 /// @endcond 3354 3355 /// std::is_nothrow_invocable_r 3356 template<typename _Ret, typename _Fn, typename... _ArgTypes> 3357 struct is_nothrow_invocable_r 3358 : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, 3359 __call_is_nothrow_<_Fn, _ArgTypes...>>::type 3360 { 3361 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}), 3362 "_Fn must be a complete class or an unbounded array"); 3363 static_assert((std::__is_complete_or_unbounded( 3364 __type_identity<_ArgTypes>{}) && ...), 3365 "each argument type must be a complete class or an unbounded array"); 3366 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}), 3367 "_Ret must be a complete class or an unbounded array"); 3368 }; 3369 #endif // __cpp_lib_is_invocable 3370 3371 #if __cpp_lib_type_trait_variable_templates // C++ >= 17 3372 /** 3373 * @defgroup variable_templates Variable templates for type traits 3374 * @ingroup metaprogramming 3375 * 3376 * Each variable `is_xxx_v<T>` is a boolean constant with the same value 3377 * as the `value` member of the corresponding type trait `is_xxx<T>`. 3378 * 3379 * @since C++17 unless noted otherwise. 3380 */ 3381 3382 /** 3383 * @{ 3384 * @ingroup variable_templates 3385 */ 3386 template <typename _Tp> 3387 inline constexpr bool is_void_v = is_void<_Tp>::value; 3388 template <typename _Tp> 3389 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value; 3390 template <typename _Tp> 3391 inline constexpr bool is_integral_v = is_integral<_Tp>::value; 3392 template <typename _Tp> 3393 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; 3394 3395 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array) 3396 template <typename _Tp> 3397 inline constexpr bool is_array_v = __is_array(_Tp); 3398 #else 3399 template <typename _Tp> 3400 inline constexpr bool is_array_v = false; 3401 template <typename _Tp> 3402 inline constexpr bool is_array_v<_Tp[]> = true; 3403 template <typename _Tp, size_t _Num> 3404 inline constexpr bool is_array_v<_Tp[_Num]> = true; 3405 #endif 3406 3407 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer) 3408 template <typename _Tp> 3409 inline constexpr bool is_pointer_v = __is_pointer(_Tp); 3410 #else 3411 template <typename _Tp> 3412 inline constexpr bool is_pointer_v = false; 3413 template <typename _Tp> 3414 inline constexpr bool is_pointer_v<_Tp*> = true; 3415 template <typename _Tp> 3416 inline constexpr bool is_pointer_v<_Tp* const> = true; 3417 template <typename _Tp> 3418 inline constexpr bool is_pointer_v<_Tp* volatile> = true; 3419 template <typename _Tp> 3420 inline constexpr bool is_pointer_v<_Tp* const volatile> = true; 3421 #endif 3422 3423 template <typename _Tp> 3424 inline constexpr bool is_lvalue_reference_v = false; 3425 template <typename _Tp> 3426 inline constexpr bool is_lvalue_reference_v<_Tp&> = true; 3427 template <typename _Tp> 3428 inline constexpr bool is_rvalue_reference_v = false; 3429 template <typename _Tp> 3430 inline constexpr bool is_rvalue_reference_v<_Tp&&> = true; 3431 3432 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer) 3433 template <typename _Tp> 3434 inline constexpr bool is_member_object_pointer_v = 3435 __is_member_object_pointer(_Tp); 3436 #else 3437 template <typename _Tp> 3438 inline constexpr bool is_member_object_pointer_v = 3439 is_member_object_pointer<_Tp>::value; 3440 #endif 3441 3442 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer) 3443 template <typename _Tp> 3444 inline constexpr bool is_member_function_pointer_v = 3445 __is_member_function_pointer(_Tp); 3446 #else 3447 template <typename _Tp> 3448 inline constexpr bool is_member_function_pointer_v = 3449 is_member_function_pointer<_Tp>::value; 3450 #endif 3451 3452 template <typename _Tp> 3453 inline constexpr bool is_enum_v = __is_enum(_Tp); 3454 template <typename _Tp> 3455 inline constexpr bool is_union_v = __is_union(_Tp); 3456 template <typename _Tp> 3457 inline constexpr bool is_class_v = __is_class(_Tp); 3458 // is_function_v is defined below, after is_const_v. 3459 3460 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference) 3461 template <typename _Tp> 3462 inline constexpr bool is_reference_v = __is_reference(_Tp); 3463 #else 3464 template <typename _Tp> 3465 inline constexpr bool is_reference_v = false; 3466 template <typename _Tp> 3467 inline constexpr bool is_reference_v<_Tp&> = true; 3468 template <typename _Tp> 3469 inline constexpr bool is_reference_v<_Tp&&> = true; 3470 #endif 3471 3472 template <typename _Tp> 3473 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; 3474 template <typename _Tp> 3475 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; 3476 3477 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object) 3478 template <typename _Tp> 3479 inline constexpr bool is_object_v = __is_object(_Tp); 3480 #else 3481 template <typename _Tp> 3482 inline constexpr bool is_object_v = is_object<_Tp>::value; 3483 #endif 3484 3485 template <typename _Tp> 3486 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; 3487 template <typename _Tp> 3488 inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>; 3489 3490 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer) 3491 template <typename _Tp> 3492 inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); 3493 #else 3494 template <typename _Tp> 3495 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; 3496 #endif 3497 3498 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const) 3499 template <typename _Tp> 3500 inline constexpr bool is_const_v = __is_const(_Tp); 3501 #else 3502 template <typename _Tp> 3503 inline constexpr bool is_const_v = false; 3504 template <typename _Tp> 3505 inline constexpr bool is_const_v<const _Tp> = true; 3506 #endif 3507 3508 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function) 3509 template <typename _Tp> 3510 inline constexpr bool is_function_v = __is_function(_Tp); 3511 #else 3512 template <typename _Tp> 3513 inline constexpr bool is_function_v = !is_const_v<const _Tp>; 3514 template <typename _Tp> 3515 inline constexpr bool is_function_v<_Tp&> = false; 3516 template <typename _Tp> 3517 inline constexpr bool is_function_v<_Tp&&> = false; 3518 #endif 3519 3520 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile) 3521 template <typename _Tp> 3522 inline constexpr bool is_volatile_v = __is_volatile(_Tp); 3523 #else 3524 template <typename _Tp> 3525 inline constexpr bool is_volatile_v = false; 3526 template <typename _Tp> 3527 inline constexpr bool is_volatile_v<volatile _Tp> = true; 3528 #endif 3529 3530 template <typename _Tp> 3531 _GLIBCXX26_DEPRECATED_SUGGEST("is_trivially_default_constructible_v && is_trivially_copyable_v") 3532 inline constexpr bool is_trivial_v = __is_trivial(_Tp); 3533 template <typename _Tp> 3534 inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); 3535 template <typename _Tp> 3536 inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); 3537 template <typename _Tp> 3538 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v") 3539 inline constexpr bool is_pod_v = __is_pod(_Tp); 3540 template <typename _Tp> 3541 _GLIBCXX17_DEPRECATED 3542 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); 3543 template <typename _Tp> 3544 inline constexpr bool is_empty_v = __is_empty(_Tp); 3545 template <typename _Tp> 3546 inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); 3547 template <typename _Tp> 3548 inline constexpr bool is_abstract_v = __is_abstract(_Tp); 3549 template <typename _Tp> 3550 inline constexpr bool is_final_v = __is_final(_Tp); 3551 3552 template <typename _Tp> 3553 inline constexpr bool is_signed_v = is_signed<_Tp>::value; 3554 template <typename _Tp> 3555 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; 3556 3557 template <typename _Tp, typename... _Args> 3558 inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); 3559 template <typename _Tp> 3560 inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); 3561 template <typename _Tp> 3562 inline constexpr bool is_copy_constructible_v 3563 = __is_constructible(_Tp, __add_lval_ref_t<const _Tp>); 3564 template <typename _Tp> 3565 inline constexpr bool is_move_constructible_v 3566 = __is_constructible(_Tp, __add_rval_ref_t<_Tp>); 3567 3568 template <typename _Tp, typename _Up> 3569 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up); 3570 template <typename _Tp> 3571 inline constexpr bool is_copy_assignable_v 3572 = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t<const _Tp>); 3573 template <typename _Tp> 3574 inline constexpr bool is_move_assignable_v 3575 = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); 3576 3577 template <typename _Tp> 3578 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; 3579 3580 template <typename _Tp, typename... _Args> 3581 inline constexpr bool is_trivially_constructible_v 3582 = __is_trivially_constructible(_Tp, _Args...); 3583 template <typename _Tp> 3584 inline constexpr bool is_trivially_default_constructible_v 3585 = __is_trivially_constructible(_Tp); 3586 template <typename _Tp> 3587 inline constexpr bool is_trivially_copy_constructible_v 3588 = __is_trivially_constructible(_Tp, __add_lval_ref_t<const _Tp>); 3589 template <typename _Tp> 3590 inline constexpr bool is_trivially_move_constructible_v 3591 = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>); 3592 3593 template <typename _Tp, typename _Up> 3594 inline constexpr bool is_trivially_assignable_v 3595 = __is_trivially_assignable(_Tp, _Up); 3596 template <typename _Tp> 3597 inline constexpr bool is_trivially_copy_assignable_v 3598 = __is_trivially_assignable(__add_lval_ref_t<_Tp>, 3599 __add_lval_ref_t<const _Tp>); 3600 template <typename _Tp> 3601 inline constexpr bool is_trivially_move_assignable_v 3602 = __is_trivially_assignable(__add_lval_ref_t<_Tp>, 3603 __add_rval_ref_t<_Tp>); 3604 3605 #if __cpp_concepts 3606 template <typename _Tp> 3607 inline constexpr bool is_trivially_destructible_v = false; 3608 3609 template <typename _Tp> 3610 requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); } 3611 inline constexpr bool is_trivially_destructible_v<_Tp> 3612 = __has_trivial_destructor(_Tp); 3613 template <typename _Tp> 3614 inline constexpr bool is_trivially_destructible_v<_Tp&> = true; 3615 template <typename _Tp> 3616 inline constexpr bool is_trivially_destructible_v<_Tp&&> = true; 3617 template <typename _Tp, size_t _Nm> 3618 inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]> 3619 = is_trivially_destructible_v<_Tp>; 3620 #else 3621 template <typename _Tp> 3622 inline constexpr bool is_trivially_destructible_v = 3623 is_trivially_destructible<_Tp>::value; 3624 #endif 3625 3626 template <typename _Tp, typename... _Args> 3627 inline constexpr bool is_nothrow_constructible_v 3628 = __is_nothrow_constructible(_Tp, _Args...); 3629 template <typename _Tp> 3630 inline constexpr bool is_nothrow_default_constructible_v 3631 = __is_nothrow_constructible(_Tp); 3632 template <typename _Tp> 3633 inline constexpr bool is_nothrow_copy_constructible_v 3634 = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>); 3635 template <typename _Tp> 3636 inline constexpr bool is_nothrow_move_constructible_v 3637 = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>); 3638 3639 template <typename _Tp, typename _Up> 3640 inline constexpr bool is_nothrow_assignable_v 3641 = __is_nothrow_assignable(_Tp, _Up); 3642 template <typename _Tp> 3643 inline constexpr bool is_nothrow_copy_assignable_v 3644 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, 3645 __add_lval_ref_t<const _Tp>); 3646 template <typename _Tp> 3647 inline constexpr bool is_nothrow_move_assignable_v 3648 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>); 3649 3650 template <typename _Tp> 3651 inline constexpr bool is_nothrow_destructible_v = 3652 is_nothrow_destructible<_Tp>::value; 3653 3654 template <typename _Tp> 3655 inline constexpr bool has_virtual_destructor_v 3656 = __has_virtual_destructor(_Tp); 3657 3658 template <typename _Tp> 3659 inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; 3660 3661 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank) \ 3662 && (!defined(__clang__) || __clang_major__ >= 20) // PR118559 3663 template <typename _Tp> 3664 inline constexpr size_t rank_v = __array_rank(_Tp); 3665 #else 3666 template <typename _Tp> 3667 inline constexpr size_t rank_v = 0; 3668 template <typename _Tp, size_t _Size> 3669 inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>; 3670 template <typename _Tp> 3671 inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>; 3672 #endif 3673 3674 template <typename _Tp, unsigned _Idx = 0> 3675 inline constexpr size_t extent_v = 0; 3676 template <typename _Tp, size_t _Size> 3677 inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size; 3678 template <typename _Tp, unsigned _Idx, size_t _Size> 3679 inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>; 3680 template <typename _Tp> 3681 inline constexpr size_t extent_v<_Tp[], 0> = 0; 3682 template <typename _Tp, unsigned _Idx> 3683 inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>; 3684 3685 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same) 3686 template <typename _Tp, typename _Up> 3687 inline constexpr bool is_same_v = __is_same(_Tp, _Up); 3688 #else 3689 template <typename _Tp, typename _Up> 3690 inline constexpr bool is_same_v = false; 3691 template <typename _Tp> 3692 inline constexpr bool is_same_v<_Tp, _Tp> = true; 3693 #endif 3694 template <typename _Base, typename _Derived> 3695 inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); 3696 #ifdef __cpp_lib_is_virtual_base_of // C++ >= 26 3697 template <typename _Base, typename _Derived> 3698 inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived); 3699 #endif 3700 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible) 3701 template <typename _From, typename _To> 3702 inline constexpr bool is_convertible_v = __is_convertible(_From, _To); 3703 #else 3704 template <typename _From, typename _To> 3705 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; 3706 #endif 3707 template<typename _Fn, typename... _Args> 3708 inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; 3709 template<typename _Fn, typename... _Args> 3710 inline constexpr bool is_nothrow_invocable_v 3711 = is_nothrow_invocable<_Fn, _Args...>::value; 3712 template<typename _Ret, typename _Fn, typename... _Args> 3713 inline constexpr bool is_invocable_r_v 3714 = is_invocable_r<_Ret, _Fn, _Args...>::value; 3715 template<typename _Ret, typename _Fn, typename... _Args> 3716 inline constexpr bool is_nothrow_invocable_r_v 3717 = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; 3718 /// @} 3719 #endif // __cpp_lib_type_trait_variable_templates 3720 3721 #ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP 3722 /// has_unique_object_representations 3723 /// @since C++17 3724 template<typename _Tp> 3725 struct has_unique_object_representations 3726 : bool_constant<__has_unique_object_representations( 3727 remove_cv_t<remove_all_extents_t<_Tp>> 3728 )> 3729 { 3730 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), 3731 "template argument must be a complete class or an unbounded array"); 3732 }; 3733 3734 # if __cpp_lib_type_trait_variable_templates // C++ >= 17 3735 /// @ingroup variable_templates 3736 template<typename _Tp> 3737 inline constexpr bool has_unique_object_representations_v 3738 = has_unique_object_representations<_Tp>::value; 3739 # endif 3740 #endif 3741 3742 #ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate 3743 /// is_aggregate - true if the type is an aggregate. 3744 /// @since C++17 3745 template<typename _Tp> 3746 struct is_aggregate 3747 : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> 3748 { }; 3749 3750 # if __cpp_lib_type_trait_variable_templates // C++ >= 17 3751 /** is_aggregate_v - true if the type is an aggregate. 3752 * @ingroup variable_templates 3753 * @since C++17 3754 */ 3755 template<typename _Tp> 3756 inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>); 3757 # endif 3758 #endif 3759 3760 /** * Remove references and cv-qualifiers. 3761 * @since C++20 3762 * @{ 3763 */ 3764 #ifdef __cpp_lib_remove_cvref // C++ >= 20 3765 # if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref) 3766 template<typename _Tp> 3767 struct remove_cvref 3768 { using type = __remove_cvref(_Tp); }; 3769 # else 3770 template<typename _Tp> 3771 struct remove_cvref 3772 { using type = typename remove_cv<_Tp>::type; }; 3773 3774 template<typename _Tp> 3775 struct remove_cvref<_Tp&> 3776 { using type = typename remove_cv<_Tp>::type; }; 3777 3778 template<typename _Tp> 3779 struct remove_cvref<_Tp&&> 3780 { using type = typename remove_cv<_Tp>::type; }; 3781 # endif 3782 3783 template<typename _Tp> 3784 using remove_cvref_t = typename remove_cvref<_Tp>::type; 3785 /// @} 3786 #endif // __cpp_lib_remove_cvref 3787 3788 #ifdef __cpp_lib_type_identity // C++ >= 20 3789 /** * Identity metafunction. 3790 * @since C++20 3791 * @{ 3792 */ 3793 template<typename _Tp> 3794 struct type_identity { using type = _Tp; }; 3795 3796 template<typename _Tp> 3797 using type_identity_t = typename type_identity<_Tp>::type; 3798 /// @} 3799 #endif 3800 3801 #ifdef __cpp_lib_unwrap_ref // C++ >= 20 3802 /** Unwrap a reference_wrapper 3803 * @since C++20 3804 * @{ 3805 */ 3806 template<typename _Tp> 3807 struct unwrap_reference { using type = _Tp; }; 3808 3809 template<typename _Tp> 3810 struct unwrap_reference<reference_wrapper<_Tp>> { using type = _Tp&; }; 3811 3812 template<typename _Tp> 3813 using unwrap_reference_t = typename unwrap_reference<_Tp>::type; 3814 /// @} 3815 3816 /** Decay type and if it's a reference_wrapper, unwrap it 3817 * @since C++20 3818 * @{ 3819 */ 3820 template<typename _Tp> 3821 struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; }; 3822 3823 template<typename _Tp> 3824 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; 3825 /// @} 3826 #endif // __cpp_lib_unwrap_ref 3827 3828 #ifdef __cpp_lib_bounded_array_traits // C++ >= 20 3829 /// True for a type that is an array of known bound. 3830 /// @ingroup variable_templates 3831 /// @since C++20 3832 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array) 3833 template<typename _Tp> 3834 inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp); 3835 # else 3836 template<typename _Tp> 3837 inline constexpr bool is_bounded_array_v = false; 3838 3839 template<typename _Tp, size_t _Size> 3840 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true; 3841 # endif 3842 3843 /// True for a type that is an array of unknown bound. 3844 /// @ingroup variable_templates 3845 /// @since C++20 3846 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array) 3847 template<typename _Tp> 3848 inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp); 3849 # else 3850 template<typename _Tp> 3851 inline constexpr bool is_unbounded_array_v = false; 3852 3853 template<typename _Tp> 3854 inline constexpr bool is_unbounded_array_v<_Tp[]> = true; 3855 # endif 3856 3857 /// True for a type that is an array of known bound. 3858 /// @since C++20 3859 template<typename _Tp> 3860 struct is_bounded_array 3861 : public bool_constant<is_bounded_array_v<_Tp>> 3862 { }; 3863 3864 /// True for a type that is an array of unknown bound. 3865 /// @since C++20 3866 template<typename _Tp> 3867 struct is_unbounded_array 3868 : public bool_constant<is_unbounded_array_v<_Tp>> 3869 { }; 3870 #endif // __cpp_lib_bounded_array_traits 3871 3872 #if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L 3873 3874 /// @since C++20 3875 template<typename _Tp, typename _Up> 3876 struct is_layout_compatible 3877 : bool_constant<__is_layout_compatible(_Tp, _Up)> 3878 { }; 3879 3880 /// @ingroup variable_templates 3881 /// @since C++20 3882 template<typename _Tp, typename _Up> 3883 constexpr bool is_layout_compatible_v 3884 = __is_layout_compatible(_Tp, _Up); 3885 3886 #if __has_builtin(__builtin_is_corresponding_member) 3887 # ifndef __cpp_lib_is_layout_compatible 3888 # error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set" 3889 # endif 3890 3891 /// @since C++20 3892 template<typename _S1, typename _S2, typename _M1, typename _M2> 3893 constexpr bool 3894 is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept 3895 { return __builtin_is_corresponding_member(__m1, __m2); } 3896 #endif 3897 #endif 3898 3899 #if __has_builtin(__is_pointer_interconvertible_base_of) \ 3900 && __cplusplus >= 202002L 3901 /// True if `_Derived` is standard-layout and has a base class of type `_Base` 3902 /// @since C++20 3903 template<typename _Base, typename _Derived> 3904 struct is_pointer_interconvertible_base_of 3905 : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> 3906 { }; 3907 3908 /// @ingroup variable_templates 3909 /// @since C++20 3910 template<typename _Base, typename _Derived> 3911 constexpr bool is_pointer_interconvertible_base_of_v 3912 = __is_pointer_interconvertible_base_of(_Base, _Derived); 3913 3914 #if __has_builtin(__builtin_is_pointer_interconvertible_with_class) 3915 # ifndef __cpp_lib_is_pointer_interconvertible 3916 # error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set" 3917 # endif 3918 3919 /// True if `__mp` points to the first member of a standard-layout type 3920 /// @returns true if `s.*__mp` is pointer-interconvertible with `s` 3921 /// @since C++20 3922 template<typename _Tp, typename _Mem> 3923 constexpr bool 3924 is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept 3925 { return __builtin_is_pointer_interconvertible_with_class(__mp); } 3926 #endif 3927 #endif 3928 3929 #ifdef __cpp_lib_is_scoped_enum // C++ >= 23 3930 /// True if the type is a scoped enumeration type. 3931 /// @since C++23 3932 3933 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) 3934 template<typename _Tp> 3935 struct is_scoped_enum 3936 : bool_constant<__is_scoped_enum(_Tp)> 3937 { }; 3938 # else 3939 template<typename _Tp> 3940 struct is_scoped_enum 3941 : false_type 3942 { }; 3943 3944 template<typename _Tp> 3945 requires __is_enum(_Tp) 3946 && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete 3947 struct is_scoped_enum<_Tp> 3948 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }> 3949 { }; 3950 # endif 3951 3952 /// @ingroup variable_templates 3953 /// @since C++23 3954 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum) 3955 template<typename _Tp> 3956 inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); 3957 # else 3958 template<typename _Tp> 3959 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; 3960 # endif 3961 #endif 3962 3963 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp 3964 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in 3965 /// direct-initialization, and a temporary object would be bound to 3966 /// the reference, false otherwise. 3967 /// @since C++23 3968 template<typename _Tp, typename _Up> 3969 struct reference_constructs_from_temporary 3970 : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)> 3971 { 3972 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) 3973 && std::__is_complete_or_unbounded(__type_identity<_Up>{}), 3974 "template argument must be a complete class or an unbounded array"); 3975 }; 3976 3977 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in 3978 /// copy-initialization, and a temporary object would be bound to 3979 /// the reference, false otherwise. 3980 /// @since C++23 3981 template<typename _Tp, typename _Up> 3982 struct reference_converts_from_temporary 3983 : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)> 3984 { 3985 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}) 3986 && std::__is_complete_or_unbounded(__type_identity<_Up>{}), 3987 "template argument must be a complete class or an unbounded array"); 3988 }; 3989 3990 /// @ingroup variable_templates 3991 /// @since C++23 3992 template<typename _Tp, typename _Up> 3993 inline constexpr bool reference_constructs_from_temporary_v 3994 = reference_constructs_from_temporary<_Tp, _Up>::value; 3995 3996 /// @ingroup variable_templates 3997 /// @since C++23 3998 template<typename _Tp, typename _Up> 3999 inline constexpr bool reference_converts_from_temporary_v 4000 = reference_converts_from_temporary<_Tp, _Up>::value; 4001 #endif // __cpp_lib_reference_from_temporary 4002 4003 #ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL 4004 /// Returns true only when called during constant evaluation. 4005 /// @since C++20 4006 constexpr inline bool 4007 is_constant_evaluated() noexcept 4008 { 4009 #if __cpp_if_consteval >= 202106L 4010 if consteval { return true; } else { return false; } 4011 #else 4012 return __builtin_is_constant_evaluated(); 4013 #endif 4014 } 4015 #endif 4016 4017 #if __cplusplus >= 202002L 4018 /// @cond undocumented 4019 template<typename _From, typename _To> 4020 using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type; 4021 4022 template<typename _Xp, typename _Yp> 4023 using __cond_res 4024 = decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()()); 4025 4026 template<typename _Ap, typename _Bp, typename = void> 4027 struct __common_ref_impl 4028 { }; 4029 4030 // [meta.trans.other], COMMON-REF(A, B) 4031 template<typename _Ap, typename _Bp> 4032 using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type; 4033 4034 // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &) 4035 template<typename _Xp, typename _Yp> 4036 using __condres_cvref 4037 = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>; 4038 4039 // If A and B are both lvalue reference types, ... 4040 template<typename _Xp, typename _Yp> 4041 struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>> 4042 : enable_if<is_reference_v<__condres_cvref<_Xp, _Yp>>, 4043 __condres_cvref<_Xp, _Yp>> 4044 { }; 4045 4046 // let C be remove_reference_t<COMMON-REF(X&, Y&)>&& 4047 template<typename _Xp, typename _Yp> 4048 using __common_ref_C = remove_reference_t<__common_ref<_Xp&, _Yp&>>&&; 4049 4050 // If A and B are both rvalue reference types, ... 4051 template<typename _Xp, typename _Yp> 4052 struct __common_ref_impl<_Xp&&, _Yp&&, 4053 _Require<is_convertible<_Xp&&, __common_ref_C<_Xp, _Yp>>, 4054 is_convertible<_Yp&&, __common_ref_C<_Xp, _Yp>>>> 4055 { using type = __common_ref_C<_Xp, _Yp>; }; 4056 4057 // let D be COMMON-REF(const X&, Y&) 4058 template<typename _Xp, typename _Yp> 4059 using __common_ref_D = __common_ref<const _Xp&, _Yp&>; 4060 4061 // If A is an rvalue reference and B is an lvalue reference, ... 4062 template<typename _Xp, typename _Yp> 4063 struct __common_ref_impl<_Xp&&, _Yp&, 4064 _Require<is_convertible<_Xp&&, __common_ref_D<_Xp, _Yp>>>> 4065 { using type = __common_ref_D<_Xp, _Yp>; }; 4066 4067 // If A is an lvalue reference and B is an rvalue reference, ... 4068 template<typename _Xp, typename _Yp> 4069 struct __common_ref_impl<_Xp&, _Yp&&> 4070 : __common_ref_impl<_Yp&&, _Xp&> 4071 { }; 4072 /// @endcond 4073 4074 template<typename _Tp, typename _Up, 4075 template<typename> class _TQual, template<typename> class _UQual> 4076 struct basic_common_reference 4077 { }; 4078 4079 /// @cond undocumented 4080 template<typename _Tp> 4081 struct __xref 4082 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>; }; 4083 4084 template<typename _Tp> 4085 struct __xref<_Tp&> 4086 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&; }; 4087 4088 template<typename _Tp> 4089 struct __xref<_Tp&&> 4090 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&&; }; 4091 4092 template<typename _Tp1, typename _Tp2> 4093 using __basic_common_ref 4094 = typename basic_common_reference<remove_cvref_t<_Tp1>, 4095 remove_cvref_t<_Tp2>, 4096 __xref<_Tp1>::template __type, 4097 __xref<_Tp2>::template __type>::type; 4098 /// @endcond 4099 4100 template<typename... _Tp> 4101 struct common_reference; 4102 4103 template<typename... _Tp> 4104 using common_reference_t = typename common_reference<_Tp...>::type; 4105 4106 // If sizeof...(T) is zero, there shall be no member type. 4107 template<> 4108 struct common_reference<> 4109 { }; 4110 4111 // If sizeof...(T) is one ... 4112 template<typename _Tp0> 4113 struct common_reference<_Tp0> 4114 { using type = _Tp0; }; 4115 4116 /// @cond undocumented 4117 template<typename _Tp1, typename _Tp2, int _Bullet = 1> 4118 struct __common_reference_impl 4119 : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1> 4120 { }; 4121 4122 // If sizeof...(T) is two ... 4123 template<typename _Tp1, typename _Tp2> 4124 struct common_reference<_Tp1, _Tp2> 4125 : __common_reference_impl<_Tp1, _Tp2> 4126 { }; 4127 4128 // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ... 4129 template<typename _Tp1, typename _Tp2> 4130 requires is_reference_v<_Tp1> && is_reference_v<_Tp2> 4131 && requires { typename __common_ref<_Tp1, _Tp2>; } 4132 #if __cpp_lib_common_reference // C++ >= 20 4133 && is_convertible_v<add_pointer_t<_Tp1>, 4134 add_pointer_t<__common_ref<_Tp1, _Tp2>>> 4135 && is_convertible_v<add_pointer_t<_Tp2>, 4136 add_pointer_t<__common_ref<_Tp1, _Tp2>>> 4137 #endif 4138 struct __common_reference_impl<_Tp1, _Tp2, 1> 4139 { using type = __common_ref<_Tp1, _Tp2>; }; 4140 4141 // Otherwise, if basic_common_reference<...>::type is well-formed, ... 4142 template<typename _Tp1, typename _Tp2> 4143 requires requires { typename __basic_common_ref<_Tp1, _Tp2>; } 4144 struct __common_reference_impl<_Tp1, _Tp2, 2> 4145 { using type = __basic_common_ref<_Tp1, _Tp2>; }; 4146 4147 // Otherwise, if COND-RES(T1, T2) is well-formed, ... 4148 template<typename _Tp1, typename _Tp2> 4149 requires requires { typename __cond_res<_Tp1, _Tp2>; } 4150 struct __common_reference_impl<_Tp1, _Tp2, 3> 4151 { using type = __cond_res<_Tp1, _Tp2>; }; 4152 4153 // Otherwise, if common_type_t<T1, T2> is well-formed, ... 4154 template<typename _Tp1, typename _Tp2> 4155 requires requires { typename common_type_t<_Tp1, _Tp2>; } 4156 struct __common_reference_impl<_Tp1, _Tp2, 4> 4157 { using type = common_type_t<_Tp1, _Tp2>; }; 4158 4159 // Otherwise, there shall be no member type. 4160 template<typename _Tp1, typename _Tp2> 4161 struct __common_reference_impl<_Tp1, _Tp2, 5> 4162 { }; 4163 4164 // Otherwise, if sizeof...(T) is greater than two, ... 4165 template<typename _Tp1, typename _Tp2, typename... _Rest> 4166 struct common_reference<_Tp1, _Tp2, _Rest...> 4167 : __common_type_fold<common_reference<_Tp1, _Tp2>, 4168 __common_type_pack<_Rest...>> 4169 { }; 4170 4171 // Reuse __common_type_fold for common_reference<T1, T2, Rest...> 4172 template<typename _Tp1, typename _Tp2, typename... _Rest> 4173 struct __common_type_fold<common_reference<_Tp1, _Tp2>, 4174 __common_type_pack<_Rest...>, 4175 void_t<common_reference_t<_Tp1, _Tp2>>> 4176 : public common_reference<common_reference_t<_Tp1, _Tp2>, _Rest...> 4177 { }; 4178 /// @endcond 4179 4180 #endif // C++20 4181 4182 /// @} group metaprogramming 4183 4184 _GLIBCXX_END_NAMESPACE_VERSION 4185 } // namespace std 4186 } // extern "C++" 4187 4188 #endif // C++11 4189 4190 #endif // _GLIBCXX_TYPE_TRAITS