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