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