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