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