1 // C++11 <type_traits> -*- C++ -*-
3 // Copyright (C) 2007-2025 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 #ifdef _GLIBCXX_SYSHDR
33 #pragma GCC system_header
36 #if __cplusplus < 201103L
37 # include <bits/c++0x_warning.h>
40 #include <bits/c++config.h>
42 #define __glibcxx_want_bool_constant
43 #define __glibcxx_want_bounded_array_traits
44 #define __glibcxx_want_common_reference
45 #define __glibcxx_want_has_unique_object_representations
46 #define __glibcxx_want_integral_constant_callable
47 #define __glibcxx_want_is_aggregate
48 #define __glibcxx_want_is_constant_evaluated
49 #define __glibcxx_want_is_final
50 #define __glibcxx_want_is_invocable
51 #define __glibcxx_want_is_layout_compatible
52 #define __glibcxx_want_is_nothrow_convertible
53 #define __glibcxx_want_is_null_pointer
54 #define __glibcxx_want_is_pointer_interconvertible
55 #define __glibcxx_want_is_scoped_enum
56 #define __glibcxx_want_is_swappable
57 #define __glibcxx_want_is_virtual_base_of
58 #define __glibcxx_want_logical_traits
59 #define __glibcxx_want_reference_from_temporary
60 #define __glibcxx_want_remove_cvref
61 #define __glibcxx_want_result_of_sfinae
62 #define __glibcxx_want_transformation_trait_aliases
63 #define __glibcxx_want_type_identity
64 #define __glibcxx_want_type_trait_variable_templates
65 #define __glibcxx_want_unwrap_ref
66 #define __glibcxx_want_void_t
67 #include <bits/version.h>
71 namespace std _GLIBCXX_VISIBILITY(default)
73 _GLIBCXX_BEGIN_NAMESPACE_VERSION
75 template<typename _Tp>
76 class reference_wrapper;
79 * @defgroup metaprogramming Metaprogramming
82 * Template utilities for compile-time introspection and modification,
83 * including type classification traits, type property inspection traits
84 * and type transformation traits.
92 template<typename _Tp, _Tp __v>
93 struct integral_constant
95 static constexpr _Tp value = __v;
96 using value_type = _Tp;
97 using type = integral_constant<_Tp, __v>;
98 constexpr operator value_type() const noexcept { return value; }
100 #ifdef __cpp_lib_integral_constant_callable // C++ >= 14
101 constexpr value_type operator()() const noexcept { return value; }
105 #if ! __cpp_inline_variables
106 template<typename _Tp, _Tp __v>
107 constexpr _Tp integral_constant<_Tp, __v>::value;
110 /// @cond undocumented
111 /// bool_constant for C++11
113 using __bool_constant = integral_constant<bool, __v>;
116 /// The type used as a compile-time boolean with true value.
117 using true_type = __bool_constant<true>;
119 /// The type used as a compile-time boolean with false value.
120 using false_type = __bool_constant<false>;
122 #ifdef __cpp_lib_bool_constant // C++ >= 17
123 /// Alias template for compile-time boolean constant types.
126 using bool_constant = __bool_constant<__v>;
129 // Metaprogramming helper types.
132 /// Define a member typedef `type` only if a boolean constant is true.
133 template<bool, typename _Tp = void>
137 // Partial specialization for true.
138 template<typename _Tp>
139 struct enable_if<true, _Tp>
140 { using type = _Tp; };
142 // __enable_if_t (std::enable_if_t for C++11)
143 template<bool _Cond, typename _Tp = void>
144 using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
149 template<typename _Tp, typename>
154 struct __conditional<false>
156 template<typename, typename _Up>
160 // More efficient version of std::conditional_t for internal use (and C++11)
161 template<bool _Cond, typename _If, typename _Else>
162 using __conditional_t
163 = typename __conditional<_Cond>::template type<_If, _Else>;
165 /// @cond undocumented
166 template <typename _Type>
167 struct __type_identity
168 { using type = _Type; };
170 template<typename _Tp>
171 using __type_identity_t = typename __type_identity<_Tp>::type;
175 // A variadic alias template that resolves to its first argument.
176 template<typename _Tp, typename...>
177 using __first_t = _Tp;
179 // These are deliberately not defined.
180 template<typename... _Bn>
181 auto __or_fn(int) -> __first_t<false_type,
182 __enable_if_t<!bool(_Bn::value)>...>;
184 template<typename... _Bn>
185 auto __or_fn(...) -> true_type;
187 template<typename... _Bn>
188 auto __and_fn(int) -> __first_t<true_type,
189 __enable_if_t<bool(_Bn::value)>...>;
191 template<typename... _Bn>
192 auto __and_fn(...) -> false_type;
193 } // namespace detail
195 // Like C++17 std::dis/conjunction, but usable in C++11 and resolves
196 // to either true_type or false_type which allows for a more efficient
197 // implementation that avoids recursive class template instantiation.
198 template<typename... _Bn>
200 : decltype(__detail::__or_fn<_Bn...>(0))
203 template<typename... _Bn>
205 : decltype(__detail::__and_fn<_Bn...>(0))
208 template<typename _Pp>
210 : __bool_constant<!bool(_Pp::value)>
214 #ifdef __cpp_lib_logical_traits // C++ >= 17
216 /// @cond undocumented
217 template<typename... _Bn>
218 inline constexpr bool __or_v = __or_<_Bn...>::value;
219 template<typename... _Bn>
220 inline constexpr bool __and_v = __and_<_Bn...>::value;
224 template<typename /* = void */, typename _B1, typename... _Bn>
225 struct __disjunction_impl
226 { using type = _B1; };
228 template<typename _B1, typename _B2, typename... _Bn>
229 struct __disjunction_impl<__enable_if_t<!bool(_B1::value)>, _B1, _B2, _Bn...>
230 { using type = typename __disjunction_impl<void, _B2, _Bn...>::type; };
232 template<typename /* = void */, typename _B1, typename... _Bn>
233 struct __conjunction_impl
234 { using type = _B1; };
236 template<typename _B1, typename _B2, typename... _Bn>
237 struct __conjunction_impl<__enable_if_t<bool(_B1::value)>, _B1, _B2, _Bn...>
238 { using type = typename __conjunction_impl<void, _B2, _Bn...>::type; };
239 } // namespace __detail
242 template<typename... _Bn>
244 : __detail::__conjunction_impl<void, _Bn...>::type
252 template<typename... _Bn>
254 : __detail::__disjunction_impl<void, _Bn...>::type
262 template<typename _Pp>
267 /** @ingroup variable_templates
270 template<typename... _Bn>
271 inline constexpr bool conjunction_v = conjunction<_Bn...>::value;
273 template<typename... _Bn>
274 inline constexpr bool disjunction_v = disjunction<_Bn...>::value;
276 template<typename _Pp>
277 inline constexpr bool negation_v = negation<_Pp>::value;
280 #endif // __cpp_lib_logical_traits
282 // Forward declarations
294 /// @cond undocumented
296 struct __is_array_unknown_bounds;
298 // Helper functions that return false_type for incomplete classes,
299 // incomplete unions and arrays of known bound from those.
301 template <typename _Tp, size_t = sizeof(_Tp)>
302 constexpr true_type __is_complete_or_unbounded(__type_identity<_Tp>)
305 template <typename _TypeIdentity,
306 typename _NestedType = typename _TypeIdentity::type>
307 constexpr typename __or_<
308 is_reference<_NestedType>,
309 is_function<_NestedType>,
310 is_void<_NestedType>,
311 __is_array_unknown_bounds<_NestedType>
312 >::type __is_complete_or_unbounded(_TypeIdentity)
315 // __remove_cv_t (std::remove_cv_t for C++11).
316 template<typename _Tp>
317 using __remove_cv_t = typename remove_cv<_Tp>::type;
320 // Primary type categories.
323 template<typename _Tp>
325 : public false_type { };
329 : public true_type { };
332 struct is_void<const void>
333 : public true_type { };
336 struct is_void<volatile void>
337 : public true_type { };
340 struct is_void<const volatile void>
341 : public true_type { };
343 /// @cond undocumented
345 struct __is_integral_helper
346 : public false_type { };
349 struct __is_integral_helper<bool>
350 : public true_type { };
353 struct __is_integral_helper<char>
354 : public true_type { };
357 struct __is_integral_helper<signed char>
358 : public true_type { };
361 struct __is_integral_helper<unsigned char>
362 : public true_type { };
364 // We want is_integral<wchar_t> to be true (and make_signed/unsigned to work)
365 // even when libc doesn't provide working <wchar.h> and related functions,
366 // so don't check _GLIBCXX_USE_WCHAR_T here.
368 struct __is_integral_helper<wchar_t>
369 : public true_type { };
371 #ifdef _GLIBCXX_USE_CHAR8_T
373 struct __is_integral_helper<char8_t>
374 : public true_type { };
378 struct __is_integral_helper<char16_t>
379 : public true_type { };
382 struct __is_integral_helper<char32_t>
383 : public true_type { };
386 struct __is_integral_helper<short>
387 : public true_type { };
390 struct __is_integral_helper<unsigned short>
391 : public true_type { };
394 struct __is_integral_helper<int>
395 : public true_type { };
398 struct __is_integral_helper<unsigned int>
399 : public true_type { };
402 struct __is_integral_helper<long>
403 : public true_type { };
406 struct __is_integral_helper<unsigned long>
407 : public true_type { };
410 struct __is_integral_helper<long long>
411 : public true_type { };
414 struct __is_integral_helper<unsigned long long>
415 : public true_type { };
417 // Conditionalizing on __STRICT_ANSI__ here will break any port that
418 // uses one of these types for size_t.
419 #if defined(__GLIBCXX_TYPE_INT_N_0)
422 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0>
423 : public true_type { };
427 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0>
428 : public true_type { };
430 #if defined(__GLIBCXX_TYPE_INT_N_1)
433 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1>
434 : public true_type { };
438 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1>
439 : public true_type { };
441 #if defined(__GLIBCXX_TYPE_INT_N_2)
444 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2>
445 : public true_type { };
449 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2>
450 : public true_type { };
452 #if defined(__GLIBCXX_TYPE_INT_N_3)
455 struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3>
456 : public true_type { };
460 struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3>
461 : public true_type { };
466 template<typename _Tp>
468 : public __is_integral_helper<__remove_cv_t<_Tp>>::type
471 /// @cond undocumented
473 struct __is_floating_point_helper
474 : public false_type { };
477 struct __is_floating_point_helper<float>
478 : public true_type { };
481 struct __is_floating_point_helper<double>
482 : public true_type { };
485 struct __is_floating_point_helper<long double>
486 : public true_type { };
488 #ifdef __STDCPP_FLOAT16_T__
490 struct __is_floating_point_helper<_Float16>
491 : public true_type { };
494 #ifdef __STDCPP_FLOAT32_T__
496 struct __is_floating_point_helper<_Float32>
497 : public true_type { };
500 #ifdef __STDCPP_FLOAT64_T__
502 struct __is_floating_point_helper<_Float64>
503 : public true_type { };
506 #ifdef __STDCPP_FLOAT128_T__
508 struct __is_floating_point_helper<_Float128>
509 : public true_type { };
512 #ifdef __STDCPP_BFLOAT16_T__
514 struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
515 : public true_type { };
518 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
520 struct __is_floating_point_helper<__float128>
521 : public true_type { };
525 /// is_floating_point
526 template<typename _Tp>
527 struct is_floating_point
528 : public __is_floating_point_helper<__remove_cv_t<_Tp>>::type
532 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
533 template<typename _Tp>
535 : public __bool_constant<__is_array(_Tp)>
540 : public false_type { };
542 template<typename _Tp, std::size_t _Size>
543 struct is_array<_Tp[_Size]>
544 : public true_type { };
546 template<typename _Tp>
547 struct is_array<_Tp[]>
548 : public true_type { };
552 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
553 template<typename _Tp>
555 : public __bool_constant<__is_pointer(_Tp)>
558 template<typename _Tp>
560 : public false_type { };
562 template<typename _Tp>
563 struct is_pointer<_Tp*>
564 : public true_type { };
566 template<typename _Tp>
567 struct is_pointer<_Tp* const>
568 : public true_type { };
570 template<typename _Tp>
571 struct is_pointer<_Tp* volatile>
572 : public true_type { };
574 template<typename _Tp>
575 struct is_pointer<_Tp* const volatile>
576 : public true_type { };
579 /// is_lvalue_reference
581 struct is_lvalue_reference
582 : public false_type { };
584 template<typename _Tp>
585 struct is_lvalue_reference<_Tp&>
586 : public true_type { };
588 /// is_rvalue_reference
590 struct is_rvalue_reference
591 : public false_type { };
593 template<typename _Tp>
594 struct is_rvalue_reference<_Tp&&>
595 : public true_type { };
597 /// is_member_object_pointer
598 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
599 template<typename _Tp>
600 struct is_member_object_pointer
601 : public __bool_constant<__is_member_object_pointer(_Tp)>
605 struct __is_member_object_pointer_helper
606 : public false_type { };
608 template<typename _Tp, typename _Cp>
609 struct __is_member_object_pointer_helper<_Tp _Cp::*>
610 : public __not_<is_function<_Tp>>::type { };
613 template<typename _Tp>
614 struct is_member_object_pointer
615 : public __is_member_object_pointer_helper<__remove_cv_t<_Tp>>::type
619 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
620 /// is_member_function_pointer
621 template<typename _Tp>
622 struct is_member_function_pointer
623 : public __bool_constant<__is_member_function_pointer(_Tp)>
627 struct __is_member_function_pointer_helper
628 : public false_type { };
630 template<typename _Tp, typename _Cp>
631 struct __is_member_function_pointer_helper<_Tp _Cp::*>
632 : public is_function<_Tp>::type { };
634 /// is_member_function_pointer
635 template<typename _Tp>
636 struct is_member_function_pointer
637 : public __is_member_function_pointer_helper<__remove_cv_t<_Tp>>::type
642 template<typename _Tp>
644 : public __bool_constant<__is_enum(_Tp)>
648 template<typename _Tp>
650 : public __bool_constant<__is_union(_Tp)>
654 template<typename _Tp>
656 : public __bool_constant<__is_class(_Tp)>
660 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
661 template<typename _Tp>
663 : public __bool_constant<__is_function(_Tp)>
666 template<typename _Tp>
668 : public __bool_constant<!is_const<const _Tp>::value> { };
670 template<typename _Tp>
671 struct is_function<_Tp&>
672 : public false_type { };
674 template<typename _Tp>
675 struct is_function<_Tp&&>
676 : public false_type { };
679 #ifdef __cpp_lib_is_null_pointer // C++ >= 11
680 /// is_null_pointer (LWG 2247).
681 template<typename _Tp>
682 struct is_null_pointer
683 : public false_type { };
686 struct is_null_pointer<std::nullptr_t>
687 : public true_type { };
690 struct is_null_pointer<const std::nullptr_t>
691 : public true_type { };
694 struct is_null_pointer<volatile std::nullptr_t>
695 : public true_type { };
698 struct is_null_pointer<const volatile std::nullptr_t>
699 : public true_type { };
701 /// __is_nullptr_t (deprecated extension).
702 /// @deprecated Non-standard. Use `is_null_pointer` instead.
703 template<typename _Tp>
704 struct __is_nullptr_t
705 : public is_null_pointer<_Tp>
706 { } _GLIBCXX_DEPRECATED_SUGGEST("std::is_null_pointer");
707 #endif // __cpp_lib_is_null_pointer
709 // Composite type categories.
712 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
713 template<typename _Tp>
715 : public __bool_constant<__is_reference(_Tp)>
718 template<typename _Tp>
723 template<typename _Tp>
724 struct is_reference<_Tp&>
728 template<typename _Tp>
729 struct is_reference<_Tp&&>
735 template<typename _Tp>
737 : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type
741 template<typename _Tp>
742 struct is_fundamental
743 : public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
744 is_null_pointer<_Tp>>::type
748 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
749 template<typename _Tp>
751 : public __bool_constant<__is_object(_Tp)>
754 template<typename _Tp>
756 : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>,
762 struct is_member_pointer;
765 template<typename _Tp>
767 : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>,
768 is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type
772 template<typename _Tp>
774 : public __bool_constant<!is_fundamental<_Tp>::value> { };
776 /// is_member_pointer
777 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
778 template<typename _Tp>
779 struct is_member_pointer
780 : public __bool_constant<__is_member_pointer(_Tp)>
783 /// @cond undocumented
784 template<typename _Tp>
785 struct __is_member_pointer_helper
786 : public false_type { };
788 template<typename _Tp, typename _Cp>
789 struct __is_member_pointer_helper<_Tp _Cp::*>
790 : public true_type { };
793 template<typename _Tp>
794 struct is_member_pointer
795 : public __is_member_pointer_helper<__remove_cv_t<_Tp>>::type
799 template<typename, typename>
802 /// @cond undocumented
803 template<typename _Tp, typename... _Types>
804 using __is_one_of = __or_<is_same<_Tp, _Types>...>;
806 // Check if a type is one of the signed integer types.
808 template<typename _Tp>
809 using __is_signed_integer = __is_one_of<__remove_cv_t<_Tp>,
810 signed char, signed short, signed int, signed long,
812 #if defined(__GLIBCXX_TYPE_INT_N_0)
813 , signed __GLIBCXX_TYPE_INT_N_0
815 #if defined(__GLIBCXX_TYPE_INT_N_1)
816 , signed __GLIBCXX_TYPE_INT_N_1
818 #if defined(__GLIBCXX_TYPE_INT_N_2)
819 , signed __GLIBCXX_TYPE_INT_N_2
821 #if defined(__GLIBCXX_TYPE_INT_N_3)
822 , signed __GLIBCXX_TYPE_INT_N_3
826 // Check if a type is one of the unsigned integer types.
828 template<typename _Tp>
829 using __is_unsigned_integer = __is_one_of<__remove_cv_t<_Tp>,
830 unsigned char, unsigned short, unsigned int, unsigned long,
832 #if defined(__GLIBCXX_TYPE_INT_N_0)
833 , unsigned __GLIBCXX_TYPE_INT_N_0
835 #if defined(__GLIBCXX_TYPE_INT_N_1)
836 , unsigned __GLIBCXX_TYPE_INT_N_1
838 #if defined(__GLIBCXX_TYPE_INT_N_2)
839 , unsigned __GLIBCXX_TYPE_INT_N_2
841 #if defined(__GLIBCXX_TYPE_INT_N_3)
842 , unsigned __GLIBCXX_TYPE_INT_N_3
846 // Check if a type is one of the signed or unsigned integer types.
847 template<typename _Tp>
848 using __is_standard_integer
849 = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
851 // __void_t (std::void_t for C++11)
852 template<typename...> using __void_t = void;
858 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
859 template<typename _Tp>
861 : public __bool_constant<__is_const(_Tp)>
866 : public false_type { };
868 template<typename _Tp>
869 struct is_const<_Tp const>
870 : public true_type { };
874 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
875 template<typename _Tp>
877 : public __bool_constant<__is_volatile(_Tp)>
882 : public false_type { };
884 template<typename _Tp>
885 struct is_volatile<_Tp volatile>
886 : public true_type { };
890 * @deprecated Deprecated in C++26.
891 * Use a combination of one or more more specialized type traits instead,
892 * such as `is_trivially_default_constructible`,
893 * `is_trivially_copy_constructible`, `is_trivially_copy_assignable`,
894 * etc., depending on the exact check(s) needed.
896 template<typename _Tp>
898 _GLIBCXX26_DEPRECATED_SUGGEST("is_trivially_default_constructible && is_trivially_copyable")
900 : public __bool_constant<__is_trivial(_Tp)>
902 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
903 "template argument must be a complete class or an unbounded array");
906 /// is_trivially_copyable
907 template<typename _Tp>
908 struct is_trivially_copyable
909 : public __bool_constant<__is_trivially_copyable(_Tp)>
911 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
912 "template argument must be a complete class or an unbounded array");
915 /// is_standard_layout
916 template<typename _Tp>
917 struct is_standard_layout
918 : public __bool_constant<__is_standard_layout(_Tp)>
920 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
921 "template argument must be a complete class or an unbounded array");
925 * @deprecated Deprecated in C++20.
926 * Use `is_standard_layout && is_trivial` instead.
928 // Could use is_standard_layout && is_trivial instead of the builtin.
929 template<typename _Tp>
931 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial")
933 : public __bool_constant<__is_pod(_Tp)>
935 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
936 "template argument must be a complete class or an unbounded array");
940 * @deprecated Deprecated in C++17, removed in C++20.
941 * The idea of a literal type isn't useful.
943 template<typename _Tp>
945 _GLIBCXX17_DEPRECATED
947 : public __bool_constant<__is_literal_type(_Tp)>
949 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
950 "template argument must be a complete class or an unbounded array");
954 template<typename _Tp>
956 : public __bool_constant<__is_empty(_Tp)>
960 template<typename _Tp>
961 struct is_polymorphic
962 : public __bool_constant<__is_polymorphic(_Tp)>
965 #ifdef __cpp_lib_is_final // C++ >= 14
968 template<typename _Tp>
970 : public __bool_constant<__is_final(_Tp)>
975 template<typename _Tp>
977 : public __bool_constant<__is_abstract(_Tp)>
980 /// @cond undocumented
981 template<typename _Tp,
982 bool = is_arithmetic<_Tp>::value>
983 struct __is_signed_helper
984 : public false_type { };
986 template<typename _Tp>
987 struct __is_signed_helper<_Tp, true>
988 : public __bool_constant<_Tp(-1) < _Tp(0)>
993 template<typename _Tp>
995 : public __is_signed_helper<_Tp>::type
999 template<typename _Tp>
1001 : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type
1004 /// @cond undocumented
1005 template<typename _Tp, typename _Up = _Tp&&>
1009 template<typename _Tp>
1014 template<typename _Tp>
1015 auto declval() noexcept -> decltype(__declval<_Tp>(0));
1018 struct remove_all_extents;
1020 /// @cond undocumented
1021 template<typename _Tp>
1022 struct __is_array_known_bounds
1026 template<typename _Tp, size_t _Size>
1027 struct __is_array_known_bounds<_Tp[_Size]>
1031 template<typename _Tp>
1032 struct __is_array_unknown_bounds
1036 template<typename _Tp>
1037 struct __is_array_unknown_bounds<_Tp[]>
1041 // Destructible and constructible type properties.
1043 // In N3290 is_destructible does not say anything about function
1044 // types and abstract types, see LWG 2049. This implementation
1045 // describes function types as non-destructible and all complete
1046 // object types as destructible, iff the explicit destructor
1047 // call expression is wellformed.
1048 struct __do_is_destructible_impl
1050 template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())>
1051 static true_type __test(int);
1054 static false_type __test(...);
1057 template<typename _Tp>
1058 struct __is_destructible_impl
1059 : public __do_is_destructible_impl
1061 using type = decltype(__test<_Tp>(0));
1064 template<typename _Tp,
1065 bool = __or_<is_void<_Tp>,
1066 __is_array_unknown_bounds<_Tp>,
1067 is_function<_Tp>>::value,
1068 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
1069 struct __is_destructible_safe;
1071 template<typename _Tp>
1072 struct __is_destructible_safe<_Tp, false, false>
1073 : public __is_destructible_impl<typename
1074 remove_all_extents<_Tp>::type>::type
1077 template<typename _Tp>
1078 struct __is_destructible_safe<_Tp, true, false>
1079 : public false_type { };
1081 template<typename _Tp>
1082 struct __is_destructible_safe<_Tp, false, true>
1083 : public true_type { };
1087 template<typename _Tp>
1088 struct is_destructible
1089 : public __is_destructible_safe<_Tp>::type
1091 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1092 "template argument must be a complete class or an unbounded array");
1095 /// @cond undocumented
1097 // is_nothrow_destructible requires that is_destructible is
1098 // satisfied as well. We realize that by mimicing the
1099 // implementation of is_destructible but refer to noexcept(expr)
1100 // instead of decltype(expr).
1101 struct __do_is_nt_destructible_impl
1103 template<typename _Tp>
1104 static __bool_constant<noexcept(declval<_Tp&>().~_Tp())>
1108 static false_type __test(...);
1111 template<typename _Tp>
1112 struct __is_nt_destructible_impl
1113 : public __do_is_nt_destructible_impl
1115 using type = decltype(__test<_Tp>(0));
1118 template<typename _Tp,
1119 bool = __or_<is_void<_Tp>,
1120 __is_array_unknown_bounds<_Tp>,
1121 is_function<_Tp>>::value,
1122 bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value>
1123 struct __is_nt_destructible_safe;
1125 template<typename _Tp>
1126 struct __is_nt_destructible_safe<_Tp, false, false>
1127 : public __is_nt_destructible_impl<typename
1128 remove_all_extents<_Tp>::type>::type
1131 template<typename _Tp>
1132 struct __is_nt_destructible_safe<_Tp, true, false>
1133 : public false_type { };
1135 template<typename _Tp>
1136 struct __is_nt_destructible_safe<_Tp, false, true>
1137 : public true_type { };
1140 /// is_nothrow_destructible
1141 template<typename _Tp>
1142 struct is_nothrow_destructible
1143 : public __is_nt_destructible_safe<_Tp>::type
1145 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1146 "template argument must be a complete class or an unbounded array");
1149 /// @cond undocumented
1150 template<typename _Tp, typename... _Args>
1151 using __is_constructible_impl
1152 = __bool_constant<__is_constructible(_Tp, _Args...)>;
1155 /// is_constructible
1156 template<typename _Tp, typename... _Args>
1157 struct is_constructible
1158 : public __is_constructible_impl<_Tp, _Args...>
1160 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1161 "template argument must be a complete class or an unbounded array");
1164 /// is_default_constructible
1165 template<typename _Tp>
1166 struct is_default_constructible
1167 : public __is_constructible_impl<_Tp>
1169 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1170 "template argument must be a complete class or an unbounded array");
1173 /// @cond undocumented
1174 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_lvalue_reference)
1175 template<typename _Tp>
1176 using __add_lval_ref_t = __add_lvalue_reference(_Tp);
1178 template<typename _Tp, typename = void>
1179 struct __add_lvalue_reference_helper
1180 { using type = _Tp; };
1182 template<typename _Tp>
1183 struct __add_lvalue_reference_helper<_Tp, __void_t<_Tp&>>
1184 { using type = _Tp&; };
1186 template<typename _Tp>
1187 using __add_lval_ref_t = typename __add_lvalue_reference_helper<_Tp>::type;
1191 /// is_copy_constructible
1192 template<typename _Tp>
1193 struct is_copy_constructible
1194 : public __is_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1196 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1197 "template argument must be a complete class or an unbounded array");
1200 /// @cond undocumented
1201 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_rvalue_reference)
1202 template<typename _Tp>
1203 using __add_rval_ref_t = __add_rvalue_reference(_Tp);
1205 template<typename _Tp, typename = void>
1206 struct __add_rvalue_reference_helper
1207 { using type = _Tp; };
1209 template<typename _Tp>
1210 struct __add_rvalue_reference_helper<_Tp, __void_t<_Tp&&>>
1211 { using type = _Tp&&; };
1213 template<typename _Tp>
1214 using __add_rval_ref_t = typename __add_rvalue_reference_helper<_Tp>::type;
1218 /// is_move_constructible
1219 template<typename _Tp>
1220 struct is_move_constructible
1221 : public __is_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1223 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1224 "template argument must be a complete class or an unbounded array");
1227 /// @cond undocumented
1228 template<typename _Tp, typename... _Args>
1229 using __is_nothrow_constructible_impl
1230 = __bool_constant<__is_nothrow_constructible(_Tp, _Args...)>;
1233 /// is_nothrow_constructible
1234 template<typename _Tp, typename... _Args>
1235 struct is_nothrow_constructible
1236 : public __is_nothrow_constructible_impl<_Tp, _Args...>
1238 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1239 "template argument must be a complete class or an unbounded array");
1242 /// is_nothrow_default_constructible
1243 template<typename _Tp>
1244 struct is_nothrow_default_constructible
1245 : public __is_nothrow_constructible_impl<_Tp>
1247 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1248 "template argument must be a complete class or an unbounded array");
1251 /// is_nothrow_copy_constructible
1252 template<typename _Tp>
1253 struct is_nothrow_copy_constructible
1254 : public __is_nothrow_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1256 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1257 "template argument must be a complete class or an unbounded array");
1260 /// is_nothrow_move_constructible
1261 template<typename _Tp>
1262 struct is_nothrow_move_constructible
1263 : public __is_nothrow_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1265 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1266 "template argument must be a complete class or an unbounded array");
1269 /// @cond undocumented
1270 template<typename _Tp, typename _Up>
1271 using __is_assignable_impl = __bool_constant<__is_assignable(_Tp, _Up)>;
1275 template<typename _Tp, typename _Up>
1276 struct is_assignable
1277 : public __is_assignable_impl<_Tp, _Up>
1279 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1280 "template argument must be a complete class or an unbounded array");
1283 /// is_copy_assignable
1284 template<typename _Tp>
1285 struct is_copy_assignable
1286 : public __is_assignable_impl<__add_lval_ref_t<_Tp>,
1287 __add_lval_ref_t<const _Tp>>
1289 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1290 "template argument must be a complete class or an unbounded array");
1293 /// is_move_assignable
1294 template<typename _Tp>
1295 struct is_move_assignable
1296 : public __is_assignable_impl<__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>>
1298 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1299 "template argument must be a complete class or an unbounded array");
1302 /// @cond undocumented
1303 template<typename _Tp, typename _Up>
1304 using __is_nothrow_assignable_impl
1305 = __bool_constant<__is_nothrow_assignable(_Tp, _Up)>;
1308 /// is_nothrow_assignable
1309 template<typename _Tp, typename _Up>
1310 struct is_nothrow_assignable
1311 : public __is_nothrow_assignable_impl<_Tp, _Up>
1313 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1314 "template argument must be a complete class or an unbounded array");
1317 /// is_nothrow_copy_assignable
1318 template<typename _Tp>
1319 struct is_nothrow_copy_assignable
1320 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
1321 __add_lval_ref_t<const _Tp>>
1323 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1324 "template argument must be a complete class or an unbounded array");
1327 /// is_nothrow_move_assignable
1328 template<typename _Tp>
1329 struct is_nothrow_move_assignable
1330 : public __is_nothrow_assignable_impl<__add_lval_ref_t<_Tp>,
1331 __add_rval_ref_t<_Tp>>
1333 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1334 "template argument must be a complete class or an unbounded array");
1337 /// @cond undocumented
1338 template<typename _Tp, typename... _Args>
1339 using __is_trivially_constructible_impl
1340 = __bool_constant<__is_trivially_constructible(_Tp, _Args...)>;
1343 /// is_trivially_constructible
1344 template<typename _Tp, typename... _Args>
1345 struct is_trivially_constructible
1346 : public __is_trivially_constructible_impl<_Tp, _Args...>
1348 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1349 "template argument must be a complete class or an unbounded array");
1352 /// is_trivially_default_constructible
1353 template<typename _Tp>
1354 struct is_trivially_default_constructible
1355 : public __is_trivially_constructible_impl<_Tp>
1357 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1358 "template argument must be a complete class or an unbounded array");
1361 #if __cpp_variable_templates && __cpp_concepts
1362 template<typename _Tp>
1363 constexpr bool __is_implicitly_default_constructible_v
1364 = requires (void(&__f)(_Tp)) { __f({}); };
1366 template<typename _Tp>
1367 struct __is_implicitly_default_constructible
1368 : __bool_constant<__is_implicitly_default_constructible_v<_Tp>>
1371 struct __do_is_implicitly_default_constructible_impl
1373 template <typename _Tp>
1374 static void __helper(const _Tp&);
1376 template <typename _Tp>
1377 static true_type __test(const _Tp&,
1378 decltype(__helper<const _Tp&>({}))* = 0);
1380 static false_type __test(...);
1383 template<typename _Tp>
1384 struct __is_implicitly_default_constructible_impl
1385 : public __do_is_implicitly_default_constructible_impl
1387 using type = decltype(__test(declval<_Tp>()));
1390 template<typename _Tp>
1391 struct __is_implicitly_default_constructible_safe
1392 : public __is_implicitly_default_constructible_impl<_Tp>::type
1395 template <typename _Tp>
1396 struct __is_implicitly_default_constructible
1397 : public __and_<__is_constructible_impl<_Tp>,
1398 __is_implicitly_default_constructible_safe<_Tp>>::type
1402 /// is_trivially_copy_constructible
1403 template<typename _Tp>
1404 struct is_trivially_copy_constructible
1405 : public __is_trivially_constructible_impl<_Tp, __add_lval_ref_t<const _Tp>>
1407 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1408 "template argument must be a complete class or an unbounded array");
1411 /// is_trivially_move_constructible
1412 template<typename _Tp>
1413 struct is_trivially_move_constructible
1414 : public __is_trivially_constructible_impl<_Tp, __add_rval_ref_t<_Tp>>
1416 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1417 "template argument must be a complete class or an unbounded array");
1420 /// @cond undocumented
1421 template<typename _Tp, typename _Up>
1422 using __is_trivially_assignable_impl
1423 = __bool_constant<__is_trivially_assignable(_Tp, _Up)>;
1426 /// is_trivially_assignable
1427 template<typename _Tp, typename _Up>
1428 struct is_trivially_assignable
1429 : public __is_trivially_assignable_impl<_Tp, _Up>
1431 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1432 "template argument must be a complete class or an unbounded array");
1435 /// is_trivially_copy_assignable
1436 template<typename _Tp>
1437 struct is_trivially_copy_assignable
1438 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
1439 __add_lval_ref_t<const _Tp>>
1441 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1442 "template argument must be a complete class or an unbounded array");
1445 /// is_trivially_move_assignable
1446 template<typename _Tp>
1447 struct is_trivially_move_assignable
1448 : public __is_trivially_assignable_impl<__add_lval_ref_t<_Tp>,
1449 __add_rval_ref_t<_Tp>>
1451 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1452 "template argument must be a complete class or an unbounded array");
1455 /// is_trivially_destructible
1456 template<typename _Tp>
1457 struct is_trivially_destructible
1458 : public __and_<__is_destructible_safe<_Tp>,
1459 __bool_constant<__has_trivial_destructor(_Tp)>>::type
1461 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1462 "template argument must be a complete class or an unbounded array");
1466 /// has_virtual_destructor
1467 template<typename _Tp>
1468 struct has_virtual_destructor
1469 : public __bool_constant<__has_virtual_destructor(_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 // type property queries.
1479 template<typename _Tp>
1481 : public integral_constant<std::size_t, alignof(_Tp)>
1483 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
1484 "template argument must be a complete class or an unbounded array");
1488 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank) \
1489 && (!defined(__clang__) || __clang_major__ >= 20) // PR118559
1490 template<typename _Tp>
1492 : public integral_constant<std::size_t, __array_rank(_Tp)> { };
1496 : public integral_constant<std::size_t, 0> { };
1498 template<typename _Tp, std::size_t _Size>
1499 struct rank<_Tp[_Size]>
1500 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1502 template<typename _Tp>
1504 : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { };
1508 template<typename, unsigned _Uint = 0>
1510 : public integral_constant<size_t, 0> { };
1512 template<typename _Tp, size_t _Size>
1513 struct extent<_Tp[_Size], 0>
1514 : public integral_constant<size_t, _Size> { };
1516 template<typename _Tp, unsigned _Uint, size_t _Size>
1517 struct extent<_Tp[_Size], _Uint>
1518 : public extent<_Tp, _Uint - 1>::type { };
1520 template<typename _Tp>
1521 struct extent<_Tp[], 0>
1522 : public integral_constant<size_t, 0> { };
1524 template<typename _Tp, unsigned _Uint>
1525 struct extent<_Tp[], _Uint>
1526 : public extent<_Tp, _Uint - 1>::type { };
1532 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same)
1533 template<typename _Tp, typename _Up>
1535 : public __bool_constant<__is_same(_Tp, _Up)>
1538 template<typename _Tp, typename _Up>
1543 template<typename _Tp>
1544 struct is_same<_Tp, _Tp>
1550 template<typename _Base, typename _Derived>
1552 : public __bool_constant<__is_base_of(_Base, _Derived)>
1555 #ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
1556 /// is_virtual_base_of
1558 template<typename _Base, typename _Derived>
1559 struct is_virtual_base_of
1560 : public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)>
1564 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
1565 template<typename _From, typename _To>
1566 struct is_convertible
1567 : public __bool_constant<__is_convertible(_From, _To)>
1570 template<typename _From, typename _To,
1571 bool = __or_<is_void<_From>, is_function<_To>,
1572 is_array<_To>>::value>
1573 struct __is_convertible_helper
1575 using type = typename is_void<_To>::type;
1578 #pragma GCC diagnostic push
1579 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
1580 template<typename _From, typename _To>
1581 class __is_convertible_helper<_From, _To, false>
1583 template<typename _To1>
1584 static void __test_aux(_To1) noexcept;
1586 template<typename _From1, typename _To1,
1587 typename = decltype(__test_aux<_To1>(std::declval<_From1>()))>
1591 template<typename, typename>
1596 using type = decltype(__test<_From, _To>(0));
1598 #pragma GCC diagnostic pop
1601 template<typename _From, typename _To>
1602 struct is_convertible
1603 : public __is_convertible_helper<_From, _To>::type
1607 // helper trait for unique_ptr<T[]>, shared_ptr<T[]>, and span<T, N>
1608 template<typename _ToElementType, typename _FromElementType>
1609 using __is_array_convertible
1610 = is_convertible<_FromElementType(*)[], _ToElementType(*)[]>;
1612 #ifdef __cpp_lib_is_nothrow_convertible // C++ >= 20
1614 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_convertible)
1615 /// is_nothrow_convertible_v
1616 template<typename _From, typename _To>
1617 inline constexpr bool is_nothrow_convertible_v
1618 = __is_nothrow_convertible(_From, _To);
1620 /// is_nothrow_convertible
1621 template<typename _From, typename _To>
1622 struct is_nothrow_convertible
1623 : public bool_constant<is_nothrow_convertible_v<_From, _To>>
1626 template<typename _From, typename _To,
1627 bool = __or_<is_void<_From>, is_function<_To>,
1628 is_array<_To>>::value>
1629 struct __is_nt_convertible_helper
1633 #pragma GCC diagnostic push
1634 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
1635 template<typename _From, typename _To>
1636 class __is_nt_convertible_helper<_From, _To, false>
1638 template<typename _To1>
1639 static void __test_aux(_To1) noexcept;
1641 template<typename _From1, typename _To1>
1643 __bool_constant<noexcept(__test_aux<_To1>(std::declval<_From1>()))>
1646 template<typename, typename>
1651 using type = decltype(__test<_From, _To>(0));
1653 #pragma GCC diagnostic pop
1655 /// is_nothrow_convertible
1656 template<typename _From, typename _To>
1657 struct is_nothrow_convertible
1658 : public __is_nt_convertible_helper<_From, _To>::type
1661 /// is_nothrow_convertible_v
1662 template<typename _From, typename _To>
1663 inline constexpr bool is_nothrow_convertible_v
1664 = is_nothrow_convertible<_From, _To>::value;
1666 #endif // __cpp_lib_is_nothrow_convertible
1668 #pragma GCC diagnostic push
1669 #pragma GCC diagnostic ignored "-Wc++14-extensions" // for variable templates
1670 template<typename _Tp, typename... _Args>
1671 struct __is_nothrow_new_constructible_impl
1673 noexcept(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))
1677 template<typename _Tp, typename... _Args>
1678 _GLIBCXX17_INLINE constexpr bool __is_nothrow_new_constructible
1679 = __and_<is_constructible<_Tp, _Args...>,
1680 __is_nothrow_new_constructible_impl<_Tp, _Args...>>::value;
1681 #pragma GCC diagnostic pop
1683 // Const-volatile modifications.
1686 template<typename _Tp>
1688 { using type = _Tp; };
1690 template<typename _Tp>
1691 struct remove_const<_Tp const>
1692 { using type = _Tp; };
1695 template<typename _Tp>
1696 struct remove_volatile
1697 { using type = _Tp; };
1699 template<typename _Tp>
1700 struct remove_volatile<_Tp volatile>
1701 { using type = _Tp; };
1704 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cv)
1705 template<typename _Tp>
1707 { using type = __remove_cv(_Tp); };
1709 template<typename _Tp>
1711 { using type = _Tp; };
1713 template<typename _Tp>
1714 struct remove_cv<const _Tp>
1715 { using type = _Tp; };
1717 template<typename _Tp>
1718 struct remove_cv<volatile _Tp>
1719 { using type = _Tp; };
1721 template<typename _Tp>
1722 struct remove_cv<const volatile _Tp>
1723 { using type = _Tp; };
1727 template<typename _Tp>
1729 { using type = _Tp const; };
1732 template<typename _Tp>
1734 { using type = _Tp volatile; };
1737 template<typename _Tp>
1739 { using type = _Tp const volatile; };
1741 #ifdef __cpp_lib_transformation_trait_aliases // C++ >= 14
1742 /// Alias template for remove_const
1743 template<typename _Tp>
1744 using remove_const_t = typename remove_const<_Tp>::type;
1746 /// Alias template for remove_volatile
1747 template<typename _Tp>
1748 using remove_volatile_t = typename remove_volatile<_Tp>::type;
1750 /// Alias template for remove_cv
1751 template<typename _Tp>
1752 using remove_cv_t = typename remove_cv<_Tp>::type;
1754 /// Alias template for add_const
1755 template<typename _Tp>
1756 using add_const_t = typename add_const<_Tp>::type;
1758 /// Alias template for add_volatile
1759 template<typename _Tp>
1760 using add_volatile_t = typename add_volatile<_Tp>::type;
1762 /// Alias template for add_cv
1763 template<typename _Tp>
1764 using add_cv_t = typename add_cv<_Tp>::type;
1767 // Reference transformations.
1769 /// remove_reference
1770 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
1771 template<typename _Tp>
1772 struct remove_reference
1773 { using type = __remove_reference(_Tp); };
1775 template<typename _Tp>
1776 struct remove_reference
1777 { using type = _Tp; };
1779 template<typename _Tp>
1780 struct remove_reference<_Tp&>
1781 { using type = _Tp; };
1783 template<typename _Tp>
1784 struct remove_reference<_Tp&&>
1785 { using type = _Tp; };
1788 /// add_lvalue_reference
1789 template<typename _Tp>
1790 struct add_lvalue_reference
1791 { using type = __add_lval_ref_t<_Tp>; };
1793 /// add_rvalue_reference
1794 template<typename _Tp>
1795 struct add_rvalue_reference
1796 { using type = __add_rval_ref_t<_Tp>; };
1798 #if __cplusplus > 201103L
1799 /// Alias template for remove_reference
1800 template<typename _Tp>
1801 using remove_reference_t = typename remove_reference<_Tp>::type;
1803 /// Alias template for add_lvalue_reference
1804 template<typename _Tp>
1805 using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
1807 /// Alias template for add_rvalue_reference
1808 template<typename _Tp>
1809 using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
1812 // Sign modifications.
1814 /// @cond undocumented
1816 // Utility for constructing identically cv-qualified types.
1817 template<typename _Unqualified, bool _IsConst, bool _IsVol>
1818 struct __cv_selector;
1820 template<typename _Unqualified>
1821 struct __cv_selector<_Unqualified, false, false>
1822 { using __type = _Unqualified; };
1824 template<typename _Unqualified>
1825 struct __cv_selector<_Unqualified, false, true>
1826 { using __type = volatile _Unqualified; };
1828 template<typename _Unqualified>
1829 struct __cv_selector<_Unqualified, true, false>
1830 { using __type = const _Unqualified; };
1832 template<typename _Unqualified>
1833 struct __cv_selector<_Unqualified, true, true>
1834 { using __type = const volatile _Unqualified; };
1836 template<typename _Qualified, typename _Unqualified,
1837 bool _IsConst = is_const<_Qualified>::value,
1838 bool _IsVol = is_volatile<_Qualified>::value>
1839 class __match_cv_qualifiers
1841 using __match = __cv_selector<_Unqualified, _IsConst, _IsVol>;
1844 using __type = typename __match::__type;
1847 // Utility for finding the unsigned versions of signed integral types.
1848 template<typename _Tp>
1849 struct __make_unsigned
1850 { using __type = _Tp; };
1853 struct __make_unsigned<char>
1854 { using __type = unsigned char; };
1857 struct __make_unsigned<signed char>
1858 { using __type = unsigned char; };
1861 struct __make_unsigned<short>
1862 { using __type = unsigned short; };
1865 struct __make_unsigned<int>
1866 { using __type = unsigned int; };
1869 struct __make_unsigned<long>
1870 { using __type = unsigned long; };
1873 struct __make_unsigned<long long>
1874 { using __type = unsigned long long; };
1876 #if defined(__GLIBCXX_TYPE_INT_N_0)
1879 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
1880 { using __type = unsigned __GLIBCXX_TYPE_INT_N_0; };
1882 #if defined(__GLIBCXX_TYPE_INT_N_1)
1885 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1>
1886 { using __type = unsigned __GLIBCXX_TYPE_INT_N_1; };
1888 #if defined(__GLIBCXX_TYPE_INT_N_2)
1891 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2>
1892 { using __type = unsigned __GLIBCXX_TYPE_INT_N_2; };
1894 #if defined(__GLIBCXX_TYPE_INT_N_3)
1897 struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3>
1898 { using __type = unsigned __GLIBCXX_TYPE_INT_N_3; };
1901 // Select between integral and enum: not possible to be both.
1902 template<typename _Tp,
1903 bool _IsInt = is_integral<_Tp>::value,
1904 bool _IsEnum = __is_enum(_Tp)>
1905 class __make_unsigned_selector;
1907 template<typename _Tp>
1908 class __make_unsigned_selector<_Tp, true, false>
1910 using __unsigned_type
1911 = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
1915 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
1918 class __make_unsigned_selector_base
1921 template<typename...> struct _List { };
1923 template<typename _Tp, typename... _Up>
1924 struct _List<_Tp, _Up...> : _List<_Up...>
1925 { static constexpr size_t __size = sizeof(_Tp); };
1927 template<size_t _Sz, typename _Tp, bool = (_Sz <= _Tp::__size)>
1930 template<size_t _Sz, typename _Uint, typename... _UInts>
1931 struct __select<_Sz, _List<_Uint, _UInts...>, true>
1932 { using __type = _Uint; };
1934 template<size_t _Sz, typename _Uint, typename... _UInts>
1935 struct __select<_Sz, _List<_Uint, _UInts...>, false>
1936 : __select<_Sz, _List<_UInts...>>
1940 // Choose unsigned integer type with the smallest rank and same size as _Tp
1941 template<typename _Tp>
1942 class __make_unsigned_selector<_Tp, false, true>
1943 : __make_unsigned_selector_base
1945 // With -fshort-enums, an enum may be as small as a char.
1946 using _UInts = _List<unsigned char, unsigned short, unsigned int,
1947 unsigned long, unsigned long long>;
1949 using __unsigned_type = typename __select<sizeof(_Tp), _UInts>::__type;
1953 = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
1956 // wchar_t, char8_t, char16_t and char32_t are integral types but are
1957 // neither signed integer types nor unsigned integer types, so must be
1958 // transformed to the unsigned integer type with the smallest rank.
1959 // Use the partial specialization for enumeration types to do that.
1961 struct __make_unsigned<wchar_t>
1964 = typename __make_unsigned_selector<wchar_t, false, true>::__type;
1967 #ifdef _GLIBCXX_USE_CHAR8_T
1969 struct __make_unsigned<char8_t>
1972 = typename __make_unsigned_selector<char8_t, false, true>::__type;
1977 struct __make_unsigned<char16_t>
1980 = typename __make_unsigned_selector<char16_t, false, true>::__type;
1984 struct __make_unsigned<char32_t>
1987 = typename __make_unsigned_selector<char32_t, false, true>::__type;
1991 // Given an integral/enum type, return the corresponding unsigned
1993 // Primary template.
1995 template<typename _Tp>
1996 struct make_unsigned
1997 { using type = typename __make_unsigned_selector<_Tp>::__type; };
1999 // Integral, but don't define.
2000 template<> struct make_unsigned<bool>;
2001 template<> struct make_unsigned<bool const>;
2002 template<> struct make_unsigned<bool volatile>;
2003 template<> struct make_unsigned<bool const volatile>;
2005 /// @cond undocumented
2007 // Utility for finding the signed versions of unsigned integral types.
2008 template<typename _Tp>
2009 struct __make_signed
2010 { using __type = _Tp; };
2013 struct __make_signed<char>
2014 { using __type = signed char; };
2017 struct __make_signed<unsigned char>
2018 { using __type = signed char; };
2021 struct __make_signed<unsigned short>
2022 { using __type = signed short; };
2025 struct __make_signed<unsigned int>
2026 { using __type = signed int; };
2029 struct __make_signed<unsigned long>
2030 { using __type = signed long; };
2033 struct __make_signed<unsigned long long>
2034 { using __type = signed long long; };
2036 #if defined(__GLIBCXX_TYPE_INT_N_0)
2039 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
2040 { using __type = __GLIBCXX_TYPE_INT_N_0; };
2042 #if defined(__GLIBCXX_TYPE_INT_N_1)
2045 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1>
2046 { using __type = __GLIBCXX_TYPE_INT_N_1; };
2048 #if defined(__GLIBCXX_TYPE_INT_N_2)
2051 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2>
2052 { using __type = __GLIBCXX_TYPE_INT_N_2; };
2054 #if defined(__GLIBCXX_TYPE_INT_N_3)
2057 struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3>
2058 { using __type = __GLIBCXX_TYPE_INT_N_3; };
2061 // Select between integral and enum: not possible to be both.
2062 template<typename _Tp,
2063 bool _IsInt = is_integral<_Tp>::value,
2064 bool _IsEnum = __is_enum(_Tp)>
2065 class __make_signed_selector;
2067 template<typename _Tp>
2068 class __make_signed_selector<_Tp, true, false>
2071 = typename __make_signed<__remove_cv_t<_Tp>>::__type;
2075 = typename __match_cv_qualifiers<_Tp, __signed_type>::__type;
2078 // Choose signed integer type with the smallest rank and same size as _Tp
2079 template<typename _Tp>
2080 class __make_signed_selector<_Tp, false, true>
2082 using __unsigned_type = typename __make_unsigned_selector<_Tp>::__type;
2085 using __type = typename __make_signed_selector<__unsigned_type>::__type;
2088 // wchar_t, char16_t and char32_t are integral types but are neither
2089 // signed integer types nor unsigned integer types, so must be
2090 // transformed to the signed integer type with the smallest rank.
2091 // Use the partial specialization for enumeration types to do that.
2093 struct __make_signed<wchar_t>
2096 = typename __make_signed_selector<wchar_t, false, true>::__type;
2099 #if defined(_GLIBCXX_USE_CHAR8_T)
2101 struct __make_signed<char8_t>
2104 = typename __make_signed_selector<char8_t, false, true>::__type;
2109 struct __make_signed<char16_t>
2112 = typename __make_signed_selector<char16_t, false, true>::__type;
2116 struct __make_signed<char32_t>
2119 = typename __make_signed_selector<char32_t, false, true>::__type;
2123 // Given an integral/enum type, return the corresponding signed
2125 // Primary template.
2127 template<typename _Tp>
2129 { using type = typename __make_signed_selector<_Tp>::__type; };
2131 // Integral, but don't define.
2132 template<> struct make_signed<bool>;
2133 template<> struct make_signed<bool const>;
2134 template<> struct make_signed<bool volatile>;
2135 template<> struct make_signed<bool const volatile>;
2137 #if __cplusplus > 201103L
2138 /// Alias template for make_signed
2139 template<typename _Tp>
2140 using make_signed_t = typename make_signed<_Tp>::type;
2142 /// Alias template for make_unsigned
2143 template<typename _Tp>
2144 using make_unsigned_t = typename make_unsigned<_Tp>::type;
2147 // Array modifications.
2150 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_extent)
2151 template<typename _Tp>
2152 struct remove_extent
2153 { using type = __remove_extent(_Tp); };
2155 template<typename _Tp>
2156 struct remove_extent
2157 { using type = _Tp; };
2159 template<typename _Tp, std::size_t _Size>
2160 struct remove_extent<_Tp[_Size]>
2161 { using type = _Tp; };
2163 template<typename _Tp>
2164 struct remove_extent<_Tp[]>
2165 { using type = _Tp; };
2168 /// remove_all_extents
2169 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_all_extents)
2170 template<typename _Tp>
2171 struct remove_all_extents
2172 { using type = __remove_all_extents(_Tp); };
2174 template<typename _Tp>
2175 struct remove_all_extents
2176 { using type = _Tp; };
2178 template<typename _Tp, std::size_t _Size>
2179 struct remove_all_extents<_Tp[_Size]>
2180 { using type = typename remove_all_extents<_Tp>::type; };
2182 template<typename _Tp>
2183 struct remove_all_extents<_Tp[]>
2184 { using type = typename remove_all_extents<_Tp>::type; };
2187 #if __cplusplus > 201103L
2188 /// Alias template for remove_extent
2189 template<typename _Tp>
2190 using remove_extent_t = typename remove_extent<_Tp>::type;
2192 /// Alias template for remove_all_extents
2193 template<typename _Tp>
2194 using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
2197 // Pointer modifications.
2200 #if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_pointer)
2201 template<typename _Tp>
2202 struct remove_pointer
2203 { using type = __remove_pointer(_Tp); };
2205 template<typename _Tp, typename>
2206 struct __remove_pointer_helper
2207 { using type = _Tp; };
2209 template<typename _Tp, typename _Up>
2210 struct __remove_pointer_helper<_Tp, _Up*>
2211 { using type = _Up; };
2213 template<typename _Tp>
2214 struct remove_pointer
2215 : public __remove_pointer_helper<_Tp, __remove_cv_t<_Tp>>
2220 #if _GLIBCXX_USE_BUILTIN_TRAIT(__add_pointer)
2221 template<typename _Tp>
2223 { using type = __add_pointer(_Tp); };
2225 template<typename _Tp, typename = void>
2226 struct __add_pointer_helper
2227 { using type = _Tp; };
2229 template<typename _Tp>
2230 struct __add_pointer_helper<_Tp, __void_t<_Tp*>>
2231 { using type = _Tp*; };
2233 template<typename _Tp>
2235 : public __add_pointer_helper<_Tp>
2238 template<typename _Tp>
2239 struct add_pointer<_Tp&>
2240 { using type = _Tp*; };
2242 template<typename _Tp>
2243 struct add_pointer<_Tp&&>
2244 { using type = _Tp*; };
2247 #if __cplusplus > 201103L
2248 /// Alias template for remove_pointer
2249 template<typename _Tp>
2250 using remove_pointer_t = typename remove_pointer<_Tp>::type;
2252 /// Alias template for add_pointer
2253 template<typename _Tp>
2254 using add_pointer_t = typename add_pointer<_Tp>::type;
2257 /// @cond undocumented
2259 // Aligned to maximum fundamental alignment
2260 struct __attribute__((__aligned__)) __aligned_storage_max_align_t
2264 __aligned_storage_default_alignment([[__maybe_unused__]] size_t __len)
2266 #if _GLIBCXX_INLINE_VERSION
2268 = integral_constant<size_t, alignof(__aligned_storage_max_align_t)>;
2270 return __len > (_Max_align::value / 2)
2272 # if _GLIBCXX_USE_BUILTIN_TRAIT(__builtin_clzg)
2273 : 1 << (__SIZE_WIDTH__ - __builtin_clzg(__len - 1u));
2275 : 1 << (__LLONG_WIDTH__ - __builtin_clzll(__len - 1ull));
2278 // Returning a fixed value is incorrect, but kept for ABI compatibility.
2279 // XXX GLIBCXX_ABI Deprecated
2280 return alignof(__aligned_storage_max_align_t);
2286 * @brief Aligned storage
2288 * The member typedef `type` is be a POD type suitable for use as
2289 * uninitialized storage for any object whose size is at most `_Len`
2290 * and whose alignment is a divisor of `_Align`.
2292 * It is important to use the nested `type` as uninitialized storage,
2293 * not the `std::aligned_storage` type itself which is an empty class
2294 * with 1-byte alignment. So this is correct:
2296 * `typename std::aligned_storage<sizeof(X), alignof(X)>::type m_xobj;`
2300 * `std::aligned_storage<sizeof(X), alignof(X)> m_xobj;`
2302 * In C++14 and later `std::aligned_storage_t<sizeof(X), alignof(X)>`
2303 * can be used to refer to the `type` member typedef.
2305 * The default value of _Align is supposed to be the most stringent
2306 * fundamental alignment requirement for any C++ object type whose size
2307 * is no greater than `_Len` (see [basic.align] in the C++ standard).
2309 * @bug In this implementation the default value for _Align is always the
2310 * maximum fundamental alignment, i.e. `alignof(max_align_t)`, which is
2311 * incorrect. It should be an alignment value no greater than `_Len`.
2313 * @deprecated Deprecated in C++23. Uses can be replaced by an
2314 * array `std::byte[_Len]` declared with `alignas(_Align)`.
2316 template<size_t _Len,
2317 size_t _Align = __aligned_storage_default_alignment(_Len)>
2319 _GLIBCXX23_DEPRECATED
2324 alignas(_Align) unsigned char __data[_Len];
2328 template <typename... _Types>
2329 struct __strictest_alignment
2331 static const size_t _S_alignment = 0;
2332 static const size_t _S_size = 0;
2335 template <typename _Tp, typename... _Types>
2336 struct __strictest_alignment<_Tp, _Types...>
2338 static const size_t _S_alignment =
2339 alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment
2340 ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment;
2341 static const size_t _S_size =
2342 sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size
2343 ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size;
2346 #pragma GCC diagnostic push
2347 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2350 * @brief Provide aligned storage for types.
2352 * [meta.trans.other]
2354 * Provides aligned storage for any of the provided types of at
2357 * @see aligned_storage
2359 * @deprecated Deprecated in C++23.
2361 template <size_t _Len, typename... _Types>
2363 _GLIBCXX23_DEPRECATED
2367 static_assert(sizeof...(_Types) != 0, "At least one type is required");
2369 using __strictest = __strictest_alignment<_Types...>;
2370 static const size_t _S_len = _Len > __strictest::_S_size
2371 ? _Len : __strictest::_S_size;
2373 /// The value of the strictest alignment of _Types.
2374 static const size_t alignment_value = __strictest::_S_alignment;
2376 using type = typename aligned_storage<_S_len, alignment_value>::type;
2379 template <size_t _Len, typename... _Types>
2380 const size_t aligned_union<_Len, _Types...>::alignment_value;
2381 #pragma GCC diagnostic pop
2383 /// @cond undocumented
2385 #if _GLIBCXX_USE_BUILTIN_TRAIT(__decay)
2386 template<typename _Tp>
2388 { using type = __decay(_Tp); };
2390 // Decay trait for arrays and functions, used for perfect forwarding
2391 // in make_pair, make_tuple, etc.
2392 template<typename _Up>
2393 struct __decay_selector
2394 : __conditional_t<is_const<const _Up>::value, // false for functions
2395 remove_cv<_Up>, // N.B. DR 705.
2396 add_pointer<_Up>> // function decays to pointer
2399 template<typename _Up, size_t _Nm>
2400 struct __decay_selector<_Up[_Nm]>
2401 { using type = _Up*; };
2403 template<typename _Up>
2404 struct __decay_selector<_Up[]>
2405 { using type = _Up*; };
2410 template<typename _Tp>
2412 { using type = typename __decay_selector<_Tp>::type; };
2414 template<typename _Tp>
2416 { using type = typename __decay_selector<_Tp>::type; };
2418 template<typename _Tp>
2420 { using type = typename __decay_selector<_Tp>::type; };
2423 /// @cond undocumented
2425 // Helper which adds a reference to a type when given a reference_wrapper
2426 template<typename _Tp>
2427 struct __strip_reference_wrapper
2432 template<typename _Tp>
2433 struct __strip_reference_wrapper<reference_wrapper<_Tp> >
2435 using __type = _Tp&;
2438 // __decay_t (std::decay_t for C++11).
2439 template<typename _Tp>
2440 using __decay_t = typename decay<_Tp>::type;
2442 template<typename _Tp>
2443 using __decay_and_strip = __strip_reference_wrapper<__decay_t<_Tp>>;
2446 /// @cond undocumented
2448 // Helper for SFINAE constraints
2449 template<typename... _Cond>
2450 using _Require = __enable_if_t<__and_<_Cond...>::value>;
2452 // __remove_cvref_t (std::remove_cvref_t for C++11).
2453 template<typename _Tp>
2454 using __remove_cvref_t
2455 = typename remove_cv<typename remove_reference<_Tp>::type>::type;
2458 // Primary template.
2459 /// Define a member typedef @c type to one of two argument types.
2460 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2462 { using type = _Iftrue; };
2464 // Partial specialization for false.
2465 template<typename _Iftrue, typename _Iffalse>
2466 struct conditional<false, _Iftrue, _Iffalse>
2467 { using type = _Iffalse; };
2470 template<typename... _Tp>
2473 // Sfinae-friendly common_type implementation:
2475 /// @cond undocumented
2477 // For several sfinae-friendly trait implementations we transport both the
2478 // result information (as the member type) and the failure information (no
2479 // member type). This is very similar to std::enable_if, but we cannot use
2480 // that, because we need to derive from them as an implementation detail.
2482 template<typename _Tp>
2483 struct __success_type
2484 { using type = _Tp; };
2486 struct __failure_type
2489 struct __do_common_type_impl
2491 template<typename _Tp, typename _Up>
2493 = decltype(true ? std::declval<_Tp>() : std::declval<_Up>());
2495 // if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2496 // denotes a valid type, let C denote that type.
2497 template<typename _Tp, typename _Up>
2498 static __success_type<__decay_t<__cond_t<_Tp, _Up>>>
2501 #if __cplusplus > 201703L
2502 // Otherwise, if COND-RES(CREF(D1), CREF(D2)) denotes a type,
2503 // let C denote the type decay_t<COND-RES(CREF(D1), CREF(D2))>.
2504 template<typename _Tp, typename _Up>
2505 static __success_type<__remove_cvref_t<__cond_t<const _Tp&, const _Up&>>>
2509 template<typename, typename>
2510 static __failure_type
2513 template<typename _Tp, typename _Up>
2514 static decltype(_S_test_2<_Tp, _Up>(0))
2518 // If sizeof...(T) is zero, there shall be no member type.
2520 struct common_type<>
2523 // If sizeof...(T) is one, the same type, if any, as common_type_t<T0, T0>.
2524 template<typename _Tp0>
2525 struct common_type<_Tp0>
2526 : public common_type<_Tp0, _Tp0>
2529 // If sizeof...(T) is two, ...
2530 template<typename _Tp1, typename _Tp2,
2531 typename _Dp1 = __decay_t<_Tp1>, typename _Dp2 = __decay_t<_Tp2>>
2532 struct __common_type_impl
2534 // If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false,
2535 // let C denote the same type, if any, as common_type_t<D1, D2>.
2536 using type = common_type<_Dp1, _Dp2>;
2539 template<typename _Tp1, typename _Tp2>
2540 struct __common_type_impl<_Tp1, _Tp2, _Tp1, _Tp2>
2541 : private __do_common_type_impl
2543 // Otherwise, if decay_t<decltype(false ? declval<D1>() : declval<D2>())>
2544 // denotes a valid type, let C denote that type.
2545 using type = decltype(_S_test<_Tp1, _Tp2>(0));
2548 // If sizeof...(T) is two, ...
2549 template<typename _Tp1, typename _Tp2>
2550 struct common_type<_Tp1, _Tp2>
2551 : public __common_type_impl<_Tp1, _Tp2>::type
2554 template<typename...>
2555 struct __common_type_pack
2558 template<typename, typename, typename = void>
2559 struct __common_type_fold;
2561 // If sizeof...(T) is greater than two, ...
2562 template<typename _Tp1, typename _Tp2, typename... _Rp>
2563 struct common_type<_Tp1, _Tp2, _Rp...>
2564 : public __common_type_fold<common_type<_Tp1, _Tp2>,
2565 __common_type_pack<_Rp...>>
2568 // Let C denote the same type, if any, as common_type_t<T1, T2>.
2569 // If there is such a type C, type shall denote the same type, if any,
2570 // as common_type_t<C, R...>.
2571 template<typename _CTp, typename... _Rp>
2572 struct __common_type_fold<_CTp, __common_type_pack<_Rp...>,
2573 __void_t<typename _CTp::type>>
2574 : public common_type<typename _CTp::type, _Rp...>
2577 // Otherwise, there shall be no member type.
2578 template<typename _CTp, typename _Rp>
2579 struct __common_type_fold<_CTp, _Rp, void>
2582 template<typename _Tp, bool = __is_enum(_Tp)>
2583 struct __underlying_type_impl
2585 using type = __underlying_type(_Tp);
2588 template<typename _Tp>
2589 struct __underlying_type_impl<_Tp, false>
2593 /// The underlying type of an enum.
2594 template<typename _Tp>
2595 struct underlying_type
2596 : public __underlying_type_impl<_Tp>
2599 /// @cond undocumented
2600 template<typename _Tp>
2601 struct __declval_protector
2603 static const bool __stop = false;
2607 /** Utility to simplify expressions used in unevaluated operands
2609 * @ingroup utilities
2611 template<typename _Tp>
2612 auto declval() noexcept -> decltype(__declval<_Tp>(0))
2614 static_assert(__declval_protector<_Tp>::__stop,
2615 "declval() must not be used!");
2616 return __declval<_Tp>(0);
2620 template<typename _Signature>
2623 // Sfinae-friendly result_of implementation:
2625 /// @cond undocumented
2626 struct __invoke_memfun_ref { };
2627 struct __invoke_memfun_deref { };
2628 struct __invoke_memobj_ref { };
2629 struct __invoke_memobj_deref { };
2630 struct __invoke_other { };
2632 // Associate a tag type with a specialization of __success_type.
2633 template<typename _Tp, typename _Tag>
2634 struct __result_of_success : __success_type<_Tp>
2635 { using __invoke_type = _Tag; };
2637 // [func.require] paragraph 1 bullet 1:
2638 struct __result_of_memfun_ref_impl
2640 template<typename _Fp, typename _Tp1, typename... _Args>
2641 static __result_of_success<decltype(
2642 (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...)
2643 ), __invoke_memfun_ref> _S_test(int);
2645 template<typename...>
2646 static __failure_type _S_test(...);
2649 template<typename _MemPtr, typename _Arg, typename... _Args>
2650 struct __result_of_memfun_ref
2651 : private __result_of_memfun_ref_impl
2653 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0));
2656 // [func.require] paragraph 1 bullet 2:
2657 struct __result_of_memfun_deref_impl
2659 template<typename _Fp, typename _Tp1, typename... _Args>
2660 static __result_of_success<decltype(
2661 ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...)
2662 ), __invoke_memfun_deref> _S_test(int);
2664 template<typename...>
2665 static __failure_type _S_test(...);
2668 template<typename _MemPtr, typename _Arg, typename... _Args>
2669 struct __result_of_memfun_deref
2670 : private __result_of_memfun_deref_impl
2672 using type = decltype(_S_test<_MemPtr, _Arg, _Args...>(0));
2675 // [func.require] paragraph 1 bullet 3:
2676 struct __result_of_memobj_ref_impl
2678 template<typename _Fp, typename _Tp1>
2679 static __result_of_success<decltype(
2680 std::declval<_Tp1>().*std::declval<_Fp>()
2681 ), __invoke_memobj_ref> _S_test(int);
2683 template<typename, typename>
2684 static __failure_type _S_test(...);
2687 template<typename _MemPtr, typename _Arg>
2688 struct __result_of_memobj_ref
2689 : private __result_of_memobj_ref_impl
2691 using type = decltype(_S_test<_MemPtr, _Arg>(0));
2694 // [func.require] paragraph 1 bullet 4:
2695 struct __result_of_memobj_deref_impl
2697 template<typename _Fp, typename _Tp1>
2698 static __result_of_success<decltype(
2699 (*std::declval<_Tp1>()).*std::declval<_Fp>()
2700 ), __invoke_memobj_deref> _S_test(int);
2702 template<typename, typename>
2703 static __failure_type _S_test(...);
2706 template<typename _MemPtr, typename _Arg>
2707 struct __result_of_memobj_deref
2708 : private __result_of_memobj_deref_impl
2710 using type = decltype(_S_test<_MemPtr, _Arg>(0));
2713 template<typename _MemPtr, typename _Arg>
2714 struct __result_of_memobj;
2716 template<typename _Res, typename _Class, typename _Arg>
2717 struct __result_of_memobj<_Res _Class::*, _Arg>
2719 using _Argval = __remove_cvref_t<_Arg>;
2720 using _MemPtr = _Res _Class::*;
2721 using type = typename __conditional_t<__or_<is_same<_Argval, _Class>,
2722 is_base_of<_Class, _Argval>>::value,
2723 __result_of_memobj_ref<_MemPtr, _Arg>,
2724 __result_of_memobj_deref<_MemPtr, _Arg>
2728 template<typename _MemPtr, typename _Arg, typename... _Args>
2729 struct __result_of_memfun;
2731 template<typename _Res, typename _Class, typename _Arg, typename... _Args>
2732 struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
2734 using _Argval = typename remove_reference<_Arg>::type;
2735 using _MemPtr = _Res _Class::*;
2736 using type = typename __conditional_t<is_base_of<_Class, _Argval>::value,
2737 __result_of_memfun_ref<_MemPtr, _Arg, _Args...>,
2738 __result_of_memfun_deref<_MemPtr, _Arg, _Args...>
2742 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2743 // 2219. INVOKE-ing a pointer to member with a reference_wrapper
2744 // as the object expression
2746 // Used by result_of, invoke etc. to unwrap a reference_wrapper.
2747 template<typename _Tp, typename _Up = __remove_cvref_t<_Tp>>
2753 template<typename _Tp, typename _Up>
2754 struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
2759 template<bool, bool, typename _Functor, typename... _ArgTypes>
2760 struct __result_of_impl
2762 using type = __failure_type;
2765 template<typename _MemPtr, typename _Arg>
2766 struct __result_of_impl<true, false, _MemPtr, _Arg>
2767 : public __result_of_memobj<__decay_t<_MemPtr>,
2768 typename __inv_unwrap<_Arg>::type>
2771 template<typename _MemPtr, typename _Arg, typename... _Args>
2772 struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
2773 : public __result_of_memfun<__decay_t<_MemPtr>,
2774 typename __inv_unwrap<_Arg>::type, _Args...>
2777 // [func.require] paragraph 1 bullet 5:
2778 struct __result_of_other_impl
2780 template<typename _Fn, typename... _Args>
2781 static __result_of_success<decltype(
2782 std::declval<_Fn>()(std::declval<_Args>()...)
2783 ), __invoke_other> _S_test(int);
2785 template<typename...>
2786 static __failure_type _S_test(...);
2789 template<typename _Functor, typename... _ArgTypes>
2790 struct __result_of_impl<false, false, _Functor, _ArgTypes...>
2791 : private __result_of_other_impl
2793 using type = decltype(_S_test<_Functor, _ArgTypes...>(0));
2796 // __invoke_result (std::invoke_result for C++11)
2797 template<typename _Functor, typename... _ArgTypes>
2798 struct __invoke_result
2799 : public __result_of_impl<
2800 is_member_object_pointer<
2801 typename remove_reference<_Functor>::type
2803 is_member_function_pointer<
2804 typename remove_reference<_Functor>::type
2806 _Functor, _ArgTypes...
2810 // __invoke_result_t (std::invoke_result_t for C++11)
2811 template<typename _Fn, typename... _Args>
2812 using __invoke_result_t = typename __invoke_result<_Fn, _Args...>::type;
2815 template<typename _Functor, typename... _ArgTypes>
2816 struct result_of<_Functor(_ArgTypes...)>
2817 : public __invoke_result<_Functor, _ArgTypes...>
2818 { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result");
2820 #if __cplusplus >= 201402L
2821 #pragma GCC diagnostic push
2822 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2823 /// Alias template for aligned_storage
2824 template<size_t _Len,
2825 size_t _Align = __aligned_storage_default_alignment(_Len)>
2826 using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type;
2828 template <size_t _Len, typename... _Types>
2829 using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type;
2830 #pragma GCC diagnostic pop
2832 /// Alias template for decay
2833 template<typename _Tp>
2834 using decay_t = typename decay<_Tp>::type;
2836 /// Alias template for enable_if
2837 template<bool _Cond, typename _Tp = void>
2838 using enable_if_t = typename enable_if<_Cond, _Tp>::type;
2840 /// Alias template for conditional
2841 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2842 using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type;
2844 /// Alias template for common_type
2845 template<typename... _Tp>
2846 using common_type_t = typename common_type<_Tp...>::type;
2848 /// Alias template for underlying_type
2849 template<typename _Tp>
2850 using underlying_type_t = typename underlying_type<_Tp>::type;
2852 /// Alias template for result_of
2853 template<typename _Tp>
2854 using result_of_t = typename result_of<_Tp>::type;
2857 #ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11
2858 /// A metafunction that always yields void, used for detecting valid types.
2859 template<typename...> using void_t = void;
2862 /// @cond undocumented
2865 // Detect whether _Op<_Args...> is a valid type, use default _Def if not.
2868 // Implementation of the detection idiom (negative case).
2869 template<typename _Def, template<typename...> class _Op, typename... _Args>
2870 struct __detected_or
2873 using __is_detected = false_type;
2876 // Implementation of the detection idiom (positive case).
2877 template<typename _Def, template<typename...> class _Op, typename... _Args>
2878 requires requires { typename _Op<_Args...>; }
2879 struct __detected_or<_Def, _Op, _Args...>
2881 using type = _Op<_Args...>;
2882 using __is_detected = true_type;
2885 /// Implementation of the detection idiom (negative case).
2886 template<typename _Default, typename _AlwaysVoid,
2887 template<typename...> class _Op, typename... _Args>
2890 using type = _Default;
2891 using __is_detected = false_type;
2894 /// Implementation of the detection idiom (positive case).
2895 template<typename _Default, template<typename...> class _Op,
2897 struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...>
2899 using type = _Op<_Args...>;
2900 using __is_detected = true_type;
2903 template<typename _Default, template<typename...> class _Op,
2905 using __detected_or = __detector<_Default, void, _Op, _Args...>;
2906 #endif // __cpp_concepts
2908 // _Op<_Args...> if that is a valid type, otherwise _Default.
2909 template<typename _Default, template<typename...> class _Op,
2911 using __detected_or_t
2912 = typename __detected_or<_Default, _Op, _Args...>::type;
2915 * Use SFINAE to determine if the type _Tp has a publicly-accessible
2916 * member type _NTYPE.
2918 #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
2919 template<typename _Tp, typename = __void_t<>> \
2920 struct __has_##_NTYPE \
2923 template<typename _Tp> \
2924 struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \
2928 template <typename _Tp>
2929 struct __is_swappable;
2931 template <typename _Tp>
2932 struct __is_nothrow_swappable;
2935 struct __is_tuple_like_impl : false_type
2938 // Internal type trait that allows us to sfinae-protect tuple_cat.
2939 template<typename _Tp>
2940 struct __is_tuple_like
2941 : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
2945 template<typename _Tp>
2946 _GLIBCXX20_CONSTEXPR
2948 _Require<__not_<__is_tuple_like<_Tp>>,
2949 is_move_constructible<_Tp>,
2950 is_move_assignable<_Tp>>
2952 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
2953 is_nothrow_move_assignable<_Tp>>::value);
2955 template<typename _Tp, size_t _Nm>
2956 _GLIBCXX20_CONSTEXPR
2958 __enable_if_t<__is_swappable<_Tp>::value>
2959 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
2960 noexcept(__is_nothrow_swappable<_Tp>::value);
2962 /// @cond undocumented
2963 namespace __swappable_details {
2966 struct __do_is_swappable_impl
2968 template<typename _Tp, typename
2969 = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))>
2970 static true_type __test(int);
2973 static false_type __test(...);
2976 struct __do_is_nothrow_swappable_impl
2978 template<typename _Tp>
2979 static __bool_constant<
2980 noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))
2984 static false_type __test(...);
2987 } // namespace __swappable_details
2989 template<typename _Tp>
2990 struct __is_swappable_impl
2991 : public __swappable_details::__do_is_swappable_impl
2993 using type = decltype(__test<_Tp>(0));
2996 template<typename _Tp>
2997 struct __is_nothrow_swappable_impl
2998 : public __swappable_details::__do_is_nothrow_swappable_impl
3000 using type = decltype(__test<_Tp>(0));
3003 template<typename _Tp>
3004 struct __is_swappable
3005 : public __is_swappable_impl<_Tp>::type
3008 template<typename _Tp>
3009 struct __is_nothrow_swappable
3010 : public __is_nothrow_swappable_impl<_Tp>::type
3014 #ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11
3015 /// Metafunctions used for detecting swappable types: p0185r1
3018 template<typename _Tp>
3020 : public __is_swappable_impl<_Tp>::type
3022 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3023 "template argument must be a complete class or an unbounded array");
3026 /// is_nothrow_swappable
3027 template<typename _Tp>
3028 struct is_nothrow_swappable
3029 : public __is_nothrow_swappable_impl<_Tp>::type
3031 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3032 "template argument must be a complete class or an unbounded array");
3035 #if __cplusplus >= 201402L
3037 template<typename _Tp>
3038 _GLIBCXX17_INLINE constexpr bool is_swappable_v =
3039 is_swappable<_Tp>::value;
3041 /// is_nothrow_swappable_v
3042 template<typename _Tp>
3043 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v =
3044 is_nothrow_swappable<_Tp>::value;
3045 #endif // __cplusplus >= 201402L
3047 /// @cond undocumented
3048 namespace __swappable_with_details {
3051 struct __do_is_swappable_with_impl
3053 template<typename _Tp, typename _Up, typename
3054 = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())),
3056 = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))>
3057 static true_type __test(int);
3059 template<typename, typename>
3060 static false_type __test(...);
3063 struct __do_is_nothrow_swappable_with_impl
3065 template<typename _Tp, typename _Up>
3066 static __bool_constant<
3067 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
3069 noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()))
3072 template<typename, typename>
3073 static false_type __test(...);
3076 } // namespace __swappable_with_details
3078 template<typename _Tp, typename _Up>
3079 struct __is_swappable_with_impl
3080 : public __swappable_with_details::__do_is_swappable_with_impl
3082 using type = decltype(__test<_Tp, _Up>(0));
3085 // Optimization for the homogenous lvalue case, not required:
3086 template<typename _Tp>
3087 struct __is_swappable_with_impl<_Tp&, _Tp&>
3088 : public __swappable_details::__do_is_swappable_impl
3090 using type = decltype(__test<_Tp&>(0));
3093 template<typename _Tp, typename _Up>
3094 struct __is_nothrow_swappable_with_impl
3095 : public __swappable_with_details::__do_is_nothrow_swappable_with_impl
3097 using type = decltype(__test<_Tp, _Up>(0));
3100 // Optimization for the homogenous lvalue case, not required:
3101 template<typename _Tp>
3102 struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&>
3103 : public __swappable_details::__do_is_nothrow_swappable_impl
3105 using type = decltype(__test<_Tp&>(0));
3109 /// is_swappable_with
3110 template<typename _Tp, typename _Up>
3111 struct is_swappable_with
3112 : public __is_swappable_with_impl<_Tp, _Up>::type
3114 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3115 "first template argument must be a complete class or an unbounded array");
3116 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3117 "second template argument must be a complete class or an unbounded array");
3120 /// is_nothrow_swappable_with
3121 template<typename _Tp, typename _Up>
3122 struct is_nothrow_swappable_with
3123 : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type
3125 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3126 "first template argument must be a complete class or an unbounded array");
3127 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3128 "second template argument must be a complete class or an unbounded array");
3131 #if __cplusplus >= 201402L
3132 /// is_swappable_with_v
3133 template<typename _Tp, typename _Up>
3134 _GLIBCXX17_INLINE constexpr bool is_swappable_with_v =
3135 is_swappable_with<_Tp, _Up>::value;
3137 /// is_nothrow_swappable_with_v
3138 template<typename _Tp, typename _Up>
3139 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v =
3140 is_nothrow_swappable_with<_Tp, _Up>::value;
3141 #endif // __cplusplus >= 201402L
3143 #endif // __cpp_lib_is_swappable
3145 /// @cond undocumented
3147 // __is_invocable (std::is_invocable for C++11)
3149 // The primary template is used for invalid INVOKE expressions.
3150 template<typename _Result, typename _Ret,
3151 bool = is_void<_Ret>::value, typename = void>
3152 struct __is_invocable_impl
3155 using __nothrow_conv = false_type; // For is_nothrow_invocable_r
3158 // Used for valid INVOKE and INVOKE<void> expressions.
3159 template<typename _Result, typename _Ret>
3160 struct __is_invocable_impl<_Result, _Ret,
3161 /* is_void<_Ret> = */ true,
3162 __void_t<typename _Result::type>>
3165 using __nothrow_conv = true_type; // For is_nothrow_invocable_r
3168 #pragma GCC diagnostic push
3169 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3170 // Used for INVOKE<R> expressions to check the implicit conversion to R.
3171 template<typename _Result, typename _Ret>
3172 struct __is_invocable_impl<_Result, _Ret,
3173 /* is_void<_Ret> = */ false,
3174 __void_t<typename _Result::type>>
3177 // The type of the INVOKE expression.
3178 using _Res_t = typename _Result::type;
3180 // Unlike declval, this doesn't add_rvalue_reference, so it respects
3181 // guaranteed copy elision.
3182 static _Res_t _S_get() noexcept;
3184 // Used to check if _Res_t can implicitly convert to _Tp.
3185 template<typename _Tp>
3186 static void _S_conv(__type_identity_t<_Tp>) noexcept;
3188 // This overload is viable if INVOKE(f, args...) can convert to _Tp.
3189 template<typename _Tp,
3190 bool _Nothrow = noexcept(_S_conv<_Tp>(_S_get())),
3191 typename = decltype(_S_conv<_Tp>(_S_get())),
3192 #if __has_builtin(__reference_converts_from_temporary)
3193 bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t)
3195 bool _Dangle = false
3198 static __bool_constant<_Nothrow && !_Dangle>
3201 template<typename _Tp, bool = false>
3206 // For is_invocable_r
3207 using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1));
3209 // For is_nothrow_invocable_r
3210 using __nothrow_conv = decltype(_S_test<_Ret>(1));
3212 #pragma GCC diagnostic pop
3214 template<typename _Fn, typename... _ArgTypes>
3215 struct __is_invocable
3216 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3219 template<typename _Fn, typename _Tp, typename... _Args>
3220 constexpr bool __call_is_nt(__invoke_memfun_ref)
3222 using _Up = typename __inv_unwrap<_Tp>::type;
3223 return noexcept((std::declval<_Up>().*std::declval<_Fn>())(
3224 std::declval<_Args>()...));
3227 template<typename _Fn, typename _Tp, typename... _Args>
3228 constexpr bool __call_is_nt(__invoke_memfun_deref)
3230 return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())(
3231 std::declval<_Args>()...));
3234 template<typename _Fn, typename _Tp>
3235 constexpr bool __call_is_nt(__invoke_memobj_ref)
3237 using _Up = typename __inv_unwrap<_Tp>::type;
3238 return noexcept(std::declval<_Up>().*std::declval<_Fn>());
3241 template<typename _Fn, typename _Tp>
3242 constexpr bool __call_is_nt(__invoke_memobj_deref)
3244 return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>());
3247 template<typename _Fn, typename... _Args>
3248 constexpr bool __call_is_nt(__invoke_other)
3250 return noexcept(std::declval<_Fn>()(std::declval<_Args>()...));
3253 template<typename _Result, typename _Fn, typename... _Args>
3254 struct __call_is_nothrow
3256 std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{})
3260 template<typename _Fn, typename... _Args>
3261 using __call_is_nothrow_
3262 = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
3264 // __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
3265 template<typename _Fn, typename... _Args>
3266 struct __is_nothrow_invocable
3267 : __and_<__is_invocable<_Fn, _Args...>,
3268 __call_is_nothrow_<_Fn, _Args...>>::type
3271 #pragma GCC diagnostic push
3272 #pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3273 struct __nonesuchbase {};
3274 struct __nonesuch : private __nonesuchbase {
3275 ~__nonesuch() = delete;
3276 __nonesuch(__nonesuch const&) = delete;
3277 void operator=(__nonesuch const&) = delete;
3279 #pragma GCC diagnostic pop
3282 #ifdef __cpp_lib_is_invocable // C++ >= 17
3283 /// std::invoke_result
3284 template<typename _Functor, typename... _ArgTypes>
3285 struct invoke_result
3286 : public __invoke_result<_Functor, _ArgTypes...>
3288 static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}),
3289 "_Functor must be a complete class or an unbounded array");
3290 static_assert((std::__is_complete_or_unbounded(
3291 __type_identity<_ArgTypes>{}) && ...),
3292 "each argument type must be a complete class or an unbounded array");
3295 /// std::invoke_result_t
3296 template<typename _Fn, typename... _Args>
3297 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
3299 /// std::is_invocable
3300 template<typename _Fn, typename... _ArgTypes>
3302 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
3303 : public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
3305 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3308 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3309 "_Fn must be a complete class or an unbounded array");
3310 static_assert((std::__is_complete_or_unbounded(
3311 __type_identity<_ArgTypes>{}) && ...),
3312 "each argument type must be a complete class or an unbounded array");
3315 /// std::is_invocable_r
3316 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3317 struct is_invocable_r
3318 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type
3320 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3321 "_Fn must be a complete class or an unbounded array");
3322 static_assert((std::__is_complete_or_unbounded(
3323 __type_identity<_ArgTypes>{}) && ...),
3324 "each argument type must be a complete class or an unbounded array");
3325 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3326 "_Ret must be a complete class or an unbounded array");
3329 /// std::is_nothrow_invocable
3330 template<typename _Fn, typename... _ArgTypes>
3331 struct is_nothrow_invocable
3332 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
3333 : public __bool_constant<__is_nothrow_invocable(_Fn, _ArgTypes...)>
3335 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
3336 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3339 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3340 "_Fn must be a complete class or an unbounded array");
3341 static_assert((std::__is_complete_or_unbounded(
3342 __type_identity<_ArgTypes>{}) && ...),
3343 "each argument type must be a complete class or an unbounded array");
3346 /// @cond undocumented
3347 // This checks that the INVOKE<R> expression is well-formed and that the
3348 // conversion to R does not throw. It does *not* check whether the INVOKE
3349 // expression itself can throw. That is done by __call_is_nothrow_ instead.
3350 template<typename _Result, typename _Ret>
3351 using __is_nt_invocable_impl
3352 = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv;
3355 /// std::is_nothrow_invocable_r
3356 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3357 struct is_nothrow_invocable_r
3358 : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>,
3359 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3361 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3362 "_Fn must be a complete class or an unbounded array");
3363 static_assert((std::__is_complete_or_unbounded(
3364 __type_identity<_ArgTypes>{}) && ...),
3365 "each argument type must be a complete class or an unbounded array");
3366 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3367 "_Ret must be a complete class or an unbounded array");
3369 #endif // __cpp_lib_is_invocable
3371 #if __cpp_lib_type_trait_variable_templates // C++ >= 17
3373 * @defgroup variable_templates Variable templates for type traits
3374 * @ingroup metaprogramming
3376 * Each variable `is_xxx_v<T>` is a boolean constant with the same value
3377 * as the `value` member of the corresponding type trait `is_xxx<T>`.
3379 * @since C++17 unless noted otherwise.
3384 * @ingroup variable_templates
3386 template <typename _Tp>
3387 inline constexpr bool is_void_v = is_void<_Tp>::value;
3388 template <typename _Tp>
3389 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
3390 template <typename _Tp>
3391 inline constexpr bool is_integral_v = is_integral<_Tp>::value;
3392 template <typename _Tp>
3393 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
3395 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
3396 template <typename _Tp>
3397 inline constexpr bool is_array_v = __is_array(_Tp);
3399 template <typename _Tp>
3400 inline constexpr bool is_array_v = false;
3401 template <typename _Tp>
3402 inline constexpr bool is_array_v<_Tp[]> = true;
3403 template <typename _Tp, size_t _Num>
3404 inline constexpr bool is_array_v<_Tp[_Num]> = true;
3407 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
3408 template <typename _Tp>
3409 inline constexpr bool is_pointer_v = __is_pointer(_Tp);
3411 template <typename _Tp>
3412 inline constexpr bool is_pointer_v = false;
3413 template <typename _Tp>
3414 inline constexpr bool is_pointer_v<_Tp*> = true;
3415 template <typename _Tp>
3416 inline constexpr bool is_pointer_v<_Tp* const> = true;
3417 template <typename _Tp>
3418 inline constexpr bool is_pointer_v<_Tp* volatile> = true;
3419 template <typename _Tp>
3420 inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
3423 template <typename _Tp>
3424 inline constexpr bool is_lvalue_reference_v = false;
3425 template <typename _Tp>
3426 inline constexpr bool is_lvalue_reference_v<_Tp&> = true;
3427 template <typename _Tp>
3428 inline constexpr bool is_rvalue_reference_v = false;
3429 template <typename _Tp>
3430 inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
3432 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
3433 template <typename _Tp>
3434 inline constexpr bool is_member_object_pointer_v =
3435 __is_member_object_pointer(_Tp);
3437 template <typename _Tp>
3438 inline constexpr bool is_member_object_pointer_v =
3439 is_member_object_pointer<_Tp>::value;
3442 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
3443 template <typename _Tp>
3444 inline constexpr bool is_member_function_pointer_v =
3445 __is_member_function_pointer(_Tp);
3447 template <typename _Tp>
3448 inline constexpr bool is_member_function_pointer_v =
3449 is_member_function_pointer<_Tp>::value;
3452 template <typename _Tp>
3453 inline constexpr bool is_enum_v = __is_enum(_Tp);
3454 template <typename _Tp>
3455 inline constexpr bool is_union_v = __is_union(_Tp);
3456 template <typename _Tp>
3457 inline constexpr bool is_class_v = __is_class(_Tp);
3458 // is_function_v is defined below, after is_const_v.
3460 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
3461 template <typename _Tp>
3462 inline constexpr bool is_reference_v = __is_reference(_Tp);
3464 template <typename _Tp>
3465 inline constexpr bool is_reference_v = false;
3466 template <typename _Tp>
3467 inline constexpr bool is_reference_v<_Tp&> = true;
3468 template <typename _Tp>
3469 inline constexpr bool is_reference_v<_Tp&&> = true;
3472 template <typename _Tp>
3473 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
3474 template <typename _Tp>
3475 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
3477 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
3478 template <typename _Tp>
3479 inline constexpr bool is_object_v = __is_object(_Tp);
3481 template <typename _Tp>
3482 inline constexpr bool is_object_v = is_object<_Tp>::value;
3485 template <typename _Tp>
3486 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
3487 template <typename _Tp>
3488 inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
3490 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
3491 template <typename _Tp>
3492 inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
3494 template <typename _Tp>
3495 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
3498 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
3499 template <typename _Tp>
3500 inline constexpr bool is_const_v = __is_const(_Tp);
3502 template <typename _Tp>
3503 inline constexpr bool is_const_v = false;
3504 template <typename _Tp>
3505 inline constexpr bool is_const_v<const _Tp> = true;
3508 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
3509 template <typename _Tp>
3510 inline constexpr bool is_function_v = __is_function(_Tp);
3512 template <typename _Tp>
3513 inline constexpr bool is_function_v = !is_const_v<const _Tp>;
3514 template <typename _Tp>
3515 inline constexpr bool is_function_v<_Tp&> = false;
3516 template <typename _Tp>
3517 inline constexpr bool is_function_v<_Tp&&> = false;
3520 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
3521 template <typename _Tp>
3522 inline constexpr bool is_volatile_v = __is_volatile(_Tp);
3524 template <typename _Tp>
3525 inline constexpr bool is_volatile_v = false;
3526 template <typename _Tp>
3527 inline constexpr bool is_volatile_v<volatile _Tp> = true;
3530 template <typename _Tp>
3531 _GLIBCXX26_DEPRECATED_SUGGEST("is_trivially_default_constructible_v && is_trivially_copyable_v")
3532 inline constexpr bool is_trivial_v = __is_trivial(_Tp);
3533 template <typename _Tp>
3534 inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
3535 template <typename _Tp>
3536 inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
3537 template <typename _Tp>
3538 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v")
3539 inline constexpr bool is_pod_v = __is_pod(_Tp);
3540 template <typename _Tp>
3541 _GLIBCXX17_DEPRECATED
3542 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
3543 template <typename _Tp>
3544 inline constexpr bool is_empty_v = __is_empty(_Tp);
3545 template <typename _Tp>
3546 inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
3547 template <typename _Tp>
3548 inline constexpr bool is_abstract_v = __is_abstract(_Tp);
3549 template <typename _Tp>
3550 inline constexpr bool is_final_v = __is_final(_Tp);
3552 template <typename _Tp>
3553 inline constexpr bool is_signed_v = is_signed<_Tp>::value;
3554 template <typename _Tp>
3555 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
3557 template <typename _Tp, typename... _Args>
3558 inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
3559 template <typename _Tp>
3560 inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
3561 template <typename _Tp>
3562 inline constexpr bool is_copy_constructible_v
3563 = __is_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3564 template <typename _Tp>
3565 inline constexpr bool is_move_constructible_v
3566 = __is_constructible(_Tp, __add_rval_ref_t<_Tp>);
3568 template <typename _Tp, typename _Up>
3569 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up);
3570 template <typename _Tp>
3571 inline constexpr bool is_copy_assignable_v
3572 = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t<const _Tp>);
3573 template <typename _Tp>
3574 inline constexpr bool is_move_assignable_v
3575 = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3577 template <typename _Tp>
3578 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
3580 template <typename _Tp, typename... _Args>
3581 inline constexpr bool is_trivially_constructible_v
3582 = __is_trivially_constructible(_Tp, _Args...);
3583 template <typename _Tp>
3584 inline constexpr bool is_trivially_default_constructible_v
3585 = __is_trivially_constructible(_Tp);
3586 template <typename _Tp>
3587 inline constexpr bool is_trivially_copy_constructible_v
3588 = __is_trivially_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3589 template <typename _Tp>
3590 inline constexpr bool is_trivially_move_constructible_v
3591 = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>);
3593 template <typename _Tp, typename _Up>
3594 inline constexpr bool is_trivially_assignable_v
3595 = __is_trivially_assignable(_Tp, _Up);
3596 template <typename _Tp>
3597 inline constexpr bool is_trivially_copy_assignable_v
3598 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3599 __add_lval_ref_t<const _Tp>);
3600 template <typename _Tp>
3601 inline constexpr bool is_trivially_move_assignable_v
3602 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3603 __add_rval_ref_t<_Tp>);
3606 template <typename _Tp>
3607 inline constexpr bool is_trivially_destructible_v = false;
3609 template <typename _Tp>
3610 requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); }
3611 inline constexpr bool is_trivially_destructible_v<_Tp>
3612 = __has_trivial_destructor(_Tp);
3613 template <typename _Tp>
3614 inline constexpr bool is_trivially_destructible_v<_Tp&> = true;
3615 template <typename _Tp>
3616 inline constexpr bool is_trivially_destructible_v<_Tp&&> = true;
3617 template <typename _Tp, size_t _Nm>
3618 inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]>
3619 = is_trivially_destructible_v<_Tp>;
3621 template <typename _Tp>
3622 inline constexpr bool is_trivially_destructible_v =
3623 is_trivially_destructible<_Tp>::value;
3626 template <typename _Tp, typename... _Args>
3627 inline constexpr bool is_nothrow_constructible_v
3628 = __is_nothrow_constructible(_Tp, _Args...);
3629 template <typename _Tp>
3630 inline constexpr bool is_nothrow_default_constructible_v
3631 = __is_nothrow_constructible(_Tp);
3632 template <typename _Tp>
3633 inline constexpr bool is_nothrow_copy_constructible_v
3634 = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3635 template <typename _Tp>
3636 inline constexpr bool is_nothrow_move_constructible_v
3637 = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>);
3639 template <typename _Tp, typename _Up>
3640 inline constexpr bool is_nothrow_assignable_v
3641 = __is_nothrow_assignable(_Tp, _Up);
3642 template <typename _Tp>
3643 inline constexpr bool is_nothrow_copy_assignable_v
3644 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>,
3645 __add_lval_ref_t<const _Tp>);
3646 template <typename _Tp>
3647 inline constexpr bool is_nothrow_move_assignable_v
3648 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3650 template <typename _Tp>
3651 inline constexpr bool is_nothrow_destructible_v =
3652 is_nothrow_destructible<_Tp>::value;
3654 template <typename _Tp>
3655 inline constexpr bool has_virtual_destructor_v
3656 = __has_virtual_destructor(_Tp);
3658 template <typename _Tp>
3659 inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
3661 #if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank) \
3662 && (!defined(__clang__) || __clang_major__ >= 20) // PR118559
3663 template <typename _Tp>
3664 inline constexpr size_t rank_v = __array_rank(_Tp);
3666 template <typename _Tp>
3667 inline constexpr size_t rank_v = 0;
3668 template <typename _Tp, size_t _Size>
3669 inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>;
3670 template <typename _Tp>
3671 inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>;
3674 template <typename _Tp, unsigned _Idx = 0>
3675 inline constexpr size_t extent_v = 0;
3676 template <typename _Tp, size_t _Size>
3677 inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size;
3678 template <typename _Tp, unsigned _Idx, size_t _Size>
3679 inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>;
3680 template <typename _Tp>
3681 inline constexpr size_t extent_v<_Tp[], 0> = 0;
3682 template <typename _Tp, unsigned _Idx>
3683 inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>;
3685 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same)
3686 template <typename _Tp, typename _Up>
3687 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
3689 template <typename _Tp, typename _Up>
3690 inline constexpr bool is_same_v = false;
3691 template <typename _Tp>
3692 inline constexpr bool is_same_v<_Tp, _Tp> = true;
3694 template <typename _Base, typename _Derived>
3695 inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
3696 #ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
3697 template <typename _Base, typename _Derived>
3698 inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived);
3700 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
3701 template <typename _From, typename _To>
3702 inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
3704 template <typename _From, typename _To>
3705 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
3707 template<typename _Fn, typename... _Args>
3708 inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
3709 template<typename _Fn, typename... _Args>
3710 inline constexpr bool is_nothrow_invocable_v
3711 = is_nothrow_invocable<_Fn, _Args...>::value;
3712 template<typename _Ret, typename _Fn, typename... _Args>
3713 inline constexpr bool is_invocable_r_v
3714 = is_invocable_r<_Ret, _Fn, _Args...>::value;
3715 template<typename _Ret, typename _Fn, typename... _Args>
3716 inline constexpr bool is_nothrow_invocable_r_v
3717 = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
3719 #endif // __cpp_lib_type_trait_variable_templates
3721 #ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP
3722 /// has_unique_object_representations
3724 template<typename _Tp>
3725 struct has_unique_object_representations
3726 : bool_constant<__has_unique_object_representations(
3727 remove_cv_t<remove_all_extents_t<_Tp>>
3730 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3731 "template argument must be a complete class or an unbounded array");
3734 # if __cpp_lib_type_trait_variable_templates // C++ >= 17
3735 /// @ingroup variable_templates
3736 template<typename _Tp>
3737 inline constexpr bool has_unique_object_representations_v
3738 = has_unique_object_representations<_Tp>::value;
3742 #ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate
3743 /// is_aggregate - true if the type is an aggregate.
3745 template<typename _Tp>
3747 : bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
3750 # if __cpp_lib_type_trait_variable_templates // C++ >= 17
3751 /** is_aggregate_v - true if the type is an aggregate.
3752 * @ingroup variable_templates
3755 template<typename _Tp>
3756 inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>);
3760 /** * Remove references and cv-qualifiers.
3764 #ifdef __cpp_lib_remove_cvref // C++ >= 20
3765 # if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref)
3766 template<typename _Tp>
3768 { using type = __remove_cvref(_Tp); };
3770 template<typename _Tp>
3772 { using type = typename remove_cv<_Tp>::type; };
3774 template<typename _Tp>
3775 struct remove_cvref<_Tp&>
3776 { using type = typename remove_cv<_Tp>::type; };
3778 template<typename _Tp>
3779 struct remove_cvref<_Tp&&>
3780 { using type = typename remove_cv<_Tp>::type; };
3783 template<typename _Tp>
3784 using remove_cvref_t = typename remove_cvref<_Tp>::type;
3786 #endif // __cpp_lib_remove_cvref
3788 #ifdef __cpp_lib_type_identity // C++ >= 20
3789 /** * Identity metafunction.
3793 template<typename _Tp>
3794 struct type_identity { using type = _Tp; };
3796 template<typename _Tp>
3797 using type_identity_t = typename type_identity<_Tp>::type;
3801 #ifdef __cpp_lib_unwrap_ref // C++ >= 20
3802 /** Unwrap a reference_wrapper
3806 template<typename _Tp>
3807 struct unwrap_reference { using type = _Tp; };
3809 template<typename _Tp>
3810 struct unwrap_reference<reference_wrapper<_Tp>> { using type = _Tp&; };
3812 template<typename _Tp>
3813 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
3816 /** Decay type and if it's a reference_wrapper, unwrap it
3820 template<typename _Tp>
3821 struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; };
3823 template<typename _Tp>
3824 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
3826 #endif // __cpp_lib_unwrap_ref
3828 #ifdef __cpp_lib_bounded_array_traits // C++ >= 20
3829 /// True for a type that is an array of known bound.
3830 /// @ingroup variable_templates
3832 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
3833 template<typename _Tp>
3834 inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
3836 template<typename _Tp>
3837 inline constexpr bool is_bounded_array_v = false;
3839 template<typename _Tp, size_t _Size>
3840 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
3843 /// True for a type that is an array of unknown bound.
3844 /// @ingroup variable_templates
3846 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
3847 template<typename _Tp>
3848 inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
3850 template<typename _Tp>
3851 inline constexpr bool is_unbounded_array_v = false;
3853 template<typename _Tp>
3854 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
3857 /// True for a type that is an array of known bound.
3859 template<typename _Tp>
3860 struct is_bounded_array
3861 : public bool_constant<is_bounded_array_v<_Tp>>
3864 /// True for a type that is an array of unknown bound.
3866 template<typename _Tp>
3867 struct is_unbounded_array
3868 : public bool_constant<is_unbounded_array_v<_Tp>>
3870 #endif // __cpp_lib_bounded_array_traits
3872 #if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L
3875 template<typename _Tp, typename _Up>
3876 struct is_layout_compatible
3877 : bool_constant<__is_layout_compatible(_Tp, _Up)>
3880 /// @ingroup variable_templates
3882 template<typename _Tp, typename _Up>
3883 constexpr bool is_layout_compatible_v
3884 = __is_layout_compatible(_Tp, _Up);
3886 #if __has_builtin(__builtin_is_corresponding_member)
3887 # ifndef __cpp_lib_is_layout_compatible
3888 # error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set"
3892 template<typename _S1, typename _S2, typename _M1, typename _M2>
3894 is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept
3895 { return __builtin_is_corresponding_member(__m1, __m2); }
3899 #if __has_builtin(__is_pointer_interconvertible_base_of) \
3900 && __cplusplus >= 202002L
3901 /// True if `_Derived` is standard-layout and has a base class of type `_Base`
3903 template<typename _Base, typename _Derived>
3904 struct is_pointer_interconvertible_base_of
3905 : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)>
3908 /// @ingroup variable_templates
3910 template<typename _Base, typename _Derived>
3911 constexpr bool is_pointer_interconvertible_base_of_v
3912 = __is_pointer_interconvertible_base_of(_Base, _Derived);
3914 #if __has_builtin(__builtin_is_pointer_interconvertible_with_class)
3915 # ifndef __cpp_lib_is_pointer_interconvertible
3916 # error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set"
3919 /// True if `__mp` points to the first member of a standard-layout type
3920 /// @returns true if `s.*__mp` is pointer-interconvertible with `s`
3922 template<typename _Tp, typename _Mem>
3924 is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept
3925 { return __builtin_is_pointer_interconvertible_with_class(__mp); }
3929 #ifdef __cpp_lib_is_scoped_enum // C++ >= 23
3930 /// True if the type is a scoped enumeration type.
3933 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
3934 template<typename _Tp>
3935 struct is_scoped_enum
3936 : bool_constant<__is_scoped_enum(_Tp)>
3939 template<typename _Tp>
3940 struct is_scoped_enum
3944 template<typename _Tp>
3945 requires __is_enum(_Tp)
3946 && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete
3947 struct is_scoped_enum<_Tp>
3948 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
3952 /// @ingroup variable_templates
3954 # if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
3955 template<typename _Tp>
3956 inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
3958 template<typename _Tp>
3959 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
3963 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp
3964 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
3965 /// direct-initialization, and a temporary object would be bound to
3966 /// the reference, false otherwise.
3968 template<typename _Tp, typename _Up>
3969 struct reference_constructs_from_temporary
3970 : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)>
3972 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
3973 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3974 "template argument must be a complete class or an unbounded array");
3977 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
3978 /// copy-initialization, and a temporary object would be bound to
3979 /// the reference, false otherwise.
3981 template<typename _Tp, typename _Up>
3982 struct reference_converts_from_temporary
3983 : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)>
3985 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
3986 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3987 "template argument must be a complete class or an unbounded array");
3990 /// @ingroup variable_templates
3992 template<typename _Tp, typename _Up>
3993 inline constexpr bool reference_constructs_from_temporary_v
3994 = reference_constructs_from_temporary<_Tp, _Up>::value;
3996 /// @ingroup variable_templates
3998 template<typename _Tp, typename _Up>
3999 inline constexpr bool reference_converts_from_temporary_v
4000 = reference_converts_from_temporary<_Tp, _Up>::value;
4001 #endif // __cpp_lib_reference_from_temporary
4003 #ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL
4004 /// Returns true only when called during constant evaluation.
4006 constexpr inline bool
4007 is_constant_evaluated() noexcept
4009 #if __cpp_if_consteval >= 202106L
4010 if consteval { return true; } else { return false; }
4012 return __builtin_is_constant_evaluated();
4017 #if __cplusplus >= 202002L
4018 /// @cond undocumented
4019 template<typename _From, typename _To>
4020 using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type;
4022 template<typename _Xp, typename _Yp>
4024 = decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
4026 template<typename _Ap, typename _Bp, typename = void>
4027 struct __common_ref_impl
4030 // [meta.trans.other], COMMON-REF(A, B)
4031 template<typename _Ap, typename _Bp>
4032 using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type;
4034 // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &)
4035 template<typename _Xp, typename _Yp>
4036 using __condres_cvref
4037 = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>;
4039 // If A and B are both lvalue reference types, ...
4040 template<typename _Xp, typename _Yp>
4041 struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>>
4042 : enable_if<is_reference_v<__condres_cvref<_Xp, _Yp>>,
4043 __condres_cvref<_Xp, _Yp>>
4046 // let C be remove_reference_t<COMMON-REF(X&, Y&)>&&
4047 template<typename _Xp, typename _Yp>
4048 using __common_ref_C = remove_reference_t<__common_ref<_Xp&, _Yp&>>&&;
4050 // If A and B are both rvalue reference types, ...
4051 template<typename _Xp, typename _Yp>
4052 struct __common_ref_impl<_Xp&&, _Yp&&,
4053 _Require<is_convertible<_Xp&&, __common_ref_C<_Xp, _Yp>>,
4054 is_convertible<_Yp&&, __common_ref_C<_Xp, _Yp>>>>
4055 { using type = __common_ref_C<_Xp, _Yp>; };
4057 // let D be COMMON-REF(const X&, Y&)
4058 template<typename _Xp, typename _Yp>
4059 using __common_ref_D = __common_ref<const _Xp&, _Yp&>;
4061 // If A is an rvalue reference and B is an lvalue reference, ...
4062 template<typename _Xp, typename _Yp>
4063 struct __common_ref_impl<_Xp&&, _Yp&,
4064 _Require<is_convertible<_Xp&&, __common_ref_D<_Xp, _Yp>>>>
4065 { using type = __common_ref_D<_Xp, _Yp>; };
4067 // If A is an lvalue reference and B is an rvalue reference, ...
4068 template<typename _Xp, typename _Yp>
4069 struct __common_ref_impl<_Xp&, _Yp&&>
4070 : __common_ref_impl<_Yp&&, _Xp&>
4074 template<typename _Tp, typename _Up,
4075 template<typename> class _TQual, template<typename> class _UQual>
4076 struct basic_common_reference
4079 /// @cond undocumented
4080 template<typename _Tp>
4082 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>; };
4084 template<typename _Tp>
4086 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&; };
4088 template<typename _Tp>
4089 struct __xref<_Tp&&>
4090 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&&; };
4092 template<typename _Tp1, typename _Tp2>
4093 using __basic_common_ref
4094 = typename basic_common_reference<remove_cvref_t<_Tp1>,
4095 remove_cvref_t<_Tp2>,
4096 __xref<_Tp1>::template __type,
4097 __xref<_Tp2>::template __type>::type;
4100 template<typename... _Tp>
4101 struct common_reference;
4103 template<typename... _Tp>
4104 using common_reference_t = typename common_reference<_Tp...>::type;
4106 // If sizeof...(T) is zero, there shall be no member type.
4108 struct common_reference<>
4111 // If sizeof...(T) is one ...
4112 template<typename _Tp0>
4113 struct common_reference<_Tp0>
4114 { using type = _Tp0; };
4116 /// @cond undocumented
4117 template<typename _Tp1, typename _Tp2, int _Bullet = 1>
4118 struct __common_reference_impl
4119 : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1>
4122 // If sizeof...(T) is two ...
4123 template<typename _Tp1, typename _Tp2>
4124 struct common_reference<_Tp1, _Tp2>
4125 : __common_reference_impl<_Tp1, _Tp2>
4128 // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ...
4129 template<typename _Tp1, typename _Tp2>
4130 requires is_reference_v<_Tp1> && is_reference_v<_Tp2>
4131 && requires { typename __common_ref<_Tp1, _Tp2>; }
4132 #if __cpp_lib_common_reference // C++ >= 20
4133 && is_convertible_v<add_pointer_t<_Tp1>,
4134 add_pointer_t<__common_ref<_Tp1, _Tp2>>>
4135 && is_convertible_v<add_pointer_t<_Tp2>,
4136 add_pointer_t<__common_ref<_Tp1, _Tp2>>>
4138 struct __common_reference_impl<_Tp1, _Tp2, 1>
4139 { using type = __common_ref<_Tp1, _Tp2>; };
4141 // Otherwise, if basic_common_reference<...>::type is well-formed, ...
4142 template<typename _Tp1, typename _Tp2>
4143 requires requires { typename __basic_common_ref<_Tp1, _Tp2>; }
4144 struct __common_reference_impl<_Tp1, _Tp2, 2>
4145 { using type = __basic_common_ref<_Tp1, _Tp2>; };
4147 // Otherwise, if COND-RES(T1, T2) is well-formed, ...
4148 template<typename _Tp1, typename _Tp2>
4149 requires requires { typename __cond_res<_Tp1, _Tp2>; }
4150 struct __common_reference_impl<_Tp1, _Tp2, 3>
4151 { using type = __cond_res<_Tp1, _Tp2>; };
4153 // Otherwise, if common_type_t<T1, T2> is well-formed, ...
4154 template<typename _Tp1, typename _Tp2>
4155 requires requires { typename common_type_t<_Tp1, _Tp2>; }
4156 struct __common_reference_impl<_Tp1, _Tp2, 4>
4157 { using type = common_type_t<_Tp1, _Tp2>; };
4159 // Otherwise, there shall be no member type.
4160 template<typename _Tp1, typename _Tp2>
4161 struct __common_reference_impl<_Tp1, _Tp2, 5>
4164 // Otherwise, if sizeof...(T) is greater than two, ...
4165 template<typename _Tp1, typename _Tp2, typename... _Rest>
4166 struct common_reference<_Tp1, _Tp2, _Rest...>
4167 : __common_type_fold<common_reference<_Tp1, _Tp2>,
4168 __common_type_pack<_Rest...>>
4171 // Reuse __common_type_fold for common_reference<T1, T2, Rest...>
4172 template<typename _Tp1, typename _Tp2, typename... _Rest>
4173 struct __common_type_fold<common_reference<_Tp1, _Tp2>,
4174 __common_type_pack<_Rest...>,
4175 void_t<common_reference_t<_Tp1, _Tp2>>>
4176 : public common_reference<common_reference_t<_Tp1, _Tp2>, _Rest...>
4182 /// @} group metaprogramming
4184 _GLIBCXX_END_NAMESPACE_VERSION
4190 #endif // _GLIBCXX_TYPE_TRAITS