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