1 // C++11 <type_traits> -*- C++ -*-
3 // Copyright (C) 2007-2024 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/type_traits
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_TYPE_TRAITS
30 #define _GLIBCXX_TYPE_TRAITS 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
38 #include <bits/c++config.h>
40 #define __glibcxx_want_bool_constant
41 #define __glibcxx_want_bounded_array_traits
42 #define __glibcxx_want_has_unique_object_representations
43 #define __glibcxx_want_integral_constant_callable
44 #define __glibcxx_want_is_aggregate
45 #define __glibcxx_want_is_constant_evaluated
46 #define __glibcxx_want_is_final
47 #define __glibcxx_want_is_invocable
48 #define __glibcxx_want_is_layout_compatible
49 #define __glibcxx_want_is_nothrow_convertible
50 #define __glibcxx_want_is_null_pointer
51 #define __glibcxx_want_is_pointer_interconvertible
52 #define __glibcxx_want_is_scoped_enum
53 #define __glibcxx_want_is_swappable
54 #define __glibcxx_want_logical_traits
55 #define __glibcxx_want_reference_from_temporary
56 #define __glibcxx_want_remove_cvref
57 #define __glibcxx_want_result_of_sfinae
58 #define __glibcxx_want_transformation_trait_aliases
59 #define __glibcxx_want_type_identity
60 #define __glibcxx_want_type_trait_variable_templates
61 #define __glibcxx_want_unwrap_ref
62 #define __glibcxx_want_void_t
63 #include <bits/version.h>
67 namespace std _GLIBCXX_VISIBILITY(default)
69 _GLIBCXX_BEGIN_NAMESPACE_VERSION
71 template<typename _Tp>
72 class reference_wrapper;
75 * @defgroup metaprogramming Metaprogramming
78 * Template utilities for compile-time introspection and modification,
79 * including type classification traits, type property inspection traits
80 * and type transformation traits.
88 template<typename _Tp, _Tp __v>
89 struct integral_constant
91 static constexpr _Tp value = __v;
92 using value_type = _Tp;
93 using type = integral_constant<_Tp, __v>;
94 constexpr operator value_type() const noexcept { return value; }
96 #ifdef __cpp_lib_integral_constant_callable // C++ >= 14
97 constexpr value_type operator()() const noexcept { return value; }
101 #if ! __cpp_inline_variables
102 template<typename _Tp, _Tp __v>
103 constexpr _Tp integral_constant<_Tp, __v>::value;
106 /// @cond undocumented
107 /// bool_constant for C++11
109 using __bool_constant = integral_constant<bool, __v>;
112 /// The type used as a compile-time boolean with true value.
113 using true_type = __bool_constant<true>;
115 /// The type used as a compile-time boolean with false value.
116 using false_type = __bool_constant<false>;
118 #ifdef __cpp_lib_bool_constant // C++ >= 17
119 /// Alias template for compile-time boolean constant types.
122 using bool_constant = __bool_constant<__v>;
125 // Metaprogramming helper types.
128 /// Define a member typedef `type` only if a boolean constant is true.
129 template<bool, typename _Tp = void>
133 // Partial specialization for true.
134 template<typename _Tp>
135 struct enable_if<true, _Tp>
136 { using type = _Tp; };
138 // __enable_if_t (std::enable_if_t for C++11)
139 template<bool _Cond, typename _Tp = void>
140 using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
145 template<typename _Tp, typename>
150 struct __conditional<false>
152 template<typename, typename _Up>
156 // More efficient version of std::conditional_t for internal use (and C++11)
157 template<bool _Cond, typename _If, typename _Else>
158 using __conditional_t
159 = typename __conditional<_Cond>::template type<_If, _Else>;
161 /// @cond undocumented
162 template <typename _Type>
163 struct __type_identity
164 { using type = _Type; };
166 template<typename _Tp>
167 using __type_identity_t = typename __type_identity<_Tp>::type;
171 // A variadic alias template that resolves to its first argument.
172 template<typename _Tp, typename...>
173 using __first_t = _Tp;
175 // These are deliberately not defined.
176 template<typename... _Bn>
177 auto __or_fn(int) -> __first_t<false_type,
178 __enable_if_t<!bool(_Bn::value)>...>;
180 template<typename... _Bn>
181 auto __or_fn(...) -> true_type;
183 template<typename... _Bn>
184 auto __and_fn(int) -> __first_t<true_type,
185 __enable_if_t<bool(_Bn::value)>...>;
187 template<typename... _Bn>
188 auto __and_fn(...) -> false_type;
189 } // namespace detail
191 // Like C++17 std::dis/conjunction, but usable in C++11 and resolves
192 // to either true_type or false_type which allows for a more efficient
193 // implementation that avoids recursive class template instantiation.
194 template<typename... _Bn>
196 : decltype(__detail::__or_fn<_Bn...>(0))
199 template<typename... _Bn>
201 : decltype(__detail::__and_fn<_Bn...>(0))
204 template<typename _Pp>
206 : __bool_constant<!bool(_Pp::value)>
210 #ifdef __cpp_lib_logical_traits // C++ >= 17
212 /// @cond undocumented
213 template<typename... _Bn>
214 inline constexpr bool __or_v = __or_<_Bn...>::value;
215 template<typename... _Bn>
216 inline constexpr bool __and_v = __and_<_Bn...>::value;
220 template<typename /* = void */, typename _B1, typename... _Bn>
221 struct __disjunction_impl
222 { using type = _B1; };
224 template<typename _B1, typename _B2, typename... _Bn>
225 struct __disjunction_impl<__enable_if_t<!bool(_B1::value)>, _B1, _B2, _Bn...>
226 { using type = typename __disjunction_impl<void, _B2, _Bn...>::type; };
228 template<typename /* = void */, typename _B1, typename... _Bn>
229 struct __conjunction_impl
230 { using type = _B1; };
232 template<typename _B1, typename _B2, typename... _Bn>
233 struct __conjunction_impl<__enable_if_t<bool(_B1::value)>, _B1, _B2, _Bn...>
234 { using type = typename __conjunction_impl<void, _B2, _Bn...>::type; };
235 } // namespace __detail
238 template<typename... _Bn>
240 : __detail::__conjunction_impl<void, _Bn...>::type
248 template<typename... _Bn>
250 : __detail::__disjunction_impl<void, _Bn...>::type
258 template<typename _Pp>
263 /** @ingroup variable_templates
266 template<typename... _Bn>
267 inline constexpr bool conjunction_v = conjunction<_Bn...>::value;
269 template<typename... _Bn>
270 inline constexpr bool disjunction_v = disjunction<_Bn...>::value;
272 template<typename _Pp>
273 inline constexpr bool negation_v = negation<_Pp>::value;
276 #endif // __cpp_lib_logical_traits
278 // Forward declarations
290 /// @cond undocumented
292 struct __is_array_unknown_bounds;
294 // Helper functions that return false_type for incomplete classes,
295 // incomplete unions and arrays of known bound from those.
297 template <typename _Tp, size_t = sizeof(_Tp)>
298 constexpr true_type __is_complete_or_unbounded(__type_identity<_Tp>)
301 template <typename _TypeIdentity,
302 typename _NestedType = typename _TypeIdentity::type>
303 constexpr typename __or_<
304 is_reference<_NestedType>,
305 is_function<_NestedType>,
306 is_void<_NestedType>,
307 __is_array_unknown_bounds<_NestedType>
308 >::type __is_complete_or_unbounded(_TypeIdentity)
311 // __remove_cv_t (std::remove_cv_t for C++11).
312 template<typename _Tp>
313 using __remove_cv_t = typename remove_cv<_Tp>::type;
316 // Primary type categories.
319 template<typename _Tp>
321 : public false_type { };
325 : public true_type { };
328 struct is_void<const void>
329 : public true_type { };
332 struct is_void<volatile void>
333 : public true_type { };
336 struct is_void<const volatile void>
337 : public true_type { };
339 /// @cond undocumented
341 struct __is_integral_helper
342 : public false_type { };
345 struct __is_integral_helper<bool>
346 : public true_type { };
349 struct __is_integral_helper<char>
350 : public true_type { };
353 struct __is_integral_helper<signed char>
354 : public true_type { };
357 struct __is_integral_helper<unsigned char>
358 : public true_type { };
360 // We want is_integral<wchar_t> to be true (and make_signed/unsigned to work)
361 // even when libc doesn't provide working <wchar.h> and related functions,
362 // so don't check _GLIBCXX_USE_WCHAR_T here.
364 struct __is_integral_helper<wchar_t>
365 : public true_type { };
367 #ifdef _GLIBCXX_USE_CHAR8_T
369 struct __is_integral_helper<char8_t>
370 : public true_type { };
374 struct __is_integral_helper<char16_t>
375 : public true_type { };
378 struct __is_integral_helper<char32_t>
379 : public true_type { };
382 struct __is_integral_helper<short>
383 : public true_type { };
386 struct __is_integral_helper<unsigned short>
387 : public true_type { };
390 struct __is_integral_helper<int>
391 : public true_type { };
394 struct __is_integral_helper<unsigned int>
395 : public true_type { };
398 struct __is_integral_helper<long>
399 : public true_type { };
402 struct __is_integral_helper<unsigned long>
403 : public true_type { };
406 struct __is_integral_helper<long long>
407 : public true_type { };
410 struct __is_integral_helper<unsigned long long>
411 : public true_type { };
413 // Conditionalizing on __STRICT_ANSI__ here will break any port that
414 // uses one of these types for size_t.
415 #if defined(__GLIBCXX_TYPE_INT_N_0)
418 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0>
419 : public true_type { };
423 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0>
424 : public true_type { };
426 #if defined(__GLIBCXX_TYPE_INT_N_1)
429 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1>
430 : public true_type { };
434 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1>
435 : public true_type { };
437 #if defined(__GLIBCXX_TYPE_INT_N_2)
440 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2>
441 : public true_type { };
445 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2>
446 : public true_type { };
448 #if defined(__GLIBCXX_TYPE_INT_N_3)
451 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3>
452 : public true_type { };
456 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3>
457 : public true_type { };
462 template<typename _Tp>
464 : public __is_integral_helper<__remove_cv_t<_Tp>>::type
467 /// @cond undocumented
469 struct __is_floating_point_helper
470 : public false_type { };
473 struct __is_floating_point_helper<float>
474 : public true_type { };
477 struct __is_floating_point_helper<double>
478 : public true_type { };
481 struct __is_floating_point_helper<long double>
482 : public true_type { };
484 #ifdef __STDCPP_FLOAT16_T__
486 struct __is_floating_point_helper<_Float16>
487 : public true_type { };
490 #ifdef __STDCPP_FLOAT32_T__
492 struct __is_floating_point_helper<_Float32>
493 : public true_type { };
496 #ifdef __STDCPP_FLOAT64_T__
498 struct __is_floating_point_helper<_Float64>
499 : public true_type { };
502 #ifdef __STDCPP_FLOAT128_T__
504 struct __is_floating_point_helper<_Float128>
505 : public true_type { };
508 #ifdef __STDCPP_BFLOAT16_T__
510 struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
511 : public true_type { };
514 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
516 struct __is_floating_point_helper<__float128>
517 : public true_type { };
521 /// is_floating_point
522 template<typename _Tp>
523 struct is_floating_point
524 : public __is_floating_point_helper<__remove_cv_t<_Tp>>::type
528 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
529 template<typename _Tp>
531 : public __bool_constant<__is_array(_Tp)>
536 : public false_type { };
538 template<typename _Tp, std::size_t _Size>
539 struct is_array<_Tp[_Size]>
540 : public true_type { };
542 template<typename _Tp>
543 struct is_array<_Tp[]>
544 : public true_type { };
548 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
549 template<typename _Tp>
551 : public __bool_constant<__is_pointer(_Tp)>
554 template<typename _Tp>
556 : public false_type { };
558 template<typename _Tp>
559 struct is_pointer<_Tp*>
560 : public true_type { };
562 template<typename _Tp>
563 struct is_pointer<_Tp* const>
564 : public true_type { };
566 template<typename _Tp>
567 struct is_pointer<_Tp* volatile>
568 : public true_type { };
570 template<typename _Tp>
571 struct is_pointer<_Tp* const volatile>
572 : public true_type { };
575 /// is_lvalue_reference
577 struct is_lvalue_reference
578 : public false_type { };
580 template<typename _Tp>
581 struct is_lvalue_reference<_Tp&>
582 : public true_type { };
584 /// is_rvalue_reference
586 struct is_rvalue_reference
587 : public false_type { };
589 template<typename _Tp>
590 struct is_rvalue_reference<_Tp&&>
591 : public true_type { };
593 /// is_member_object_pointer
594 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
595 template<typename _Tp>
596 struct is_member_object_pointer
597 : public __bool_constant<__is_member_object_pointer(_Tp)>
601 struct __is_member_object_pointer_helper
602 : public false_type { };
604 template<typename _Tp, typename _Cp>
605 struct __is_member_object_pointer_helper<_Tp _Cp::*>
606 : public __not_<is_function<_Tp>>::type { };
609 template<typename _Tp>
610 struct is_member_object_pointer
611 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
615 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
616 /// is_member_function_pointer
617 template<typename _Tp>
618 struct is_member_function_pointer
619 : public __bool_constant<__is_member_function_pointer(_Tp)>
623 struct __is_member_function_pointer_helper
624 : public false_type { };
626 template<typename _Tp, typename _Cp>
627 struct __is_member_function_pointer_helper<_Tp _Cp::*>
628 : public is_function<_Tp>::type { };
630 /// is_member_function_pointer
631 template<typename _Tp>
632 struct is_member_function_pointer
633 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
638 template<typename _Tp>
640 : public __bool_constant<__is_enum(_Tp)>
644 template<typename _Tp>
646 : public __bool_constant<__is_union(_Tp)>
650 template<typename _Tp>
652 : public __bool_constant<__is_class(_Tp)>
656 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
657 template<typename _Tp>
659 : public __bool_constant<__is_function(_Tp)>
662 template<typename _Tp>
664 : public __bool_constant<!is_const<const _Tp>::value> { };
666 template<typename _Tp>
667 struct is_function<_Tp&>
668 : public false_type { };
670 template<typename _Tp>
671 struct is_function<_Tp&&>
672 : public false_type { };
675 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
676 /// is_null_pointer (LWG 2247).
677 template<typename _Tp>
678 struct is_null_pointer
679 : public false_type { };
682 struct is_null_pointer<std::nullptr_t>
683 : public true_type { };
686 struct is_null_pointer<const std::nullptr_t>
687 : public true_type { };
690 struct is_null_pointer<volatile std::nullptr_t>
691 : public true_type { };
694 struct is_null_pointer<const volatile std::nullptr_t>
695 : public true_type { };
697 /// __is_nullptr_t (deprecated extension).
698 /// @deprecated Non-standard. Use `is_null_pointer` instead.
699 template<typename _Tp>
700 struct __is_nullptr_t
701 : public is_null_pointer<_Tp>
702 { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer");
703 #endif // __cpp_lib_is_null_pointer
705 // Composite type categories.
708 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
709 template<typename _Tp>
711 : public __bool_constant<__is_reference(_Tp)>
714 template<typename _Tp>
719 template<typename _Tp>
720 struct is_reference<_Tp&>
724 template<typename _Tp>
725 struct is_reference<_Tp&&>
731 template<typename _Tp>
733 : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type
737 template<typename _Tp>
738 struct is_fundamental
739 : public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
740 is_null_pointer<_Tp>>::type
744 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
745 template<typename _Tp>
747 : public __bool_constant<__is_object(_Tp)>
750 template<typename _Tp>
752 : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
758 struct is_member_pointer;
761 template<typename _Tp>
763 : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>,
764 is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
768 template<typename _Tp>
770 : public __bool_constant<!is_fundamental<_Tp>::value> { };
772 /// is_member_pointer
773 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
774 template<typename _Tp>
775 struct is_member_pointer
776 : public __bool_constant<__is_member_pointer(_Tp)>
779 /// @cond undocumented
780 template<typename _Tp>
781 struct __is_member_pointer_helper
782 : public false_type { };
784 template<typename _Tp, typename _Cp>
785 struct __is_member_pointer_helper<_Tp _Cp::*>
786 : public true_type { };
789 template<typename _Tp>
790 struct is_member_pointer
791 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
795 template<typename, typename>
798 /// @cond undocumented
799 template<typename _Tp, typename... _Types>
800 using __is_one_of = __or_<is_same<_Tp, _Types>...>;
802 // Check if a type is one of the signed integer types.
804 template<typename _Tp>
805 using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>,
806 signed char, signed short, signed int, signed long,
808 #if defined(__GLIBCXX_TYPE_INT_N_0)
809 , signed __GLIBCXX_TYPE_INT_N_0
811 #if defined(__GLIBCXX_TYPE_INT_N_1)
812 , signed __GLIBCXX_TYPE_INT_N_1
814 #if defined(__GLIBCXX_TYPE_INT_N_2)
815 , signed __GLIBCXX_TYPE_INT_N_2
817 #if defined(__GLIBCXX_TYPE_INT_N_3)
818 , signed __GLIBCXX_TYPE_INT_N_3
822 // Check if a type is one of the unsigned integer types.
824 template<typename _Tp>
825 using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>,
826 unsigned char, unsigned short, unsigned int, unsigned long,
828 #if defined(__GLIBCXX_TYPE_INT_N_0)
829 , unsigned __GLIBCXX_TYPE_INT_N_0
831 #if defined(__GLIBCXX_TYPE_INT_N_1)
832 , unsigned __GLIBCXX_TYPE_INT_N_1
834 #if defined(__GLIBCXX_TYPE_INT_N_2)
835 , unsigned __GLIBCXX_TYPE_INT_N_2
837 #if defined(__GLIBCXX_TYPE_INT_N_3)
838 , unsigned __GLIBCXX_TYPE_INT_N_3
842 // Check if a type is one of the signed or unsigned integer types.
843 template<typename _Tp>
844 using __is_standard_integer
845 = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
847 // __void_t (std::void_t for C++11)
848 template<typename...> using __void_t = void;
854 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
855 template<typename _Tp>
857 : public __bool_constant<__is_const(_Tp)>
862 : public false_type { };
864 template<typename _Tp>
865 struct is_const<_Tp const>
866 : public true_type { };
870 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
871 template<typename _Tp>
873 : public __bool_constant<__is_volatile(_Tp)>
878 : public false_type { };
880 template<typename _Tp>
881 struct is_volatile<_Tp volatile>
882 : public true_type { };
886 template<typename _Tp>
888 : public __bool_constant<__is_trivial(_Tp)>
890 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
891 "template argument must be a complete class or an unbounded array");
894 /// is_trivially_copyable
895 template<typename _Tp>
896 struct is_trivially_copyable
897 : public __bool_constant<__is_trivially_copyable(_Tp)>
899 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
900 "template argument must be a complete class or an unbounded array");
903 /// is_standard_layout
904 template<typename _Tp>
905 struct is_standard_layout
906 : public __bool_constant<__is_standard_layout(_Tp)>
908 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
909 "template argument must be a complete class or an unbounded array");
913 * @deprecated Deprecated in C++20.
914 * Use `is_standard_layout && is_trivial` instead.
916 // Could use is_standard_layout && is_trivial instead of the builtin.
917 template<typename _Tp>
919 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial")
921 : public __bool_constant<__is_pod(_Tp)>
923 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
924 "template argument must be a complete class or an unbounded array");
928 * @deprecated Deprecated in C++17, removed in C++20.
929 * The idea of a literal type isn't useful.
931 template<typename _Tp>
933 _GLIBCXX17_DEPRECATED
935 : public __bool_constant<__is_literal_type(_Tp)>
937 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
938 "template argument must be a complete class or an unbounded array");
942 template<typename _Tp>
944 : public __bool_constant<__is_empty(_Tp)>
948 template<typename _Tp>
949 struct is_polymorphic
950 : public __bool_constant<__is_polymorphic(_Tp)>
953 #ifdef __cpp_lib_is_final // C++ >= 14
956 template<typename _Tp>
958 : public __bool_constant<__is_final(_Tp)>
963 template<typename _Tp>
965 : public __bool_constant<__is_abstract(_Tp)>
968 /// @cond undocumented
969 template<typename _Tp,
970 bool = is_arithmetic<_Tp>::value>
971 struct __is_signed_helper
972 : public false_type { };
974 template<typename _Tp>
975 struct __is_signed_helper<_Tp, true>
976 : public __bool_constant<_Tp(-1) < _Tp(0)>
981 template<typename _Tp>
983 : public __is_signed_helper<_Tp>::type
987 template<typename _Tp>
989 : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type
992 /// @cond undocumented
993 template<typename _Tp, typename _Up = _Tp&&>
997 template<typename _Tp>
1002 template<typename _Tp>
1003 auto declval() noexcept -> decltype(__declval<_Tp>(0));
1006 struct remove_all_extents;
1008 /// @cond undocumented
1009 template<typename _Tp>
1010 struct __is_array_known_bounds
1014 template<typename _Tp, size_t _Size>
1015 struct __is_array_known_bounds<_Tp[_Size]>
1019 template<typename _Tp>
1020 struct __is_array_unknown_bounds
1024 template<typename _Tp>
1025 struct __is_array_unknown_bounds<_Tp[]>
1029 // Destructible and constructible type properties.
1031 // In N3290 is_destructible does not say anything about function
1032 // types and abstract types, see LWG 2049. This implementation
1033 // describes function types as non-destructible and all complete
1034 // object types as destructible, iff the explicit destructor
1035 // call expression is wellformed.
1036 struct __do_is_destructible_impl
1038 template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
1039 static true_type __test(int);
1042 static false_type __test(...);
1045 template<typename _Tp>
1046 struct __is_destructible_impl
1047 : public __do_is_destructible_impl
1049 using type = decltype(__test<_Tp>(0));
1052 template<typename _Tp,
1053 bool = __or_<is_void<_Tp>,
1054 __is_array_unknown_bounds<_Tp>,
1055 is_function<_Tp>>::value,
1056 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
1057 struct __is_destructible_safe;
1059 template<typename _Tp>
1060 struct __is_destructible_safe<_Tp, false, false>
1061 : public __is_destructible_impl<typename
1062 remove_all_extents<_Tp>::type>::type
1065 template<typename _Tp>
1066 struct __is_destructible_safe<_Tp, true, false>
1067 : public false_type { };
1069 template<typename _Tp>
1070 struct __is_destructible_safe<_Tp, false, true>
1071 : public true_type { };
1075 template<typename _Tp>
1076 struct is_destructible
1077 : public __is_destructible_safe<_Tp>::type
1079 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1080 "template argument must be a complete class or an unbounded array");
1083 /// @cond undocumented
1085 // is_nothrow_destructible requires that is_destructible is
1086 // satisfied as well. We realize that by mimicing the
1087 // implementation of is_destructible but refer to noexcept(expr)
1088 // instead of decltype(expr).
1089 struct __do_is_nt_destructible_impl
1091 template<typename _Tp>
1092 static __bool_constant<noexcept(declval<_Tp&>().~_Tp())>
1096 static false_type __test(...);
1099 template<typename _Tp>
1100 struct __is_nt_destructible_impl
1101 : public __do_is_nt_destructible_impl
1103 using type = decltype(__test<_Tp>(0));
1106 template<typename _Tp,
1107 bool = __or_<is_void<_Tp>,
1108 __is_array_unknown_bounds<_Tp>,
1109 is_function<_Tp>>::value,
1110 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
1111 struct __is_nt_destructible_safe;
1113 template<typename _Tp>
1114 struct __is_nt_destructible_safe<_Tp, false, false>
1115 : public __is_nt_destructible_impl<typename
1116 remove_all_extents<_Tp>::type>::type
1119 template<typename _Tp>
1120 struct __is_nt_destructible_safe<_Tp, true, false>
1121 : public false_type { };
1123 template<typename _Tp>
1124 struct __is_nt_destructible_safe<_Tp, false, true>
1125 : public true_type { };
1128 /// is_nothrow_destructible
1129 template<typename _Tp>
1130 struct is_nothrow_destructible
1131 : public __is_nt_destructible_safe<_Tp>::type
1133 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1134 "template argument must be a complete class or an unbounded array");
1137 /// @cond undocumented
1138 template<typename _Tp, typename... _Args>
1139 using __is_constructible_impl
1140 = __bool_constant<__is_constructible(_Tp, _Args...)>;
1143 /// is_constructible
1144 template<typename _Tp, typename... _Args>
1145 struct is_constructible
1146 : public __is_constructible_impl<_Tp, _Args...>
1148 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1149 "template argument must be a complete class or an unbounded array");
1152 /// is_default_constructible
1153 template<typename _Tp>
1154 struct is_default_constructible
1155 : public __is_constructible_impl<_Tp>
1157 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1158 "template argument must be a complete class or an unbounded array");
1161 /// @cond undocumented
1162 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
1163 template<typename _Tp>
1164 using __add_lval_ref_t = __add_lvalue_reference(_Tp);
1166 template<typename _Tp, typename = void>
1167 struct __add_lvalue_reference_helper
1168 { using type = _Tp; };
1170 template<typename _Tp>
1171 struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>>
1172 { using type = _Tp&; };
1174 template<typename _Tp>
1175 using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type;
1179 /// is_copy_constructible
1180 template<typename _Tp>
1181 struct is_copy_constructible
1182 : public __is_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1184 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1185 "template argument must be a complete class or an unbounded array");
1188 /// @cond undocumented
1189 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
1190 template<typename _Tp>
1191 using __add_rval_ref_t = __add_rvalue_reference(_Tp);
1193 template<typename _Tp, typename = void>
1194 struct __add_rvalue_reference_helper
1195 { using type = _Tp; };
1197 template<typename _Tp>
1198 struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>>
1199 { using type = _Tp&&; };
1201 template<typename _Tp>
1202 using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
1206 /// is_move_constructible
1207 template<typename _Tp>
1208 struct is_move_constructible
1209 : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1211 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1212 "template argument must be a complete class or an unbounded array");
1215 /// @cond undocumented
1216 template<typename _Tp, typename... _Args>
1217 using __is_nothrow_constructible_impl
1218 = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>;
1221 /// is_nothrow_constructible
1222 template<typename _Tp, typename... _Args>
1223 struct is_nothrow_constructible
1224 : public __is_nothrow_constructible_impl<_Tp, _Args...>
1226 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1227 "template argument must be a complete class or an unbounded array");
1230 /// is_nothrow_default_constructible
1231 template<typename _Tp>
1232 struct is_nothrow_default_constructible
1233 : public __is_nothrow_constructible_impl<_Tp>
1235 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1236 "template argument must be a complete class or an unbounded array");
1239 /// is_nothrow_copy_constructible
1240 template<typename _Tp>
1241 struct is_nothrow_copy_constructible
1242 : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1244 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1245 "template argument must be a complete class or an unbounded array");
1248 /// is_nothrow_move_constructible
1249 template<typename _Tp>
1250 struct is_nothrow_move_constructible
1251 : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1253 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1254 "template argument must be a complete class or an unbounded array");
1257 /// @cond undocumented
1258 template<typename _Tp, typename _Up>
1259 using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>;
1263 template<typename _Tp, typename _Up>
1264 struct is_assignable
1265 : public __is_assignable_impl<_Tp, _Up>
1267 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1268 "template argument must be a complete class or an unbounded array");
1271 /// is_copy_assignable
1272 template<typename _Tp>
1273 struct is_copy_assignable
1274 : public __is_assignable_impl<__add_lval_ref_t<_Tp>,
1275 __add_lval_ref_t<const _Tp>>
1277 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1278 "template argument must be a complete class or an unbounded array");
1281 /// is_move_assignable
1282 template<typename _Tp>
1283 struct is_move_assignable
1284 : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>>
1286 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1287 "template argument must be a complete class or an unbounded array");
1290 /// @cond undocumented
1291 template<typename _Tp, typename _Up>
1292 using __is_nothrow_assignable_impl
1293 = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>;
1296 /// is_nothrow_assignable
1297 template<typename _Tp, typename _Up>
1298 struct is_nothrow_assignable
1299 : public __is_nothrow_assignable_impl<_Tp, _Up>
1301 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1302 "template argument must be a complete class or an unbounded array");
1305 /// is_nothrow_copy_assignable
1306 template<typename _Tp>
1307 struct is_nothrow_copy_assignable
1308 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
1309 __add_lval_ref_t<const _Tp>>
1311 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1312 "template argument must be a complete class or an unbounded array");
1315 /// is_nothrow_move_assignable
1316 template<typename _Tp>
1317 struct is_nothrow_move_assignable
1318 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
1319 __add_rval_ref_t<_Tp>>
1321 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1322 "template argument must be a complete class or an unbounded array");
1325 /// @cond undocumented
1326 template<typename _Tp, typename... _Args>
1327 using __is_trivially_constructible_impl
1328 = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>;
1331 /// is_trivially_constructible
1332 template<typename _Tp, typename... _Args>
1333 struct is_trivially_constructible
1334 : public __is_trivially_constructible_impl<_Tp, _Args...>
1336 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1337 "template argument must be a complete class or an unbounded array");
1340 /// is_trivially_default_constructible
1341 template<typename _Tp>
1342 struct is_trivially_default_constructible
1343 : public __is_trivially_constructible_impl<_Tp>
1345 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1346 "template argument must be a complete class or an unbounded array");
1349 #if __cpp_variable_templates && __cpp_concepts
1350 template<typename _Tp>
1351 constexpr bool __is_implicitly_default_constructible_v
1352 = requires (void(&__f)(_Tp)) { __f({}); };
1354 template<typename _Tp>
1355 struct __is_implicitly_default_constructible
1356 : __bool_constant<__is_implicitly_default_constructible_v<_Tp>>
1359 struct __do_is_implicitly_default_constructible_impl
1361 template <typename _Tp>
1362 static void __helper(const _Tp&);
1364 template <typename _Tp>
1365 static true_type __test(const _Tp&,
1366 decltype(__helper<const _Tp&>({}))* = 0);
1368 static false_type __test(...);
1371 template<typename _Tp>
1372 struct __is_implicitly_default_constructible_impl
1373 : public __do_is_implicitly_default_constructible_impl
1375 using type = decltype(__test(declval<_Tp>()));
1378 template<typename _Tp>
1379 struct __is_implicitly_default_constructible_safe
1380 : public __is_implicitly_default_constructible_impl<_Tp>::type
1383 template <typename _Tp>
1384 struct __is_implicitly_default_constructible
1385 : public __and_<__is_constructible_impl<_Tp>,
1386 __is_implicitly_default_constructible_safe<_Tp>>::type
1390 /// is_trivially_copy_constructible
1391 template<typename _Tp>
1392 struct is_trivially_copy_constructible
1393 : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1395 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1396 "template argument must be a complete class or an unbounded array");
1399 /// is_trivially_move_constructible
1400 template<typename _Tp>
1401 struct is_trivially_move_constructible
1402 : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1404 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1405 "template argument must be a complete class or an unbounded array");
1408 /// @cond undocumented
1409 template<typename _Tp, typename _Up>
1410 using __is_trivially_assignable_impl
1411 = __bool_constant<__is_trivially_assignable(_Tp, _Up)>;
1414 /// is_trivially_assignable
1415 template<typename _Tp, typename _Up>
1416 struct is_trivially_assignable
1417 : public __is_trivially_assignable_impl<_Tp, _Up>
1419 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1420 "template argument must be a complete class or an unbounded array");
1423 /// is_trivially_copy_assignable
1424 template<typename _Tp>
1425 struct is_trivially_copy_assignable
1426 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
1427 __add_lval_ref_t<const _Tp>>
1429 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1430 "template argument must be a complete class or an unbounded array");
1433 /// is_trivially_move_assignable
1434 template<typename _Tp>
1435 struct is_trivially_move_assignable
1436 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
1437 __add_rval_ref_t<_Tp>>
1439 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1440 "template argument must be a complete class or an unbounded array");
1443 /// is_trivially_destructible
1444 template<typename _Tp>
1445 struct is_trivially_destructible
1446 : public __and_<__is_destructible_safe<_Tp>,
1447 __bool_constant<__has_trivial_destructor(_Tp)>>::type
1449 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1450 "template argument must be a complete class or an unbounded array");
1454 /// has_virtual_destructor
1455 template<typename _Tp>
1456 struct has_virtual_destructor
1457 : public __bool_constant<__has_virtual_destructor(_Tp)>
1459 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1460 "template argument must be a complete class or an unbounded array");
1464 // type property queries.
1467 template<typename _Tp>
1469 : public integral_constant<std::size_t, alignof(_Tp)>
1471 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1472 "template argument must be a complete class or an unbounded array");
1476 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank)
1477 template<typename _Tp>
1479 : public integral_constant<std::size_t, __array_rank(_Tp)> { };
1483 : public integral_constant<std::size_t, 0> { };
1485 template<typename _Tp, std::size_t _Size>
1486 struct rank<_Tp[_Size]>
1487 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1489 template<typename _Tp>
1491 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1495 template<typename, unsigned _Uint = 0>
1497 : public integral_constant<size_t, 0> { };
1499 template<typename _Tp, size_t _Size>
1500 struct extent<_Tp[_Size], 0>
1501 : public integral_constant<size_t, _Size> { };
1503 template<typename _Tp, unsigned _Uint, size_t _Size>
1504 struct extent<_Tp[_Size], _Uint>
1505 : public extent<_Tp, _Uint - 1>::type { };
1507 template<typename _Tp>
1508 struct extent<_Tp[], 0>
1509 : public integral_constant<size_t, 0> { };
1511 template<typename _Tp, unsigned _Uint>
1512 struct extent<_Tp[], _Uint>
1513 : public extent<_Tp, _Uint - 1>::type { };
1519 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same)
1520 template<typename _Tp, typename _Up>
1522 : public __bool_constant<__is_same(_Tp, _Up)>
1525 template<typename _Tp, typename _Up>
1530 template<typename _Tp>
1531 struct is_same<_Tp, _Tp>
1537 template<typename _Base, typename _Derived>
1539 : public __bool_constant<__is_base_of(_Base, _Derived)>
1542 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
1543 template<typename _From, typename _To>
1544 struct is_convertible
1545 : public __bool_constant<__is_convertible(_From, _To)>
1548 template<typename _From, typename _To,
1549 bool = __or_<is_void<_From>, is_function<_To>,
1550 is_array<_To>>::value>
1551 struct __is_convertible_helper
1553 using type = typename is_void<_To>::type;
1556 #pragma GCC diagnostic push
1557 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
1558 template<typename _From, typename _To>
1559 class __is_convertible_helper<_From, _To, false>
1561 template<typename _To1>
1562 static void __test_aux(_To1) noexcept;
1564 template<typename _From1, typename _To1,
1565 typename = decltype(__test_aux<_To1>(std::declval<_From1>()))>
1569 template<typename, typename>
1574 using type = decltype(__test<_From, _To>(0));
1576 #pragma GCC diagnostic pop
1579 template<typename _From, typename _To>
1580 struct is_convertible
1581 : public __is_convertible_helper<_From, _To>::type
1585 // helper trait for unique_ptr<T[]>, shared_ptr<T[]>, and span<T, N>
1586 template<typename _ToElementType, typename _FromElementType>
1587 using __is_array_convertible
1588 = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>;
1590 #ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20
1592 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible)
1593 /// is_nothrow_convertible_v
1594 template<typename _From, typename _To>
1595 inline constexpr bool is_nothrow_convertible_v
1596 = __is_nothrow_convertible(_From, _To);
1598 /// is_nothrow_convertible
1599 template<typename _From, typename _To>
1600 struct is_nothrow_convertible
1601 : public bool_constant<is_nothrow_convertible_v<_From, _To>>
1604 template<typename _From, typename _To,
1605 bool = __or_<is_void<_From>, is_function<_To>,
1606 is_array<_To>>::value>
1607 struct __is_nt_convertible_helper
1611 #pragma GCC diagnostic push
1612 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
1613 template<typename _From, typename _To>
1614 class __is_nt_convertible_helper<_From, _To, false>
1616 template<typename _To1>
1617 static void __test_aux(_To1) noexcept;
1619 template<typename _From1, typename _To1>
1621 __bool_constant<noexcept(__test_aux<_To1>(std::declval<_From1>()))>
1624 template<typename, typename>
1629 using type = decltype(__test<_From, _To>(0));
1631 #pragma GCC diagnostic pop
1633 /// is_nothrow_convertible
1634 template<typename _From, typename _To>
1635 struct is_nothrow_convertible
1636 : public __is_nt_convertible_helper<_From, _To>::type
1639 /// is_nothrow_convertible_v
1640 template<typename _From, typename _To>
1641 inline constexpr bool is_nothrow_convertible_v
1642 = is_nothrow_convertible<_From, _To>::value;
1644 #endif // __cpp_lib_is_nothrow_convertible
1646 // Const-volatile modifications.
1649 template<typename _Tp>
1651 { using type = _Tp; };
1653 template<typename _Tp>
1654 struct remove_const<_Tp const>
1655 { using type = _Tp; };
1658 template<typename _Tp>
1659 struct remove_volatile
1660 { using type = _Tp; };
1662 template<typename _Tp>
1663 struct remove_volatile<_Tp volatile>
1664 { using type = _Tp; };
1667 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv)
1668 template<typename _Tp>
1670 { using type = __remove_cv(_Tp); };
1672 template<typename _Tp>
1674 { using type = _Tp; };
1676 template<typename _Tp>
1677 struct remove_cv<const _Tp>
1678 { using type = _Tp; };
1680 template<typename _Tp>
1681 struct remove_cv<volatile _Tp>
1682 { using type = _Tp; };
1684 template<typename _Tp>
1685 struct remove_cv<const volatile _Tp>
1686 { using type = _Tp; };
1690 template<typename _Tp>
1692 { using type = _Tp const; };
1695 template<typename _Tp>
1697 { using type = _Tp volatile; };
1700 template<typename _Tp>
1702 { using type = _Tp const volatile; };
1704 #ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14
1705 /// Alias template for remove_const
1706 template<typename _Tp>
1707 using remove_const_t = typename remove_const<_Tp>::type;
1709 /// Alias template for remove_volatile
1710 template<typename _Tp>
1711 using remove_volatile_t = typename remove_volatile<_Tp>::type;
1713 /// Alias template for remove_cv
1714 template<typename _Tp>
1715 using remove_cv_t = typename remove_cv<_Tp>::type;
1717 /// Alias template for add_const
1718 template<typename _Tp>
1719 using add_const_t = typename add_const<_Tp>::type;
1721 /// Alias template for add_volatile
1722 template<typename _Tp>
1723 using add_volatile_t = typename add_volatile<_Tp>::type;
1725 /// Alias template for add_cv
1726 template<typename _Tp>
1727 using add_cv_t = typename add_cv<_Tp>::type;
1730 // Reference transformations.
1732 /// remove_reference
1733 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
1734 template<typename _Tp>
1735 struct remove_reference
1736 { using type = __remove_reference(_Tp); };
1738 template<typename _Tp>
1739 struct remove_reference
1740 { using type = _Tp; };
1742 template<typename _Tp>
1743 struct remove_reference<_Tp&>
1744 { using type = _Tp; };
1746 template<typename _Tp>
1747 struct remove_reference<_Tp&&>
1748 { using type = _Tp; };
1751 /// add_lvalue_reference
1752 template<typename _Tp>
1753 struct add_lvalue_reference
1754 { using type = __add_lval_ref_t<_Tp>; };
1756 /// add_rvalue_reference
1757 template<typename _Tp>
1758 struct add_rvalue_reference
1759 { using type = __add_rval_ref_t<_Tp>; };
1761 #if __cplusplus > 201103L
1762 /// Alias template for remove_reference
1763 template<typename _Tp>
1764 using remove_reference_t = typename remove_reference<_Tp>::type;
1766 /// Alias template for add_lvalue_reference
1767 template<typename _Tp>
1768 using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
1770 /// Alias template for add_rvalue_reference
1771 template<typename _Tp>
1772 using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
1775 // Sign modifications.
1777 /// @cond undocumented
1779 // Utility for constructing identically cv-qualified types.
1780 template<typename _Unqualified, bool _IsConst, bool _IsVol>
1781 struct __cv_selector;
1783 template<typename _Unqualified>
1784 struct __cv_selector<_Unqualified, false, false>
1785 { using __type = _Unqualified; };
1787 template<typename _Unqualified>
1788 struct __cv_selector<_Unqualified, false, true>
1789 { using __type = volatile _Unqualified; };
1791 template<typename _Unqualified>
1792 struct __cv_selector<_Unqualified, true, false>
1793 { using __type = const _Unqualified; };
1795 template<typename _Unqualified>
1796 struct __cv_selector<_Unqualified, true, true>
1797 { using __type = const volatile _Unqualified; };
1799 template<typename _Qualified, typename _Unqualified,
1800 bool _IsConst = is_const<_Qualified>::value,
1801 bool _IsVol = is_volatile<_Qualified>::value>
1802 class __match_cv_qualifiers
1804 using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>;
1807 using __type = typename __match::__type;
1810 // Utility for finding the unsigned versions of signed integral types.
1811 template<typename _Tp>
1812 struct __make_unsigned
1813 { using __type = _Tp; };
1816 struct __make_unsigned<char>
1817 { using __type = unsigned char; };
1820 struct __make_unsigned<signed char>
1821 { using __type = unsigned char; };
1824 struct __make_unsigned<short>
1825 { using __type = unsigned short; };
1828 struct __make_unsigned<int>
1829 { using __type = unsigned int; };
1832 struct __make_unsigned<long>
1833 { using __type = unsigned long; };
1836 struct __make_unsigned<long long>
1837 { using __type = unsigned long long; };
1839 #if defined(__GLIBCXX_TYPE_INT_N_0)
1842 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
1843 { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; };
1845 #if defined(__GLIBCXX_TYPE_INT_N_1)
1848 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1>
1849 { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; };
1851 #if defined(__GLIBCXX_TYPE_INT_N_2)
1854 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2>
1855 { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; };
1857 #if defined(__GLIBCXX_TYPE_INT_N_3)
1860 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3>
1861 { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; };
1864 // Select between integral and enum: not possible to be both.
1865 template<typename _Tp,
1866 bool _IsInt = is_integral<_Tp>::value,
1867 bool _IsEnum = __is_enum(_Tp)>
1868 class __make_unsigned_selector;
1870 template<typename _Tp>
1871 class __make_unsigned_selector<_Tp, true, false>
1873 using __unsigned_type
1874 = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
1878 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
1881 class __make_unsigned_selector_base
1884 template<typename...> struct _List { };
1886 template<typename _Tp, typename... _Up>
1887 struct _List<_Tp, _Up...> : _List<_Up...>
1888 { static constexpr size_t __size = sizeof(_Tp); };
1890 template<size_t _Sz, typename _Tp, bool = (_Sz <= _Tp::__size)>
1893 template<size_t _Sz, typename _Uint, typename... _UInts>
1894 struct __select<_Sz, _List<_Uint, _UInts...>, true>
1895 { using __type = _Uint; };
1897 template<size_t _Sz, typename _Uint, typename... _UInts>
1898 struct __select<_Sz, _List<_Uint, _UInts...>, false>
1899 : __select<_Sz, _List<_UInts...>>
1903 // Choose unsigned integer type with the smallest rank and same size as _Tp
1904 template<typename _Tp>
1905 class __make_unsigned_selector<_Tp, false, true>
1906 : __make_unsigned_selector_base
1908 // With -fshort-enums, an enum may be as small as a char.
1909 using _UInts = _List<unsigned char, unsigned short, unsigned int,
1910 unsigned long, unsigned long long>;
1912 using __unsigned_type = typename __select<sizeof(_Tp), _UInts>::__type;
1916 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
1919 // wchar_t, char8_t, char16_t and char32_t are integral types but are
1920 // neither signed integer types nor unsigned integer types, so must be
1921 // transformed to the unsigned integer type with the smallest rank.
1922 // Use the partial specialization for enumeration types to do that.
1924 struct __make_unsigned<wchar_t>
1927 = typename __make_unsigned_selector<wchar_t, false, true>::__type;
1930 #ifdef _GLIBCXX_USE_CHAR8_T
1932 struct __make_unsigned<char8_t>
1935 = typename __make_unsigned_selector<char8_t, false, true>::__type;
1940 struct __make_unsigned<char16_t>
1943 = typename __make_unsigned_selector<char16_t, false, true>::__type;
1947 struct __make_unsigned<char32_t>
1950 = typename __make_unsigned_selector<char32_t, false, true>::__type;
1954 // Given an integral/enum type, return the corresponding unsigned
1956 // Primary template.
1958 template<typename _Tp>
1959 struct make_unsigned
1960 { using type = typename __make_unsigned_selector<_Tp>::__type; };
1962 // Integral, but don't define.
1963 template<> struct make_unsigned<bool>;
1964 template<> struct make_unsigned<bool const>;
1965 template<> struct make_unsigned<bool volatile>;
1966 template<> struct make_unsigned<bool const volatile>;
1968 /// @cond undocumented
1970 // Utility for finding the signed versions of unsigned integral types.
1971 template<typename _Tp>
1972 struct __make_signed
1973 { using __type = _Tp; };
1976 struct __make_signed<char>
1977 { using __type = signed char; };
1980 struct __make_signed<unsigned char>
1981 { using __type = signed char; };
1984 struct __make_signed<unsigned short>
1985 { using __type = signed short; };
1988 struct __make_signed<unsigned int>
1989 { using __type = signed int; };
1992 struct __make_signed<unsigned long>
1993 { using __type = signed long; };
1996 struct __make_signed<unsigned long long>
1997 { using __type = signed long long; };
1999 #if defined(__GLIBCXX_TYPE_INT_N_0)
2002 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
2003 { using __type = __GLIBCXX_TYPE_INT_N_0; };
2005 #if defined(__GLIBCXX_TYPE_INT_N_1)
2008 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1>
2009 { using __type = __GLIBCXX_TYPE_INT_N_1; };
2011 #if defined(__GLIBCXX_TYPE_INT_N_2)
2014 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2>
2015 { using __type = __GLIBCXX_TYPE_INT_N_2; };
2017 #if defined(__GLIBCXX_TYPE_INT_N_3)
2020 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3>
2021 { using __type = __GLIBCXX_TYPE_INT_N_3; };
2024 // Select between integral and enum: not possible to be both.
2025 template<typename _Tp,
2026 bool _IsInt = is_integral<_Tp>::value,
2027 bool _IsEnum = __is_enum(_Tp)>
2028 class __make_signed_selector;
2030 template<typename _Tp>
2031 class __make_signed_selector<_Tp, true, false>
2034 = typename __make_signed<__remove_cv_t<_Tp>>::__type;
2038 = typename __match_cv_qualifiers<_Tp, __signed_type>::__type;
2041 // Choose signed integer type with the smallest rank and same size as _Tp
2042 template<typename _Tp>
2043 class __make_signed_selector<_Tp, false, true>
2045 using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type;
2048 using __type = typename __make_signed_selector<__unsigned_type>::__type;
2051 // wchar_t, char16_t and char32_t are integral types but are neither
2052 // signed integer types nor unsigned integer types, so must be
2053 // transformed to the signed integer type with the smallest rank.
2054 // Use the partial specialization for enumeration types to do that.
2056 struct __make_signed<wchar_t>
2059 = typename __make_signed_selector<wchar_t, false, true>::__type;
2062 #if defined(_GLIBCXX_USE_CHAR8_T)
2064 struct __make_signed<char8_t>
2067 = typename __make_signed_selector<char8_t, false, true>::__type;
2072 struct __make_signed<char16_t>
2075 = typename __make_signed_selector<char16_t, false, true>::__type;
2079 struct __make_signed<char32_t>
2082 = typename __make_signed_selector<char32_t, false, true>::__type;
2086 // Given an integral/enum type, return the corresponding signed
2088 // Primary template.
2090 template<typename _Tp>
2092 { using type = typename __make_signed_selector<_Tp>::__type; };
2094 // Integral, but don't define.
2095 template<> struct make_signed<bool>;
2096 template<> struct make_signed<bool const>;
2097 template<> struct make_signed<bool volatile>;
2098 template<> struct make_signed<bool const volatile>;
2100 #if __cplusplus > 201103L
2101 /// Alias template for make_signed
2102 template<typename _Tp>
2103 using make_signed_t = typename make_signed<_Tp>::type;
2105 /// Alias template for make_unsigned
2106 template<typename _Tp>
2107 using make_unsigned_t = typename make_unsigned<_Tp>::type;
2110 // Array modifications.
2113 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
2114 template<typename _Tp>
2115 struct remove_extent
2116 { using type = __remove_extent(_Tp); };
2118 template<typename _Tp>
2119 struct remove_extent
2120 { using type = _Tp; };
2122 template<typename _Tp, std::size_t _Size>
2123 struct remove_extent<_Tp[_Size]>
2124 { using type = _Tp; };
2126 template<typename _Tp>
2127 struct remove_extent<_Tp[]>
2128 { using type = _Tp; };
2131 /// remove_all_extents
2132 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents)
2133 template<typename _Tp>
2134 struct remove_all_extents
2135 { using type = __remove_all_extents(_Tp); };
2137 template<typename _Tp>
2138 struct remove_all_extents
2139 { using type = _Tp; };
2141 template<typename _Tp, std::size_t _Size>
2142 struct remove_all_extents<_Tp[_Size]>
2143 { using type = typename remove_all_extents<_Tp>::type; };
2145 template<typename _Tp>
2146 struct remove_all_extents<_Tp[]>
2147 { using type = typename remove_all_extents<_Tp>::type; };
2150 #if __cplusplus > 201103L
2151 /// Alias template for remove_extent
2152 template<typename _Tp>
2153 using remove_extent_t = typename remove_extent<_Tp>::type;
2155 /// Alias template for remove_all_extents
2156 template<typename _Tp>
2157 using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
2160 // Pointer modifications.
2163 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
2164 template<typename _Tp>
2165 struct remove_pointer
2166 { using type = __remove_pointer(_Tp); };
2168 template<typename _Tp, typename>
2169 struct __remove_pointer_helper
2170 { using type = _Tp; };
2172 template<typename _Tp, typename _Up>
2173 struct __remove_pointer_helper<_Tp, _Up*>
2174 { using type = _Up; };
2176 template<typename _Tp>
2177 struct remove_pointer
2178 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
2183 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
2184 template<typename _Tp>
2186 { using type = __add_pointer(_Tp); };
2188 template<typename _Tp, typename = void>
2189 struct __add_pointer_helper
2190 { using type = _Tp; };
2192 template<typename _Tp>
2193 struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
2194 { using type = _Tp*; };
2196 template<typename _Tp>
2198 : public __add_pointer_helper<_Tp>
2201 template<typename _Tp>
2202 struct add_pointer<_Tp&>
2203 { using type = _Tp*; };
2205 template<typename _Tp>
2206 struct add_pointer<_Tp&&>
2207 { using type = _Tp*; };
2210 #if __cplusplus > 201103L
2211 /// Alias template for remove_pointer
2212 template<typename _Tp>
2213 using remove_pointer_t = typename remove_pointer<_Tp>::type;
2215 /// Alias template for add_pointer
2216 template<typename _Tp>
2217 using add_pointer_t = typename add_pointer<_Tp>::type;
2220 template<std::size_t _Len>
2221 struct __aligned_storage_msa
2225 unsigned char __data[_Len];
2226 struct __attribute__((__aligned__)) { } __align;
2231 * @brief Alignment type.
2233 * The value of _Align is a default-alignment which shall be the
2234 * most stringent alignment requirement for any C++ object type
2235 * whose size is no greater than _Len (3.9). The member typedef
2236 * type shall be a POD type suitable for use as uninitialized
2237 * storage for any object whose size is at most _Len and whose
2238 * alignment is a divisor of _Align.
2240 * @deprecated Deprecated in C++23. Uses can be replaced by an
2241 * array std::byte[_Len] declared with alignas(_Align).
2243 template<std::size_t _Len, std::size_t _Align =
2244 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
2246 _GLIBCXX23_DEPRECATED
2251 unsigned char __data[_Len];
2252 struct __attribute__((__aligned__((_Align)))) { } __align;
2256 template <typename... _Types>
2257 struct __strictest_alignment
2259 static const size_t _S_alignment = 0;
2260 static const size_t _S_size = 0;
2263 template <typename _Tp, typename... _Types>
2264 struct __strictest_alignment<_Tp, _Types...>
2266 static const size_t _S_alignment =
2267 alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment
2268 ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment;
2269 static const size_t _S_size =
2270 sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size
2271 ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size;
2274 #pragma GCC diagnostic push
2275 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2278 * @brief Provide aligned storage for types.
2280 * [meta.trans.other]
2282 * Provides aligned storage for any of the provided types of at
2285 * @see aligned_storage
2287 * @deprecated Deprecated in C++23.
2289 template <size_t _Len, typename... _Types>
2291 _GLIBCXX23_DEPRECATED
2295 static_assert(sizeof...(_Types) != 0, "At least one type is required");
2297 using __strictest = __strictest_alignment<_Types...>;
2298 static const size_t _S_len = _Len > __strictest::_S_size
2299 ? _Len : __strictest::_S_size;
2301 /// The value of the strictest alignment of _Types.
2302 static const size_t alignment_value = __strictest::_S_alignment;
2304 using type = typename aligned_storage<_S_len, alignment_value>::type;
2307 template <size_t _Len, typename... _Types>
2308 const size_t aligned_union<_Len, _Types...>::alignment_value;
2309 #pragma GCC diagnostic pop
2311 /// @cond undocumented
2313 #if _GLIBCXX_USE_BUILTIN_TRAIT(__decay)
2314 template<typename _Tp>
2316 { using type = __decay(_Tp); };
2318 // Decay trait for arrays and functions, used for perfect forwarding
2319 // in make_pair, make_tuple, etc.
2320 template<typename _Up>
2321 struct __decay_selector
2322 : __conditional_t<is_const<const _Up>::value, // false for functions
2323 remove_cv<_Up>, // N.B. DR 705.
2324 add_pointer<_Up>> // function decays to pointer
2327 template<typename _Up, size_t _Nm>
2328 struct __decay_selector<_Up[_Nm]>
2329 { using type = _Up*; };
2331 template<typename _Up>
2332 struct __decay_selector<_Up[]>
2333 { using type = _Up*; };
2338 template<typename _Tp>
2340 { using type = typename __decay_selector<_Tp>::type; };
2342 template<typename _Tp>
2344 { using type = typename __decay_selector<_Tp>::type; };
2346 template<typename _Tp>
2348 { using type = typename __decay_selector<_Tp>::type; };
2351 /// @cond undocumented
2353 // Helper which adds a reference to a type when given a reference_wrapper
2354 template<typename _Tp>
2355 struct __strip_reference_wrapper
2360 template<typename _Tp>
2361 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
2363 using __type = _Tp&;
2366 // __decay_t (std::decay_t for C++11).
2367 template<typename _Tp>
2368 using __decay_t = typename decay<_Tp>::type;
2370 template<typename _Tp>
2371 using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>;
2374 /// @cond undocumented
2376 // Helper for SFINAE constraints
2377 template<typename... _Cond>
2378 using _Require = __enable_if_t<__and_<_Cond...>::value>;
2380 // __remove_cvref_t (std::remove_cvref_t for C++11).
2381 template<typename _Tp>
2382 using __remove_cvref_t
2383 = typename remove_cv<typename remove_reference<_Tp>::type>::type;
2386 // Primary template.
2387 /// Define a member typedef @c type to one of two argument types.
2388 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2390 { using type = _Iftrue; };
2392 // Partial specialization for false.
2393 template<typename _Iftrue, typename _Iffalse>
2394 struct conditional<false, _Iftrue, _Iffalse>
2395 { using type = _Iffalse; };
2398 template<typename... _Tp>
2401 // Sfinae-friendly common_type implementation:
2403 /// @cond undocumented
2405 // For several sfinae-friendly trait implementations we transport both the
2406 // result information (as the member type) and the failure information (no
2407 // member type). This is very similar to std::enable_if, but we cannot use
2408 // that, because we need to derive from them as an implementation detail.
2410 template<typename _Tp>
2411 struct __success_type
2412 { using type = _Tp; };
2414 struct __failure_type
2417 struct __do_common_type_impl
2419 template<typename _Tp, typename _Up>
2421 = decltype(true ? std::declval<_Tp>() : std::declval<_Up>());
2423 // if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2424 // denotes a valid type, let C denote that type.
2425 template<typename _Tp, typename _Up>
2426 static __success_type<__decay_t<__cond_t<_Tp, _Up>>>
2429 #if __cplusplus > 201703L
2430 // Otherwise, if COND-RES(CREF(D1), CREF(D2)) denotes a type,
2431 // let C denote the type decay_t<COND-RES(CREF(D1), CREF(D2))>.
2432 template<typename _Tp, typename _Up>
2433 static __success_type<__remove_cvref_t<__cond_t<const _Tp&, const _Up&>>>
2437 template<typename, typename>
2438 static __failure_type
2441 template<typename _Tp, typename _Up>
2442 static decltype(_S_test_2<_Tp, _Up>(0))
2446 // If sizeof...(T) is zero, there shall be no member type.
2448 struct common_type<>
2451 // If sizeof...(T) is one, the same type, if any, as common_type_t<T0, T0>.
2452 template<typename _Tp0>
2453 struct common_type<_Tp0>
2454 : public common_type<_Tp0, _Tp0>
2457 // If sizeof...(T) is two, ...
2458 template<typename _Tp1, typename _Tp2,
2459 typename _Dp1 = __decay_t<_Tp1>, typename _Dp2 = __decay_t<_Tp2>>
2460 struct __common_type_impl
2462 // If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false,
2463 // let C denote the same type, if any, as common_type_t<D1, D2>.
2464 using type = common_type<_Dp1, _Dp2>;
2467 template<typename _Tp1, typename _Tp2>
2468 struct __common_type_impl<_Tp1, _Tp2, _Tp1, _Tp2>
2469 : private __do_common_type_impl
2471 // Otherwise, if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2472 // denotes a valid type, let C denote that type.
2473 using type = decltype(_S_test<_Tp1, _Tp2>(0));
2476 // If sizeof...(T) is two, ...
2477 template<typename _Tp1, typename _Tp2>
2478 struct common_type<_Tp1, _Tp2>
2479 : public __common_type_impl<_Tp1, _Tp2>::type
2482 template<typename...>
2483 struct __common_type_pack
2486 template<typename, typename, typename = void>
2487 struct __common_type_fold;
2489 // If sizeof...(T) is greater than two, ...
2490 template<typename _Tp1, typename _Tp2, typename... _Rp>
2491 struct common_type<_Tp1, _Tp2, _Rp...>
2492 : public __common_type_fold<common_type<_Tp1, _Tp2>,
2493 __common_type_pack<_Rp...>>
2496 // Let C denote the same type, if any, as common_type_t<T1, T2>.
2497 // If there is such a type C, type shall denote the same type, if any,
2498 // as common_type_t<C, R...>.
2499 template<typename _CTp, typename... _Rp>
2500 struct __common_type_fold<_CTp, __common_type_pack<_Rp...>,
2501 __void_t<typename _CTp::type>>
2502 : public common_type<typename _CTp::type, _Rp...>
2505 // Otherwise, there shall be no member type.
2506 template<typename _CTp, typename _Rp>
2507 struct __common_type_fold<_CTp, _Rp, void>
2510 template<typename _Tp, bool = __is_enum(_Tp)>
2511 struct __underlying_type_impl
2513 using type = __underlying_type(_Tp);
2516 template<typename _Tp>
2517 struct __underlying_type_impl<_Tp, false>
2521 /// The underlying type of an enum.
2522 template<typename _Tp>
2523 struct underlying_type
2524 : public __underlying_type_impl<_Tp>
2527 /// @cond undocumented
2528 template<typename _Tp>
2529 struct __declval_protector
2531 static const bool __stop = false;
2535 /** Utility to simplify expressions used in unevaluated operands
2537 * @ingroup utilities
2539 template<typename _Tp>
2540 auto declval() noexcept -> decltype(__declval<_Tp>(0))
2542 static_assert(__declval_protector<_Tp>::__stop,
2543 "declval() must not be used!");
2544 return __declval<_Tp>(0);
2548 template<typename _Signature>
2551 // Sfinae-friendly result_of implementation:
2553 /// @cond undocumented
2554 struct __invoke_memfun_ref { };
2555 struct __invoke_memfun_deref { };
2556 struct __invoke_memobj_ref { };
2557 struct __invoke_memobj_deref { };
2558 struct __invoke_other { };
2560 // Associate a tag type with a specialization of __success_type.
2561 template<typename _Tp, typename _Tag>
2562 struct __result_of_success : __success_type<_Tp>
2563 { using __invoke_type = _Tag; };
2565 // [func.require] paragraph 1 bullet 1:
2566 struct __result_of_memfun_ref_impl
2568 template<typename _Fp, typename _Tp1, typename... _Args>
2569 static __result_of_success<decltype(
2570 (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...)
2571 ), __invoke_memfun_ref> _S_test(int);
2573 template<typename...>
2574 static __failure_type _S_test(...);
2577 template<typename _MemPtr, typename _Arg, typename... _Args>
2578 struct __result_of_memfun_ref
2579 : private __result_of_memfun_ref_impl
2581 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0));
2584 // [func.require] paragraph 1 bullet 2:
2585 struct __result_of_memfun_deref_impl
2587 template<typename _Fp, typename _Tp1, typename... _Args>
2588 static __result_of_success<decltype(
2589 ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...)
2590 ), __invoke_memfun_deref> _S_test(int);
2592 template<typename...>
2593 static __failure_type _S_test(...);
2596 template<typename _MemPtr, typename _Arg, typename... _Args>
2597 struct __result_of_memfun_deref
2598 : private __result_of_memfun_deref_impl
2600 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0));
2603 // [func.require] paragraph 1 bullet 3:
2604 struct __result_of_memobj_ref_impl
2606 template<typename _Fp, typename _Tp1>
2607 static __result_of_success<decltype(
2608 std::declval<_Tp1>().*std::declval<_Fp>()
2609 ), __invoke_memobj_ref> _S_test(int);
2611 template<typename, typename>
2612 static __failure_type _S_test(...);
2615 template<typename _MemPtr, typename _Arg>
2616 struct __result_of_memobj_ref
2617 : private __result_of_memobj_ref_impl
2619 using type = decltype(_S_test<_MemPtr, _Arg>(0));
2622 // [func.require] paragraph 1 bullet 4:
2623 struct __result_of_memobj_deref_impl
2625 template<typename _Fp, typename _Tp1>
2626 static __result_of_success<decltype(
2627 (*std::declval<_Tp1>()).*std::declval<_Fp>()
2628 ), __invoke_memobj_deref> _S_test(int);
2630 template<typename, typename>
2631 static __failure_type _S_test(...);
2634 template<typename _MemPtr, typename _Arg>
2635 struct __result_of_memobj_deref
2636 : private __result_of_memobj_deref_impl
2638 using type = decltype(_S_test<_MemPtr, _Arg>(0));
2641 template<typename _MemPtr, typename _Arg>
2642 struct __result_of_memobj;
2644 template<typename _Res, typename _Class, typename _Arg>
2645 struct __result_of_memobj<_Res _Class::*, _Arg>
2647 using _Argval = __remove_cvref_t<_Arg>;
2648 using _MemPtr = _Res _Class::*;
2649 using type = typename __conditional_t<__or_<is_same<_Argval, _Class>,
2650 is_base_of<_Class, _Argval>>::value,
2651 __result_of_memobj_ref<_MemPtr, _Arg>,
2652 __result_of_memobj_deref<_MemPtr, _Arg>
2656 template<typename _MemPtr, typename _Arg, typename... _Args>
2657 struct __result_of_memfun;
2659 template<typename _Res, typename _Class, typename _Arg, typename... _Args>
2660 struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
2662 using _Argval = typename remove_reference<_Arg>::type;
2663 using _MemPtr = _Res _Class::*;
2664 using type = typename __conditional_t<is_base_of<_Class, _Argval>::value,
2665 __result_of_memfun_ref<_MemPtr, _Arg, _Args...>,
2666 __result_of_memfun_deref<_MemPtr, _Arg, _Args...>
2670 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2671 // 2219. INVOKE-ing a pointer to member with a reference_wrapper
2672 // as the object expression
2674 // Used by result_of, invoke etc. to unwrap a reference_wrapper.
2675 template<typename _Tp, typename _Up = __remove_cvref_t<_Tp>>
2681 template<typename _Tp, typename _Up>
2682 struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
2687 template<bool, bool, typename _Functor, typename... _ArgTypes>
2688 struct __result_of_impl
2690 using type = __failure_type;
2693 template<typename _MemPtr, typename _Arg>
2694 struct __result_of_impl<true, false, _MemPtr, _Arg>
2695 : public __result_of_memobj<__decay_t<_MemPtr>,
2696 typename __inv_unwrap<_Arg>::type>
2699 template<typename _MemPtr, typename _Arg, typename... _Args>
2700 struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
2701 : public __result_of_memfun<__decay_t<_MemPtr>,
2702 typename __inv_unwrap<_Arg>::type, _Args...>
2705 // [func.require] paragraph 1 bullet 5:
2706 struct __result_of_other_impl
2708 template<typename _Fn, typename... _Args>
2709 static __result_of_success<decltype(
2710 std::declval<_Fn>()(std::declval<_Args>()...)
2711 ), __invoke_other> _S_test(int);
2713 template<typename...>
2714 static __failure_type _S_test(...);
2717 template<typename _Functor, typename... _ArgTypes>
2718 struct __result_of_impl<false, false, _Functor, _ArgTypes...>
2719 : private __result_of_other_impl
2721 using type = decltype(_S_test<_Functor, _ArgTypes...>(0));
2724 // __invoke_result (std::invoke_result for C++11)
2725 template<typename _Functor, typename... _ArgTypes>
2726 struct __invoke_result
2727 : public __result_of_impl<
2728 is_member_object_pointer<
2729 typename remove_reference<_Functor>::type
2731 is_member_function_pointer<
2732 typename remove_reference<_Functor>::type
2734 _Functor, _ArgTypes...
2738 // __invoke_result_t (std::invoke_result_t for C++11)
2739 template<typename _Fn, typename... _Args>
2740 using __invoke_result_t = typename __invoke_result<_Fn, _Args...>::type;
2743 template<typename _Functor, typename... _ArgTypes>
2744 struct result_of<_Functor(_ArgTypes...)>
2745 : public __invoke_result<_Functor, _ArgTypes...>
2746 { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result");
2748 #if __cplusplus >= 201402L
2749 #pragma GCC diagnostic push
2750 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2751 /// Alias template for aligned_storage
2752 template<size_t _Len, size_t _Align =
2753 __alignof__(typename __aligned_storage_msa<_Len>::__type)>
2754 using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type;
2756 template <size_t _Len, typename... _Types>
2757 using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type;
2758 #pragma GCC diagnostic pop
2760 /// Alias template for decay
2761 template<typename _Tp>
2762 using decay_t = typename decay<_Tp>::type;
2764 /// Alias template for enable_if
2765 template<bool _Cond, typename _Tp = void>
2766 using enable_if_t = typename enable_if<_Cond, _Tp>::type;
2768 /// Alias template for conditional
2769 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2770 using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type;
2772 /// Alias template for common_type
2773 template<typename... _Tp>
2774 using common_type_t = typename common_type<_Tp...>::type;
2776 /// Alias template for underlying_type
2777 template<typename _Tp>
2778 using underlying_type_t = typename underlying_type<_Tp>::type;
2780 /// Alias template for result_of
2781 template<typename _Tp>
2782 using result_of_t = typename result_of<_Tp>::type;
2785 #ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11
2786 /// A metafunction that always yields void, used for detecting valid types.
2787 template<typename...> using void_t = void;
2790 /// @cond undocumented
2793 // Detect whether _Op<_Args...> is a valid type, use default _Def if not.
2796 // Implementation of the detection idiom (negative case).
2797 template<typename _Def, template<typename...> class _Op, typename... _Args>
2798 struct __detected_or
2801 using __is_detected = false_type;
2804 // Implementation of the detection idiom (positive case).
2805 template<typename _Def, template<typename...> class _Op, typename... _Args>
2806 requires requires { typename _Op<_Args...>; }
2807 struct __detected_or<_Def, _Op, _Args...>
2809 using type = _Op<_Args...>;
2810 using __is_detected = true_type;
2813 /// Implementation of the detection idiom (negative case).
2814 template<typename _Default, typename _AlwaysVoid,
2815 template<typename...> class _Op, typename... _Args>
2818 using type = _Default;
2819 using __is_detected = false_type;
2822 /// Implementation of the detection idiom (positive case).
2823 template<typename _Default, template<typename...> class _Op,
2825 struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...>
2827 using type = _Op<_Args...>;
2828 using __is_detected = true_type;
2831 template<typename _Default, template<typename...> class _Op,
2833 using __detected_or = __detector<_Default, void, _Op, _Args...>;
2834 #endif // __cpp_concepts
2836 // _Op<_Args...> if that is a valid type, otherwise _Default.
2837 template<typename _Default, template<typename...> class _Op,
2839 using __detected_or_t
2840 = typename __detected_or<_Default, _Op, _Args...>::type;
2843 * Use SFINAE to determine if the type _Tp has a publicly-accessible
2844 * member type _NTYPE.
2846 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
2847 template<typename _Tp, typename = __void_t<>> \
2848 struct __has_##_NTYPE \
2851 template<typename _Tp> \
2852 struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \
2856 template <typename _Tp>
2857 struct __is_swappable;
2859 template <typename _Tp>
2860 struct __is_nothrow_swappable;
2863 struct __is_tuple_like_impl : false_type
2866 // Internal type trait that allows us to sfinae-protect tuple_cat.
2867 template<typename _Tp>
2868 struct __is_tuple_like
2869 : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
2873 template<typename _Tp>
2874 _GLIBCXX20_CONSTEXPR
2876 _Require<__not_<__is_tuple_like<_Tp>>,
2877 is_move_constructible<_Tp>,
2878 is_move_assignable<_Tp>>
2880 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
2881 is_nothrow_move_assignable<_Tp>>::value);
2883 template<typename _Tp, size_t _Nm>
2884 _GLIBCXX20_CONSTEXPR
2886 __enable_if_t<__is_swappable<_Tp>::value>
2887 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
2888 noexcept(__is_nothrow_swappable<_Tp>::value);
2890 /// @cond undocumented
2891 namespace __swappable_details {
2894 struct __do_is_swappable_impl
2896 template<typename _Tp, typename
2897 = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))>
2898 static true_type __test(int);
2901 static false_type __test(...);
2904 struct __do_is_nothrow_swappable_impl
2906 template<typename _Tp>
2907 static __bool_constant<
2908 noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))
2912 static false_type __test(...);
2915 } // namespace __swappable_details
2917 template<typename _Tp>
2918 struct __is_swappable_impl
2919 : public __swappable_details::__do_is_swappable_impl
2921 using type = decltype(__test<_Tp>(0));
2924 template<typename _Tp>
2925 struct __is_nothrow_swappable_impl
2926 : public __swappable_details::__do_is_nothrow_swappable_impl
2928 using type = decltype(__test<_Tp>(0));
2931 template<typename _Tp>
2932 struct __is_swappable
2933 : public __is_swappable_impl<_Tp>::type
2936 template<typename _Tp>
2937 struct __is_nothrow_swappable
2938 : public __is_nothrow_swappable_impl<_Tp>::type
2942 #ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11
2943 /// Metafunctions used for detecting swappable types: p0185r1
2946 template<typename _Tp>
2948 : public __is_swappable_impl<_Tp>::type
2950 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2951 "template argument must be a complete class or an unbounded array");
2954 /// is_nothrow_swappable
2955 template<typename _Tp>
2956 struct is_nothrow_swappable
2957 : public __is_nothrow_swappable_impl<_Tp>::type
2959 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
2960 "template argument must be a complete class or an unbounded array");
2963 #if __cplusplus >= 201402L
2965 template<typename _Tp>
2966 _GLIBCXX17_INLINE constexpr bool is_swappable_v =
2967 is_swappable<_Tp>::value;
2969 /// is_nothrow_swappable_v
2970 template<typename _Tp>
2971 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v =
2972 is_nothrow_swappable<_Tp>::value;
2973 #endif // __cplusplus >= 201402L
2975 /// @cond undocumented
2976 namespace __swappable_with_details {
2979 struct __do_is_swappable_with_impl
2981 template<typename _Tp, typename _Up, typename
2982 = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())),
2984 = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))>
2985 static true_type __test(int);
2987 template<typename, typename>
2988 static false_type __test(...);
2991 struct __do_is_nothrow_swappable_with_impl
2993 template<typename _Tp, typename _Up>
2994 static __bool_constant<
2995 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
2997 noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()))
3000 template<typename, typename>
3001 static false_type __test(...);
3004 } // namespace __swappable_with_details
3006 template<typename _Tp, typename _Up>
3007 struct __is_swappable_with_impl
3008 : public __swappable_with_details::__do_is_swappable_with_impl
3010 using type = decltype(__test<_Tp, _Up>(0));
3013 // Optimization for the homogenous lvalue case, not required:
3014 template<typename _Tp>
3015 struct __is_swappable_with_impl<_Tp&, _Tp&>
3016 : public __swappable_details::__do_is_swappable_impl
3018 using type = decltype(__test<_Tp&>(0));
3021 template<typename _Tp, typename _Up>
3022 struct __is_nothrow_swappable_with_impl
3023 : public __swappable_with_details::__do_is_nothrow_swappable_with_impl
3025 using type = decltype(__test<_Tp, _Up>(0));
3028 // Optimization for the homogenous lvalue case, not required:
3029 template<typename _Tp>
3030 struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&>
3031 : public __swappable_details::__do_is_nothrow_swappable_impl
3033 using type = decltype(__test<_Tp&>(0));
3037 /// is_swappable_with
3038 template<typename _Tp, typename _Up>
3039 struct is_swappable_with
3040 : public __is_swappable_with_impl<_Tp, _Up>::type
3042 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3043 "first template argument must be a complete class or an unbounded array");
3044 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3045 "second template argument must be a complete class or an unbounded array");
3048 /// is_nothrow_swappable_with
3049 template<typename _Tp, typename _Up>
3050 struct is_nothrow_swappable_with
3051 : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type
3053 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3054 "first template argument must be a complete class or an unbounded array");
3055 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3056 "second template argument must be a complete class or an unbounded array");
3059 #if __cplusplus >= 201402L
3060 /// is_swappable_with_v
3061 template<typename _Tp, typename _Up>
3062 _GLIBCXX17_INLINE constexpr bool is_swappable_with_v =
3063 is_swappable_with<_Tp, _Up>::value;
3065 /// is_nothrow_swappable_with_v
3066 template<typename _Tp, typename _Up>
3067 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v =
3068 is_nothrow_swappable_with<_Tp, _Up>::value;
3069 #endif // __cplusplus >= 201402L
3071 #endif // __cpp_lib_is_swappable
3073 /// @cond undocumented
3075 // __is_invocable (std::is_invocable for C++11)
3077 // The primary template is used for invalid INVOKE expressions.
3078 template<typename _Result, typename _Ret,
3079 bool = is_void<_Ret>::value, typename = void>
3080 struct __is_invocable_impl
3083 using __nothrow_conv = false_type; // For is_nothrow_invocable_r
3086 // Used for valid INVOKE and INVOKE<void> expressions.
3087 template<typename _Result, typename _Ret>
3088 struct __is_invocable_impl<_Result, _Ret,
3089 /* is_void<_Ret> = */ true,
3090 __void_t<typename _Result::type>>
3093 using __nothrow_conv = true_type; // For is_nothrow_invocable_r
3096 #pragma GCC diagnostic push
3097 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3098 // Used for INVOKE<R> expressions to check the implicit conversion to R.
3099 template<typename _Result, typename _Ret>
3100 struct __is_invocable_impl<_Result, _Ret,
3101 /* is_void<_Ret> = */ false,
3102 __void_t<typename _Result::type>>
3105 // The type of the INVOKE expression.
3106 using _Res_t = typename _Result::type;
3108 // Unlike declval, this doesn't add_rvalue_reference, so it respects
3109 // guaranteed copy elision.
3110 static _Res_t _S_get() noexcept;
3112 // Used to check if _Res_t can implicitly convert to _Tp.
3113 template<typename _Tp>
3114 static void _S_conv(__type_identity_t<_Tp>) noexcept;
3116 // This overload is viable if INVOKE(f, args...) can convert to _Tp.
3117 template<typename _Tp,
3118 bool _Nothrow = noexcept(_S_conv<_Tp>(_S_get())),
3119 typename = decltype(_S_conv<_Tp>(_S_get())),
3120 #if __has_builtin(__reference_converts_from_temporary)
3121 bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t)
3123 bool _Dangle = false
3126 static __bool_constant<_Nothrow && !_Dangle>
3129 template<typename _Tp, bool = false>
3134 // For is_invocable_r
3135 using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1));
3137 // For is_nothrow_invocable_r
3138 using __nothrow_conv = decltype(_S_test<_Ret>(1));
3140 #pragma GCC diagnostic pop
3142 template<typename _Fn, typename... _ArgTypes>
3143 struct __is_invocable
3144 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3147 template<typename _Fn, typename _Tp, typename... _Args>
3148 constexpr bool __call_is_nt(__invoke_memfun_ref)
3150 using _Up = typename __inv_unwrap<_Tp>::type;
3151 return noexcept((std::declval<_Up>().*std::declval<_Fn>())(
3152 std::declval<_Args>()...));
3155 template<typename _Fn, typename _Tp, typename... _Args>
3156 constexpr bool __call_is_nt(__invoke_memfun_deref)
3158 return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())(
3159 std::declval<_Args>()...));
3162 template<typename _Fn, typename _Tp>
3163 constexpr bool __call_is_nt(__invoke_memobj_ref)
3165 using _Up = typename __inv_unwrap<_Tp>::type;
3166 return noexcept(std::declval<_Up>().*std::declval<_Fn>());
3169 template<typename _Fn, typename _Tp>
3170 constexpr bool __call_is_nt(__invoke_memobj_deref)
3172 return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>());
3175 template<typename _Fn, typename... _Args>
3176 constexpr bool __call_is_nt(__invoke_other)
3178 return noexcept(std::declval<_Fn>()(std::declval<_Args>()...));
3181 template<typename _Result, typename _Fn, typename... _Args>
3182 struct __call_is_nothrow
3184 std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{})
3188 template<typename _Fn, typename... _Args>
3189 using __call_is_nothrow_
3190 = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
3192 // __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
3193 template<typename _Fn, typename... _Args>
3194 struct __is_nothrow_invocable
3195 : __and_<__is_invocable<_Fn, _Args...>,
3196 __call_is_nothrow_<_Fn, _Args...>>::type
3199 #pragma GCC diagnostic push
3200 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3201 struct __nonesuchbase {};
3202 struct __nonesuch : private __nonesuchbase {
3203 ~__nonesuch() = delete;
3204 __nonesuch(__nonesuch const&) = delete;
3205 void operator=(__nonesuch const&) = delete;
3207 #pragma GCC diagnostic pop
3210 #ifdef __cpp_lib_is_invocable // C++ >= 17
3211 /// std::invoke_result
3212 template<typename _Functor, typename... _ArgTypes>
3213 struct invoke_result
3214 : public __invoke_result<_Functor, _ArgTypes...>
3216 static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}),
3217 "_Functor must be a complete class or an unbounded array");
3218 static_assert((std::__is_complete_or_unbounded(
3219 __type_identity<_ArgTypes>{}) && ...),
3220 "each argument type must be a complete class or an unbounded array");
3223 /// std::invoke_result_t
3224 template<typename _Fn, typename... _Args>
3225 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
3227 /// std::is_invocable
3228 template<typename _Fn, typename... _ArgTypes>
3230 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
3231 : public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
3233 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3236 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3237 "_Fn must be a complete class or an unbounded array");
3238 static_assert((std::__is_complete_or_unbounded(
3239 __type_identity<_ArgTypes>{}) && ...),
3240 "each argument type must be a complete class or an unbounded array");
3243 /// std::is_invocable_r
3244 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3245 struct is_invocable_r
3246 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type
3248 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3249 "_Fn must be a complete class or an unbounded array");
3250 static_assert((std::__is_complete_or_unbounded(
3251 __type_identity<_ArgTypes>{}) && ...),
3252 "each argument type must be a complete class or an unbounded array");
3253 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3254 "_Ret must be a complete class or an unbounded array");
3257 /// std::is_nothrow_invocable
3258 template<typename _Fn, typename... _ArgTypes>
3259 struct is_nothrow_invocable
3260 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
3261 : public __bool_constant<__is_nothrow_invocable(_Fn, _ArgTypes...)>
3263 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
3264 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3267 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3268 "_Fn must be a complete class or an unbounded array");
3269 static_assert((std::__is_complete_or_unbounded(
3270 __type_identity<_ArgTypes>{}) && ...),
3271 "each argument type must be a complete class or an unbounded array");
3274 /// @cond undocumented
3275 // This checks that the INVOKE<R> expression is well-formed and that the
3276 // conversion to R does not throw. It does *not* check whether the INVOKE
3277 // expression itself can throw. That is done by __call_is_nothrow_ instead.
3278 template<typename _Result, typename _Ret>
3279 using __is_nt_invocable_impl
3280 = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv;
3283 /// std::is_nothrow_invocable_r
3284 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3285 struct is_nothrow_invocable_r
3286 : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>,
3287 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3289 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3290 "_Fn must be a complete class or an unbounded array");
3291 static_assert((std::__is_complete_or_unbounded(
3292 __type_identity<_ArgTypes>{}) && ...),
3293 "each argument type must be a complete class or an unbounded array");
3294 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3295 "_Ret must be a complete class or an unbounded array");
3297 #endif // __cpp_lib_is_invocable
3299 #if __cpp_lib_type_trait_variable_templates // C++ >= 17
3301 * @defgroup variable_templates Variable templates for type traits
3302 * @ingroup metaprogramming
3304 * Each variable `is_xxx_v<T>` is a boolean constant with the same value
3305 * as the `value` member of the corresponding type trait `is_xxx<T>`.
3307 * @since C++17 unless noted otherwise.
3312 * @ingroup variable_templates
3314 template <typename _Tp>
3315 inline constexpr bool is_void_v = is_void<_Tp>::value;
3316 template <typename _Tp>
3317 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
3318 template <typename _Tp>
3319 inline constexpr bool is_integral_v = is_integral<_Tp>::value;
3320 template <typename _Tp>
3321 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
3323 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
3324 template <typename _Tp>
3325 inline constexpr bool is_array_v = __is_array(_Tp);
3327 template <typename _Tp>
3328 inline constexpr bool is_array_v = false;
3329 template <typename _Tp>
3330 inline constexpr bool is_array_v<_Tp[]> = true;
3331 template <typename _Tp, size_t _Num>
3332 inline constexpr bool is_array_v<_Tp[_Num]> = true;
3335 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
3336 template <typename _Tp>
3337 inline constexpr bool is_pointer_v = __is_pointer(_Tp);
3339 template <typename _Tp>
3340 inline constexpr bool is_pointer_v = false;
3341 template <typename _Tp>
3342 inline constexpr bool is_pointer_v<_Tp*> = true;
3343 template <typename _Tp>
3344 inline constexpr bool is_pointer_v<_Tp* const> = true;
3345 template <typename _Tp>
3346 inline constexpr bool is_pointer_v<_Tp* volatile> = true;
3347 template <typename _Tp>
3348 inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
3351 template <typename _Tp>
3352 inline constexpr bool is_lvalue_reference_v = false;
3353 template <typename _Tp>
3354 inline constexpr bool is_lvalue_reference_v<_Tp&> = true;
3355 template <typename _Tp>
3356 inline constexpr bool is_rvalue_reference_v = false;
3357 template <typename _Tp>
3358 inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
3360 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
3361 template <typename _Tp>
3362 inline constexpr bool is_member_object_pointer_v =
3363 __is_member_object_pointer(_Tp);
3365 template <typename _Tp>
3366 inline constexpr bool is_member_object_pointer_v =
3367 is_member_object_pointer<_Tp>::value;
3370 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
3371 template <typename _Tp>
3372 inline constexpr bool is_member_function_pointer_v =
3373 __is_member_function_pointer(_Tp);
3375 template <typename _Tp>
3376 inline constexpr bool is_member_function_pointer_v =
3377 is_member_function_pointer<_Tp>::value;
3380 template <typename _Tp>
3381 inline constexpr bool is_enum_v = __is_enum(_Tp);
3382 template <typename _Tp>
3383 inline constexpr bool is_union_v = __is_union(_Tp);
3384 template <typename _Tp>
3385 inline constexpr bool is_class_v = __is_class(_Tp);
3386 // is_function_v is defined below, after is_const_v.
3388 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
3389 template <typename _Tp>
3390 inline constexpr bool is_reference_v = __is_reference(_Tp);
3392 template <typename _Tp>
3393 inline constexpr bool is_reference_v = false;
3394 template <typename _Tp>
3395 inline constexpr bool is_reference_v<_Tp&> = true;
3396 template <typename _Tp>
3397 inline constexpr bool is_reference_v<_Tp&&> = true;
3400 template <typename _Tp>
3401 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
3402 template <typename _Tp>
3403 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
3405 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
3406 template <typename _Tp>
3407 inline constexpr bool is_object_v = __is_object(_Tp);
3409 template <typename _Tp>
3410 inline constexpr bool is_object_v = is_object<_Tp>::value;
3413 template <typename _Tp>
3414 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
3415 template <typename _Tp>
3416 inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
3418 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
3419 template <typename _Tp>
3420 inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
3422 template <typename _Tp>
3423 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
3426 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
3427 template <typename _Tp>
3428 inline constexpr bool is_const_v = __is_const(_Tp);
3430 template <typename _Tp>
3431 inline constexpr bool is_const_v = false;
3432 template <typename _Tp>
3433 inline constexpr bool is_const_v<const _Tp> = true;
3436 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
3437 template <typename _Tp>
3438 inline constexpr bool is_function_v = __is_function(_Tp);
3440 template <typename _Tp>
3441 inline constexpr bool is_function_v = !is_const_v<const _Tp>;
3442 template <typename _Tp>
3443 inline constexpr bool is_function_v<_Tp&> = false;
3444 template <typename _Tp>
3445 inline constexpr bool is_function_v<_Tp&&> = false;
3448 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
3449 template <typename _Tp>
3450 inline constexpr bool is_volatile_v = __is_volatile(_Tp);
3452 template <typename _Tp>
3453 inline constexpr bool is_volatile_v = false;
3454 template <typename _Tp>
3455 inline constexpr bool is_volatile_v<volatile _Tp> = true;
3458 template <typename _Tp>
3459 inline constexpr bool is_trivial_v = __is_trivial(_Tp);
3460 template <typename _Tp>
3461 inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
3462 template <typename _Tp>
3463 inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
3464 template <typename _Tp>
3465 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v")
3466 inline constexpr bool is_pod_v = __is_pod(_Tp);
3467 template <typename _Tp>
3468 _GLIBCXX17_DEPRECATED
3469 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
3470 template <typename _Tp>
3471 inline constexpr bool is_empty_v = __is_empty(_Tp);
3472 template <typename _Tp>
3473 inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
3474 template <typename _Tp>
3475 inline constexpr bool is_abstract_v = __is_abstract(_Tp);
3476 template <typename _Tp>
3477 inline constexpr bool is_final_v = __is_final(_Tp);
3479 template <typename _Tp>
3480 inline constexpr bool is_signed_v = is_signed<_Tp>::value;
3481 template <typename _Tp>
3482 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
3484 template <typename _Tp, typename... _Args>
3485 inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
3486 template <typename _Tp>
3487 inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
3488 template <typename _Tp>
3489 inline constexpr bool is_copy_constructible_v
3490 = __is_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3491 template <typename _Tp>
3492 inline constexpr bool is_move_constructible_v
3493 = __is_constructible(_Tp, __add_rval_ref_t<_Tp>);
3495 template <typename _Tp, typename _Up>
3496 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up);
3497 template <typename _Tp>
3498 inline constexpr bool is_copy_assignable_v
3499 = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t<const _Tp>);
3500 template <typename _Tp>
3501 inline constexpr bool is_move_assignable_v
3502 = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3504 template <typename _Tp>
3505 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
3507 template <typename _Tp, typename... _Args>
3508 inline constexpr bool is_trivially_constructible_v
3509 = __is_trivially_constructible(_Tp, _Args...);
3510 template <typename _Tp>
3511 inline constexpr bool is_trivially_default_constructible_v
3512 = __is_trivially_constructible(_Tp);
3513 template <typename _Tp>
3514 inline constexpr bool is_trivially_copy_constructible_v
3515 = __is_trivially_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3516 template <typename _Tp>
3517 inline constexpr bool is_trivially_move_constructible_v
3518 = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>);
3520 template <typename _Tp, typename _Up>
3521 inline constexpr bool is_trivially_assignable_v
3522 = __is_trivially_assignable(_Tp, _Up);
3523 template <typename _Tp>
3524 inline constexpr bool is_trivially_copy_assignable_v
3525 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3526 __add_lval_ref_t<const _Tp>);
3527 template <typename _Tp>
3528 inline constexpr bool is_trivially_move_assignable_v
3529 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3530 __add_rval_ref_t<_Tp>);
3533 template <typename _Tp>
3534 inline constexpr bool is_trivially_destructible_v = false;
3536 template <typename _Tp>
3537 requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); }
3538 inline constexpr bool is_trivially_destructible_v<_Tp>
3539 = __has_trivial_destructor(_Tp);
3540 template <typename _Tp>
3541 inline constexpr bool is_trivially_destructible_v<_Tp&> = true;
3542 template <typename _Tp>
3543 inline constexpr bool is_trivially_destructible_v<_Tp&&> = true;
3544 template <typename _Tp, size_t _Nm>
3545 inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]>
3546 = is_trivially_destructible_v<_Tp>;
3548 template <typename _Tp>
3549 inline constexpr bool is_trivially_destructible_v =
3550 is_trivially_destructible<_Tp>::value;
3553 template <typename _Tp, typename... _Args>
3554 inline constexpr bool is_nothrow_constructible_v
3555 = __is_nothrow_constructible(_Tp, _Args...);
3556 template <typename _Tp>
3557 inline constexpr bool is_nothrow_default_constructible_v
3558 = __is_nothrow_constructible(_Tp);
3559 template <typename _Tp>
3560 inline constexpr bool is_nothrow_copy_constructible_v
3561 = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3562 template <typename _Tp>
3563 inline constexpr bool is_nothrow_move_constructible_v
3564 = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>);
3566 template <typename _Tp, typename _Up>
3567 inline constexpr bool is_nothrow_assignable_v
3568 = __is_nothrow_assignable(_Tp, _Up);
3569 template <typename _Tp>
3570 inline constexpr bool is_nothrow_copy_assignable_v
3571 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>,
3572 __add_lval_ref_t<const _Tp>);
3573 template <typename _Tp>
3574 inline constexpr bool is_nothrow_move_assignable_v
3575 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3577 template <typename _Tp>
3578 inline constexpr bool is_nothrow_destructible_v =
3579 is_nothrow_destructible<_Tp>::value;
3581 template <typename _Tp>
3582 inline constexpr bool has_virtual_destructor_v
3583 = __has_virtual_destructor(_Tp);
3585 template <typename _Tp>
3586 inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
3588 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank)
3589 template <typename _Tp>
3590 inline constexpr size_t rank_v = __array_rank(_Tp);
3592 template <typename _Tp>
3593 inline constexpr size_t rank_v = 0;
3594 template <typename _Tp, size_t _Size>
3595 inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>;
3596 template <typename _Tp>
3597 inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>;
3600 template <typename _Tp, unsigned _Idx = 0>
3601 inline constexpr size_t extent_v = 0;
3602 template <typename _Tp, size_t _Size>
3603 inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size;
3604 template <typename _Tp, unsigned _Idx, size_t _Size>
3605 inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>;
3606 template <typename _Tp>
3607 inline constexpr size_t extent_v<_Tp[], 0> = 0;
3608 template <typename _Tp, unsigned _Idx>
3609 inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>;
3611 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same)
3612 template <typename _Tp, typename _Up>
3613 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
3615 template <typename _Tp, typename _Up>
3616 inline constexpr bool is_same_v = false;
3617 template <typename _Tp>
3618 inline constexpr bool is_same_v<_Tp, _Tp> = true;
3620 template <typename _Base, typename _Derived>
3621 inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
3622 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
3623 template <typename _From, typename _To>
3624 inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
3626 template <typename _From, typename _To>
3627 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
3629 template<typename _Fn, typename... _Args>
3630 inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
3631 template<typename _Fn, typename... _Args>
3632 inline constexpr bool is_nothrow_invocable_v
3633 = is_nothrow_invocable<_Fn, _Args...>::value;
3634 template<typename _Ret, typename _Fn, typename... _Args>
3635 inline constexpr bool is_invocable_r_v
3636 = is_invocable_r<_Ret, _Fn, _Args...>::value;
3637 template<typename _Ret, typename _Fn, typename... _Args>
3638 inline constexpr bool is_nothrow_invocable_r_v
3639 = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
3641 #endif // __cpp_lib_type_trait_variable_templates
3643 #ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP
3644 /// has_unique_object_representations
3646 template<typename _Tp>
3647 struct has_unique_object_representations
3648 : bool_constant<__has_unique_object_representations(
3649 remove_cv_t<remove_all_extents_t<_Tp>>
3652 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3653 "template argument must be a complete class or an unbounded array");
3656 # if __cpp_lib_type_trait_variable_templates // C++ >= 17
3657 /// @ingroup variable_templates
3658 template<typename _Tp>
3659 inline constexpr bool has_unique_object_representations_v
3660 = has_unique_object_representations<_Tp>::value;
3664 #ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate
3665 /// is_aggregate - true if the type is an aggregate.
3667 template<typename _Tp>
3669 : bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
3672 # if __cpp_lib_type_trait_variable_templates // C++ >= 17
3673 /** is_aggregate_v - true if the type is an aggregate.
3674 * @ingroup variable_templates
3677 template<typename _Tp>
3678 inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>);
3682 /** * Remove references and cv-qualifiers.
3686 #ifdef __cpp_lib_remove_cvref // C++ >= 20
3687 # if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref)
3688 template<typename _Tp>
3690 { using type = __remove_cvref(_Tp); };
3692 template<typename _Tp>
3694 { using type = typename remove_cv<_Tp>::type; };
3696 template<typename _Tp>
3697 struct remove_cvref<_Tp&>
3698 { using type = typename remove_cv<_Tp>::type; };
3700 template<typename _Tp>
3701 struct remove_cvref<_Tp&&>
3702 { using type = typename remove_cv<_Tp>::type; };
3705 template<typename _Tp>
3706 using remove_cvref_t = typename remove_cvref<_Tp>::type;
3708 #endif // __cpp_lib_remove_cvref
3710 #ifdef __cpp_lib_type_identity // C++ >= 20
3711 /** * Identity metafunction.
3715 template<typename _Tp>
3716 struct type_identity { using type = _Tp; };
3718 template<typename _Tp>
3719 using type_identity_t = typename type_identity<_Tp>::type;
3723 #ifdef __cpp_lib_unwrap_ref // C++ >= 20
3724 /** Unwrap a reference_wrapper
3728 template<typename _Tp>
3729 struct unwrap_reference { using type = _Tp; };
3731 template<typename _Tp>
3732 struct unwrap_reference<reference_wrapper<_Tp>> { using type = _Tp&; };
3734 template<typename _Tp>
3735 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
3738 /** Decay type and if it's a reference_wrapper, unwrap it
3742 template<typename _Tp>
3743 struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; };
3745 template<typename _Tp>
3746 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
3748 #endif // __cpp_lib_unwrap_ref
3750 #ifdef __cpp_lib_bounded_array_traits // C++ >= 20
3751 /// True for a type that is an array of known bound.
3752 /// @ingroup variable_templates
3754 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
3755 template<typename _Tp>
3756 inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
3758 template<typename _Tp>
3759 inline constexpr bool is_bounded_array_v = false;
3761 template<typename _Tp, size_t _Size>
3762 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
3765 /// True for a type that is an array of unknown bound.
3766 /// @ingroup variable_templates
3768 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
3769 template<typename _Tp>
3770 inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
3772 template<typename _Tp>
3773 inline constexpr bool is_unbounded_array_v = false;
3775 template<typename _Tp>
3776 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
3779 /// True for a type that is an array of known bound.
3781 template<typename _Tp>
3782 struct is_bounded_array
3783 : public bool_constant<is_bounded_array_v<_Tp>>
3786 /// True for a type that is an array of unknown bound.
3788 template<typename _Tp>
3789 struct is_unbounded_array
3790 : public bool_constant<is_unbounded_array_v<_Tp>>
3792 #endif // __cpp_lib_bounded_array_traits
3794 #if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L
3797 template<typename _Tp, typename _Up>
3798 struct is_layout_compatible
3799 : bool_constant<__is_layout_compatible(_Tp, _Up)>
3802 /// @ingroup variable_templates
3804 template<typename _Tp, typename _Up>
3805 constexpr bool is_layout_compatible_v
3806 = __is_layout_compatible(_Tp, _Up);
3808 #if __has_builtin(__builtin_is_corresponding_member)
3809 # ifndef __cpp_lib_is_layout_compatible
3810 # error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set"
3814 template<typename _S1, typename _S2, typename _M1, typename _M2>
3816 is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept
3817 { return __builtin_is_corresponding_member(__m1, __m2); }
3821 #if __has_builtin(__is_pointer_interconvertible_base_of) \
3822 && __cplusplus >= 202002L
3823 /// True if `_Derived` is standard-layout and has a base class of type `_Base`
3825 template<typename _Base, typename _Derived>
3826 struct is_pointer_interconvertible_base_of
3827 : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)>
3830 /// @ingroup variable_templates
3832 template<typename _Base, typename _Derived>
3833 constexpr bool is_pointer_interconvertible_base_of_v
3834 = __is_pointer_interconvertible_base_of(_Base, _Derived);
3836 #if __has_builtin(__builtin_is_pointer_interconvertible_with_class)
3837 # ifndef __cpp_lib_is_pointer_interconvertible
3838 # error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set"
3841 /// True if `__mp` points to the first member of a standard-layout type
3842 /// @returns true if `s.*__mp` is pointer-interconvertible with `s`
3844 template<typename _Tp, typename _Mem>
3846 is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept
3847 { return __builtin_is_pointer_interconvertible_with_class(__mp); }
3851 #ifdef __cpp_lib_is_scoped_enum // C++ >= 23
3852 /// True if the type is a scoped enumeration type.
3855 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
3856 template<typename _Tp>
3857 struct is_scoped_enum
3858 : bool_constant<__is_scoped_enum(_Tp)>
3861 template<typename _Tp>
3862 struct is_scoped_enum
3866 template<typename _Tp>
3867 requires __is_enum(_Tp)
3868 && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete
3869 struct is_scoped_enum<_Tp>
3870 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
3874 /// @ingroup variable_templates
3876 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
3877 template<typename _Tp>
3878 inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
3880 template<typename _Tp>
3881 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
3885 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp
3886 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
3887 /// direct-initialization, and a temporary object would be bound to
3888 /// the reference, false otherwise.
3890 template<typename _Tp, typename _Up>
3891 struct reference_constructs_from_temporary
3892 : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)>
3894 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
3895 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3896 "template argument must be a complete class or an unbounded array");
3899 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
3900 /// copy-initialization, and a temporary object would be bound to
3901 /// the reference, false otherwise.
3903 template<typename _Tp, typename _Up>
3904 struct reference_converts_from_temporary
3905 : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)>
3907 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
3908 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3909 "template argument must be a complete class or an unbounded array");
3912 /// @ingroup variable_templates
3914 template<typename _Tp, typename _Up>
3915 inline constexpr bool reference_constructs_from_temporary_v
3916 = reference_constructs_from_temporary<_Tp, _Up>::value;
3918 /// @ingroup variable_templates
3920 template<typename _Tp, typename _Up>
3921 inline constexpr bool reference_converts_from_temporary_v
3922 = reference_converts_from_temporary<_Tp, _Up>::value;
3923 #endif // __cpp_lib_reference_from_temporary
3925 #ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL
3926 /// Returns true only when called during constant evaluation.
3928 constexpr inline bool
3929 is_constant_evaluated() noexcept
3931 #if __cpp_if_consteval >= 202106L
3932 if consteval { return true; } else { return false; }
3934 return __builtin_is_constant_evaluated();
3939 #if __cplusplus >= 202002L
3940 /// @cond undocumented
3941 template<typename _From, typename _To>
3942 using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type;
3944 template<typename _Xp, typename _Yp>
3946 = decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
3948 template<typename _Ap, typename _Bp, typename = void>
3949 struct __common_ref_impl
3952 // [meta.trans.other], COMMON-REF(A, B)
3953 template<typename _Ap, typename _Bp>
3954 using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type;
3956 // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &)
3957 template<typename _Xp, typename _Yp>
3958 using __condres_cvref
3959 = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>;
3961 // If A and B are both lvalue reference types, ...
3962 template<typename _Xp, typename _Yp>
3963 struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>>
3964 : enable_if<is_reference_v<__condres_cvref<_Xp, _Yp>>,
3965 __condres_cvref<_Xp, _Yp>>
3968 // let C be remove_reference_t<COMMON-REF(X&, Y&)>&&
3969 template<typename _Xp, typename _Yp>
3970 using __common_ref_C = remove_reference_t<__common_ref<_Xp&, _Yp&>>&&;
3972 // If A and B are both rvalue reference types, ...
3973 template<typename _Xp, typename _Yp>
3974 struct __common_ref_impl<_Xp&&, _Yp&&,
3975 _Require<is_convertible<_Xp&&, __common_ref_C<_Xp, _Yp>>,
3976 is_convertible<_Yp&&, __common_ref_C<_Xp, _Yp>>>>
3977 { using type = __common_ref_C<_Xp, _Yp>; };
3979 // let D be COMMON-REF(const X&, Y&)
3980 template<typename _Xp, typename _Yp>
3981 using __common_ref_D = __common_ref<const _Xp&, _Yp&>;
3983 // If A is an rvalue reference and B is an lvalue reference, ...
3984 template<typename _Xp, typename _Yp>
3985 struct __common_ref_impl<_Xp&&, _Yp&,
3986 _Require<is_convertible<_Xp&&, __common_ref_D<_Xp, _Yp>>>>
3987 { using type = __common_ref_D<_Xp, _Yp>; };
3989 // If A is an lvalue reference and B is an rvalue reference, ...
3990 template<typename _Xp, typename _Yp>
3991 struct __common_ref_impl<_Xp&, _Yp&&>
3992 : __common_ref_impl<_Yp&&, _Xp&>
3996 template<typename _Tp, typename _Up,
3997 template<typename> class _TQual, template<typename> class _UQual>
3998 struct basic_common_reference
4001 /// @cond undocumented
4002 template<typename _Tp>
4004 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>; };
4006 template<typename _Tp>
4008 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&; };
4010 template<typename _Tp>
4011 struct __xref<_Tp&&>
4012 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&&; };
4014 template<typename _Tp1, typename _Tp2>
4015 using __basic_common_ref
4016 = typename basic_common_reference<remove_cvref_t<_Tp1>,
4017 remove_cvref_t<_Tp2>,
4018 __xref<_Tp1>::template __type,
4019 __xref<_Tp2>::template __type>::type;
4022 template<typename... _Tp>
4023 struct common_reference;
4025 template<typename... _Tp>
4026 using common_reference_t = typename common_reference<_Tp...>::type;
4028 // If sizeof...(T) is zero, there shall be no member type.
4030 struct common_reference<>
4033 // If sizeof...(T) is one ...
4034 template<typename _Tp0>
4035 struct common_reference<_Tp0>
4036 { using type = _Tp0; };
4038 /// @cond undocumented
4039 template<typename _Tp1, typename _Tp2, int _Bullet = 1, typename = void>
4040 struct __common_reference_impl
4041 : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1>
4044 // If sizeof...(T) is two ...
4045 template<typename _Tp1, typename _Tp2>
4046 struct common_reference<_Tp1, _Tp2>
4047 : __common_reference_impl<_Tp1, _Tp2>
4050 // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ...
4051 template<typename _Tp1, typename _Tp2>
4052 struct __common_reference_impl<_Tp1&, _Tp2&, 1,
4053 void_t<__common_ref<_Tp1&, _Tp2&>>>
4054 { using type = __common_ref<_Tp1&, _Tp2&>; };
4056 template<typename _Tp1, typename _Tp2>
4057 struct __common_reference_impl<_Tp1&&, _Tp2&&, 1,
4058 void_t<__common_ref<_Tp1&&, _Tp2&&>>>
4059 { using type = __common_ref<_Tp1&&, _Tp2&&>; };
4061 template<typename _Tp1, typename _Tp2>
4062 struct __common_reference_impl<_Tp1&, _Tp2&&, 1,
4063 void_t<__common_ref<_Tp1&, _Tp2&&>>>
4064 { using type = __common_ref<_Tp1&, _Tp2&&>; };
4066 template<typename _Tp1, typename _Tp2>
4067 struct __common_reference_impl<_Tp1&&, _Tp2&, 1,
4068 void_t<__common_ref<_Tp1&&, _Tp2&>>>
4069 { using type = __common_ref<_Tp1&&, _Tp2&>; };
4071 // Otherwise, if basic_common_reference<...>::type is well-formed, ...
4072 template<typename _Tp1, typename _Tp2>
4073 struct __common_reference_impl<_Tp1, _Tp2, 2,
4074 void_t<__basic_common_ref<_Tp1, _Tp2>>>
4075 { using type = __basic_common_ref<_Tp1, _Tp2>; };
4077 // Otherwise, if COND-RES(T1, T2) is well-formed, ...
4078 template<typename _Tp1, typename _Tp2>
4079 struct __common_reference_impl<_Tp1, _Tp2, 3,
4080 void_t<__cond_res<_Tp1, _Tp2>>>
4081 { using type = __cond_res<_Tp1, _Tp2>; };
4083 // Otherwise, if common_type_t<T1, T2> is well-formed, ...
4084 template<typename _Tp1, typename _Tp2>
4085 struct __common_reference_impl<_Tp1, _Tp2, 4,
4086 void_t<common_type_t<_Tp1, _Tp2>>>
4087 { using type = common_type_t<_Tp1, _Tp2>; };
4089 // Otherwise, there shall be no member type.
4090 template<typename _Tp1, typename _Tp2>
4091 struct __common_reference_impl<_Tp1, _Tp2, 5, void>
4094 // Otherwise, if sizeof...(T) is greater than two, ...
4095 template<typename _Tp1, typename _Tp2, typename... _Rest>
4096 struct common_reference<_Tp1, _Tp2, _Rest...>
4097 : __common_type_fold<common_reference<_Tp1, _Tp2>,
4098 __common_type_pack<_Rest...>>
4101 // Reuse __common_type_fold for common_reference<T1, T2, Rest...>
4102 template<typename _Tp1, typename _Tp2, typename... _Rest>
4103 struct __common_type_fold<common_reference<_Tp1, _Tp2>,
4104 __common_type_pack<_Rest...>,
4105 void_t<common_reference_t<_Tp1, _Tp2>>>
4106 : public common_reference<common_reference_t<_Tp1, _Tp2>, _Rest...>
4112 /// @} group metaprogramming
4114 _GLIBCXX_END_NAMESPACE_VERSION
4120 #endif // _GLIBCXX_TYPE_TRAITS