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 using type = typename __conditional_t<__or_<is_same<_Argval, _Class>,
2853 is_base_of<_Class, _Argval>>::value,
2854 __result_of_memobj_ref<_MemPtr, _Arg>,
2855 __result_of_memobj_deref<_MemPtr, _Arg>
2856 >::type;
2857 };
2858
2859 template<typename _MemPtr, typename _Arg, typename... _Args>
2860 struct __result_of_memfun;
2861
2862 template<typename _Res, typename _Class, typename _Arg, typename... _Args>
2863 struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
2864 {
2865 using _Argval = typename remove_reference<_Arg>::type;
2866 using _MemPtr = _Res _Class::*;
2867 using type = typename __conditional_t<is_base_of<_Class, _Argval>::value,
2868 __result_of_memfun_ref<_MemPtr, _Arg, _Args...>,
2869 __result_of_memfun_deref<_MemPtr, _Arg, _Args...>
2870 >::type;
2871 };
2872
2873 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2874 // 2219. INVOKE-ing a pointer to member with a reference_wrapper
2875 // as the object expression
2876
2877 // Used by result_of, invoke etc. to unwrap a reference_wrapper.
2878 template<typename _Tp, typename _Up = __remove_cvref_t<_Tp>>
2879 struct __inv_unwrap
2880 {
2881 using type = _Tp;
2882 };
2883
2884 template<typename _Tp, typename _Up>
2885 struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
2886 {
2887 using type = _Up&;
2888 };
2889
2890 template<bool, bool, typename _Functor, typename... _ArgTypes>
2891 struct __result_of_impl
2892 {
2893 using type = __failure_type;
2894 };
2895
2896 template<typename _MemPtr, typename _Arg>
2897 struct __result_of_impl<true, false, _MemPtr, _Arg>
2898 : public __result_of_memobj<__decay_t<_MemPtr>,
2899 typename __inv_unwrap<_Arg>::type>
2900 { };
2901
2902 template<typename _MemPtr, typename _Arg, typename... _Args>
2903 struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
2904 : public __result_of_memfun<__decay_t<_MemPtr>,
2905 typename __inv_unwrap<_Arg>::type, _Args...>
2906 { };
2907
2908 // [func.require] paragraph 1 bullet 5:
2909 struct __result_of_other_impl
2910 {
2911 template<typename _Fn, typename... _Args>
2912 static __result_of_success<decltype(
2914 ), __invoke_other> _S_test(int);
2915
2916 template<typename...>
2917 static __failure_type _S_test(...);
2918 };
2919
2920 template<typename _Functor, typename... _ArgTypes>
2921 struct __result_of_impl<false, false, _Functor, _ArgTypes...>
2922 : private __result_of_other_impl
2923 {
2924 using type = decltype(_S_test<_Functor, _ArgTypes...>(0));
2925 };
2926
2927 // __invoke_result (std::invoke_result for C++11)
2928 template<typename _Functor, typename... _ArgTypes>
2929 struct __invoke_result
2930 : public __result_of_impl<
2931 is_member_object_pointer<
2932 typename remove_reference<_Functor>::type
2933 >::value,
2934 is_member_function_pointer<
2935 typename remove_reference<_Functor>::type
2936 >::value,
2937 _Functor, _ArgTypes...
2938 >::type
2939 { };
2940
2941 // __invoke_result_t (std::invoke_result_t for C++11)
2942 template<typename _Fn, typename... _Args>
2943 using __invoke_result_t = typename __invoke_result<_Fn, _Args...>::type;
2944 /// @endcond
2945
2946 template<typename _Functor, typename... _ArgTypes>
2947 struct result_of<_Functor(_ArgTypes...)>
2948 : public __invoke_result<_Functor, _ArgTypes...>
2949 { } _GLIBCXX17_DEPRECATED_SUGGEST("std::invoke_result");
2950
2951#if __cplusplus >= 201402L
2952#pragma GCC diagnostic push
2953#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2954 /// Alias template for aligned_storage
2955 template<size_t _Len,
2956 size_t _Align = __aligned_storage_default_alignment(_Len)>
2957 using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type;
2958
2959 template <size_t _Len, typename... _Types>
2960 using aligned_union_t _GLIBCXX23_DEPRECATED = typename aligned_union<_Len, _Types...>::type;
2961#pragma GCC diagnostic pop
2962
2963 /// Alias template for decay
2964 template<typename _Tp>
2965 using decay_t = typename decay<_Tp>::type;
2966
2967 /// Alias template for enable_if
2968 template<bool _Cond, typename _Tp = void>
2970
2971 /// Alias template for conditional
2972 template<bool _Cond, typename _Iftrue, typename _Iffalse>
2973 using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type;
2974
2975 /// Alias template for common_type
2976 template<typename... _Tp>
2977 using common_type_t = typename common_type<_Tp...>::type;
2978
2979 /// Alias template for underlying_type
2980 template<typename _Tp>
2982
2983 /// Alias template for result_of
2984 template<typename _Tp>
2985 using result_of_t = typename result_of<_Tp>::type;
2986#endif // C++14
2987
2988#ifdef __cpp_lib_void_t // C++ >= 17 || GNU++ >= 11
2989 /// A metafunction that always yields void, used for detecting valid types.
2990 template<typename...> using void_t = void;
2991#endif
2992
2993 /// @cond undocumented
2994
2995 // Detection idiom.
2996 // Detect whether _Op<_Args...> is a valid type, use default _Def if not.
2997
2998#if __cpp_concepts
2999 // Implementation of the detection idiom (negative case).
3000 template<typename _Def, template<typename...> class _Op, typename... _Args>
3001 struct __detected_or
3002 {
3003 using type = _Def;
3004 using __is_detected = false_type;
3005 };
3006
3007 // Implementation of the detection idiom (positive case).
3008 template<typename _Def, template<typename...> class _Op, typename... _Args>
3009 requires requires { typename _Op<_Args...>; }
3010 struct __detected_or<_Def, _Op, _Args...>
3011 {
3012 using type = _Op<_Args...>;
3013 using __is_detected = true_type;
3014 };
3015#else
3016 /// Implementation of the detection idiom (negative case).
3017 template<typename _Default, typename _AlwaysVoid,
3018 template<typename...> class _Op, typename... _Args>
3019 struct __detector
3020 {
3021 using type = _Default;
3022 using __is_detected = false_type;
3023 };
3024
3025 /// Implementation of the detection idiom (positive case).
3026 template<typename _Default, template<typename...> class _Op,
3027 typename... _Args>
3028 struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...>
3029 {
3030 using type = _Op<_Args...>;
3031 using __is_detected = true_type;
3032 };
3033
3034 template<typename _Default, template<typename...> class _Op,
3035 typename... _Args>
3036 using __detected_or = __detector<_Default, void, _Op, _Args...>;
3037#endif // __cpp_concepts
3038
3039 // _Op<_Args...> if that is a valid type, otherwise _Default.
3040 template<typename _Default, template<typename...> class _Op,
3041 typename... _Args>
3042 using __detected_or_t
3043 = typename __detected_or<_Default, _Op, _Args...>::type;
3044
3045 /**
3046 * Use SFINAE to determine if the type _Tp has a publicly-accessible
3047 * member type _NTYPE.
3048 */
3049#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
3050 template<typename _Tp, typename = __void_t<>> \
3051 struct __has_##_NTYPE \
3052 : false_type \
3053 { }; \
3054 template<typename _Tp> \
3055 struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \
3056 : true_type \
3057 { };
3058
3059 template <typename _Tp>
3060 struct __is_swappable;
3061
3062 template <typename _Tp>
3063 struct __is_nothrow_swappable;
3064
3065 template<typename>
3066 struct __is_tuple_like_impl : false_type
3067 { };
3068
3069 // Internal type trait that allows us to sfinae-protect tuple_cat.
3070 template<typename _Tp>
3071 struct __is_tuple_like
3072 : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type
3073 { };
3074 /// @endcond
3075
3076 template<typename _Tp>
3077 _GLIBCXX20_CONSTEXPR
3078 inline
3079 _Require<__not_<__is_tuple_like<_Tp>>,
3082 swap(_Tp&, _Tp&)
3083 noexcept(__and_<is_nothrow_move_constructible<_Tp>,
3085
3086 template<typename _Tp, size_t _Nm>
3087 _GLIBCXX20_CONSTEXPR
3088 inline
3089 __enable_if_t<__is_swappable<_Tp>::value>
3090 swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
3091 noexcept(__is_nothrow_swappable<_Tp>::value);
3092
3093 /// @cond undocumented
3094 namespace __swappable_details {
3095 using std::swap;
3096
3097 struct __do_is_swappable_impl
3098 {
3099 template<typename _Tp, typename
3100 = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))>
3101 static true_type __test(int);
3102
3103 template<typename>
3104 static false_type __test(...);
3105 };
3106
3107 struct __do_is_nothrow_swappable_impl
3108 {
3109 template<typename _Tp>
3110 static __bool_constant<
3111 noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))
3112 > __test(int);
3113
3114 template<typename>
3115 static false_type __test(...);
3116 };
3117
3118 } // namespace __swappable_details
3119
3120 template<typename _Tp>
3121 struct __is_swappable_impl
3122 : public __swappable_details::__do_is_swappable_impl
3123 {
3124 using type = decltype(__test<_Tp>(0));
3125 };
3126
3127 template<typename _Tp>
3128 struct __is_nothrow_swappable_impl
3129 : public __swappable_details::__do_is_nothrow_swappable_impl
3130 {
3131 using type = decltype(__test<_Tp>(0));
3132 };
3133
3134 template<typename _Tp>
3135 struct __is_swappable
3136 : public __is_swappable_impl<_Tp>::type
3137 { };
3138
3139 template<typename _Tp>
3140 struct __is_nothrow_swappable
3141 : public __is_nothrow_swappable_impl<_Tp>::type
3142 { };
3143 /// @endcond
3144
3145#ifdef __cpp_lib_is_swappable // C++ >= 17 || GNU++ >= 11
3146 /// Metafunctions used for detecting swappable types: p0185r1
3147
3148 /// is_swappable
3149 template<typename _Tp>
3150 struct is_swappable
3151 : public __is_swappable_impl<_Tp>::type
3152 {
3153 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3154 "template argument must be a complete class or an unbounded array");
3155 };
3156
3157 /// is_nothrow_swappable
3158 template<typename _Tp>
3159 struct is_nothrow_swappable
3160 : public __is_nothrow_swappable_impl<_Tp>::type
3161 {
3162 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3163 "template argument must be a complete class or an unbounded array");
3164 };
3165
3166#if __cplusplus >= 201402L
3167 /// is_swappable_v
3168 template<typename _Tp>
3169 _GLIBCXX17_INLINE constexpr bool is_swappable_v =
3170 is_swappable<_Tp>::value;
3171
3172 /// is_nothrow_swappable_v
3173 template<typename _Tp>
3174 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v =
3175 is_nothrow_swappable<_Tp>::value;
3176#endif // __cplusplus >= 201402L
3177
3178 /// @cond undocumented
3179 namespace __swappable_with_details {
3180 using std::swap;
3181
3182 struct __do_is_swappable_with_impl
3183 {
3184 template<typename _Tp, typename _Up, typename
3185 = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())),
3186 typename
3187 = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))>
3188 static true_type __test(int);
3189
3190 template<typename, typename>
3191 static false_type __test(...);
3192 };
3193
3194 struct __do_is_nothrow_swappable_with_impl
3195 {
3196 template<typename _Tp, typename _Up>
3197 static __bool_constant<
3198 noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
3199 &&
3200 noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()))
3201 > __test(int);
3202
3203 template<typename, typename>
3204 static false_type __test(...);
3205 };
3206
3207 } // namespace __swappable_with_details
3208
3209 template<typename _Tp, typename _Up>
3210 struct __is_swappable_with_impl
3211 : public __swappable_with_details::__do_is_swappable_with_impl
3212 {
3213 using type = decltype(__test<_Tp, _Up>(0));
3214 };
3215
3216 // Optimization for the homogenous lvalue case, not required:
3217 template<typename _Tp>
3218 struct __is_swappable_with_impl<_Tp&, _Tp&>
3219 : public __swappable_details::__do_is_swappable_impl
3220 {
3221 using type = decltype(__test<_Tp&>(0));
3222 };
3223
3224 template<typename _Tp, typename _Up>
3225 struct __is_nothrow_swappable_with_impl
3226 : public __swappable_with_details::__do_is_nothrow_swappable_with_impl
3227 {
3228 using type = decltype(__test<_Tp, _Up>(0));
3229 };
3230
3231 // Optimization for the homogenous lvalue case, not required:
3232 template<typename _Tp>
3233 struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&>
3234 : public __swappable_details::__do_is_nothrow_swappable_impl
3235 {
3236 using type = decltype(__test<_Tp&>(0));
3237 };
3238 /// @endcond
3239
3240 /// is_swappable_with
3241 template<typename _Tp, typename _Up>
3242 struct is_swappable_with
3243 : public __is_swappable_with_impl<_Tp, _Up>::type
3244 {
3245 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3246 "first template argument must be a complete class or an unbounded array");
3247 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3248 "second template argument must be a complete class or an unbounded array");
3249 };
3250
3251 /// is_nothrow_swappable_with
3252 template<typename _Tp, typename _Up>
3253 struct is_nothrow_swappable_with
3254 : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type
3255 {
3256 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3257 "first template argument must be a complete class or an unbounded array");
3258 static_assert(std::__is_complete_or_unbounded(__type_identity<_Up>{}),
3259 "second template argument must be a complete class or an unbounded array");
3260 };
3261
3262#if __cplusplus >= 201402L
3263 /// is_swappable_with_v
3264 template<typename _Tp, typename _Up>
3265 _GLIBCXX17_INLINE constexpr bool is_swappable_with_v =
3266 is_swappable_with<_Tp, _Up>::value;
3267
3268 /// is_nothrow_swappable_with_v
3269 template<typename _Tp, typename _Up>
3270 _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v =
3271 is_nothrow_swappable_with<_Tp, _Up>::value;
3272#endif // __cplusplus >= 201402L
3273
3274#endif // __cpp_lib_is_swappable
3275
3276 /// @cond undocumented
3277
3278 // __is_invocable (std::is_invocable for C++11)
3279
3280 // The primary template is used for invalid INVOKE expressions.
3281 template<typename _Result, typename _Ret,
3282 bool = is_void<_Ret>::value, typename = void>
3283 struct __is_invocable_impl
3284 : false_type
3285 {
3286 using __nothrow_conv = false_type; // For is_nothrow_invocable_r
3287 };
3288
3289 // Used for valid INVOKE and INVOKE<void> expressions.
3290 template<typename _Result, typename _Ret>
3291 struct __is_invocable_impl<_Result, _Ret,
3292 /* is_void<_Ret> = */ true,
3293 __void_t<typename _Result::type>>
3294 : true_type
3295 {
3296 using __nothrow_conv = true_type; // For is_nothrow_invocable_r
3297 };
3298
3299#pragma GCC diagnostic push
3300#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3301 // Used for INVOKE<R> expressions to check the implicit conversion to R.
3302 template<typename _Result, typename _Ret>
3303 struct __is_invocable_impl<_Result, _Ret,
3304 /* is_void<_Ret> = */ false,
3305 __void_t<typename _Result::type>>
3306 {
3307 private:
3308 // The type of the INVOKE expression.
3309 using _Res_t = typename _Result::type;
3310
3311 // Unlike declval, this doesn't add_rvalue_reference, so it respects
3312 // guaranteed copy elision.
3313 static _Res_t _S_get() noexcept;
3314
3315 // Used to check if _Res_t can implicitly convert to _Tp.
3316 template<typename _Tp>
3317 static void _S_conv(__type_identity_t<_Tp>) noexcept;
3318
3319 // This overload is viable if INVOKE(f, args...) can convert to _Tp.
3320 template<typename _Tp,
3321 bool _Nothrow = noexcept(_S_conv<_Tp>(_S_get())),
3322 typename = decltype(_S_conv<_Tp>(_S_get())),
3323#if __has_builtin(__reference_converts_from_temporary)
3324 bool _Dangle = __reference_converts_from_temporary(_Tp, _Res_t)
3325#else
3326 bool _Dangle = false
3327#endif
3328 >
3329 static __bool_constant<_Nothrow && !_Dangle>
3330 _S_test(int);
3331
3332 template<typename _Tp, bool = false>
3333 static false_type
3334 _S_test(...);
3335
3336 public:
3337 // For is_invocable_r
3338 using type = decltype(_S_test<_Ret, /* Nothrow = */ true>(1));
3339
3340 // For is_nothrow_invocable_r
3341 using __nothrow_conv = decltype(_S_test<_Ret>(1));
3342 };
3343#pragma GCC diagnostic pop
3344
3345 template<typename _Fn, typename... _ArgTypes>
3346 struct __is_invocable
3347#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
3348 : __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
3349#else
3350 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3351#endif
3352 { };
3353
3354 template<typename _Fn, typename _Tp, typename... _Args>
3355 constexpr bool __call_is_nt(__invoke_memfun_ref)
3356 {
3357 using _Up = typename __inv_unwrap<_Tp>::type;
3358 return noexcept((std::declval<_Up>().*std::declval<_Fn>())(
3359 std::declval<_Args>()...));
3360 }
3361
3362 template<typename _Fn, typename _Tp, typename... _Args>
3363 constexpr bool __call_is_nt(__invoke_memfun_deref)
3364 {
3365 return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())(
3366 std::declval<_Args>()...));
3367 }
3368
3369 template<typename _Fn, typename _Tp>
3370 constexpr bool __call_is_nt(__invoke_memobj_ref)
3371 {
3372 using _Up = typename __inv_unwrap<_Tp>::type;
3373 return noexcept(std::declval<_Up>().*std::declval<_Fn>());
3374 }
3375
3376 template<typename _Fn, typename _Tp>
3377 constexpr bool __call_is_nt(__invoke_memobj_deref)
3378 {
3379 return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>());
3380 }
3381
3382 template<typename _Fn, typename... _Args>
3383 constexpr bool __call_is_nt(__invoke_other)
3384 {
3385 return noexcept(std::declval<_Fn>()(std::declval<_Args>()...));
3386 }
3387
3388 template<typename _Result, typename _Fn, typename... _Args>
3389 struct __call_is_nothrow
3390 : __bool_constant<
3391 std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{})
3392 >
3393 { };
3394
3395 template<typename _Fn, typename... _Args>
3396 using __call_is_nothrow_
3397 = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>;
3398
3399 // __is_nothrow_invocable (std::is_nothrow_invocable for C++11)
3400 template<typename _Fn, typename... _Args>
3401 struct __is_nothrow_invocable
3402#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
3403 : __bool_constant<__is_nothrow_invocable(_Fn, _Args...)>
3404#else
3405 : __and_<__is_invocable<_Fn, _Args...>,
3406 __call_is_nothrow_<_Fn, _Args...>>::type
3407#endif
3408 { };
3409
3410#pragma GCC diagnostic push
3411#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
3412 struct __nonesuchbase {};
3413 struct __nonesuch : private __nonesuchbase {
3414 ~__nonesuch() = delete;
3415 __nonesuch(__nonesuch const&) = delete;
3416 void operator=(__nonesuch const&) = delete;
3417 };
3418#pragma GCC diagnostic pop
3419 /// @endcond
3420
3421#ifdef __cpp_lib_is_invocable // C++ >= 17
3422 /// std::invoke_result
3423 template<typename _Functor, typename... _ArgTypes>
3424 struct invoke_result
3425 : public __invoke_result<_Functor, _ArgTypes...>
3426 {
3427 static_assert(std::__is_complete_or_unbounded(__type_identity<_Functor>{}),
3428 "_Functor must be a complete class or an unbounded array");
3429 static_assert((std::__is_complete_or_unbounded(
3430 __type_identity<_ArgTypes>{}) && ...),
3431 "each argument type must be a complete class or an unbounded array");
3432 };
3433
3434 /// std::invoke_result_t
3435 template<typename _Fn, typename... _Args>
3436 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
3437
3438 /// std::is_invocable
3439 template<typename _Fn, typename... _ArgTypes>
3440 struct is_invocable
3441#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
3442 : public __bool_constant<__is_invocable(_Fn, _ArgTypes...)>
3443#else
3444 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
3445#endif
3446 {
3447 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3448 "_Fn must be a complete class or an unbounded array");
3449 static_assert((std::__is_complete_or_unbounded(
3450 __type_identity<_ArgTypes>{}) && ...),
3451 "each argument type must be a complete class or an unbounded array");
3452 };
3453
3454 /// std::is_invocable_r
3455 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3456 struct is_invocable_r
3457 : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type
3458 {
3459 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3460 "_Fn must be a complete class or an unbounded array");
3461 static_assert((std::__is_complete_or_unbounded(
3462 __type_identity<_ArgTypes>{}) && ...),
3463 "each argument type must be a complete class or an unbounded array");
3464 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3465 "_Ret must be a complete class or an unbounded array");
3466 };
3467
3468 /// std::is_nothrow_invocable
3469 template<typename _Fn, typename... _ArgTypes>
3470 struct is_nothrow_invocable
3471#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
3472 : public __bool_constant<__is_nothrow_invocable(_Fn, _ArgTypes...)>
3473#else
3474 : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>,
3475 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3476#endif
3477 {
3478 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3479 "_Fn must be a complete class or an unbounded array");
3480 static_assert((std::__is_complete_or_unbounded(
3481 __type_identity<_ArgTypes>{}) && ...),
3482 "each argument type must be a complete class or an unbounded array");
3483 };
3484
3485 /// @cond undocumented
3486 // This checks that the INVOKE<R> expression is well-formed and that the
3487 // conversion to R does not throw. It does *not* check whether the INVOKE
3488 // expression itself can throw. That is done by __call_is_nothrow_ instead.
3489 template<typename _Result, typename _Ret>
3490 using __is_nt_invocable_impl
3491 = typename __is_invocable_impl<_Result, _Ret>::__nothrow_conv;
3492 /// @endcond
3493
3494 /// std::is_nothrow_invocable_r
3495 template<typename _Ret, typename _Fn, typename... _ArgTypes>
3496 struct is_nothrow_invocable_r
3497 : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>,
3498 __call_is_nothrow_<_Fn, _ArgTypes...>>::type
3499 {
3500 static_assert(std::__is_complete_or_unbounded(__type_identity<_Fn>{}),
3501 "_Fn must be a complete class or an unbounded array");
3502 static_assert((std::__is_complete_or_unbounded(
3503 __type_identity<_ArgTypes>{}) && ...),
3504 "each argument type must be a complete class or an unbounded array");
3505 static_assert(std::__is_complete_or_unbounded(__type_identity<_Ret>{}),
3506 "_Ret must be a complete class or an unbounded array");
3507 };
3508#endif // __cpp_lib_is_invocable
3509
3510#if __cpp_lib_type_trait_variable_templates // C++ >= 17
3511 /**
3512 * @defgroup variable_templates Variable templates for type traits
3513 * @ingroup metaprogramming
3514 *
3515 * Each variable `is_xxx_v<T>` is a boolean constant with the same value
3516 * as the `value` member of the corresponding type trait `is_xxx<T>`.
3517 *
3518 * @since C++17 unless noted otherwise.
3519 */
3520
3521 /**
3522 * @{
3523 * @ingroup variable_templates
3524 */
3525template <typename _Tp>
3526 inline constexpr bool is_void_v = is_void<_Tp>::value;
3527template <typename _Tp>
3528 inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value;
3529template <typename _Tp>
3530 inline constexpr bool is_integral_v = is_integral<_Tp>::value;
3531template <typename _Tp>
3532 inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
3533
3534#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_array)
3535template <typename _Tp>
3536 inline constexpr bool is_array_v = __is_array(_Tp);
3537#else
3538template <typename _Tp>
3539 inline constexpr bool is_array_v = false;
3540template <typename _Tp>
3541 inline constexpr bool is_array_v<_Tp[]> = true;
3542template <typename _Tp, size_t _Num>
3543 inline constexpr bool is_array_v<_Tp[_Num]> = true;
3544#endif
3545
3546#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_pointer)
3547template <typename _Tp>
3548 inline constexpr bool is_pointer_v = __is_pointer(_Tp);
3549#else
3550template <typename _Tp>
3551 inline constexpr bool is_pointer_v = false;
3552template <typename _Tp>
3553 inline constexpr bool is_pointer_v<_Tp*> = true;
3554template <typename _Tp>
3555 inline constexpr bool is_pointer_v<_Tp* const> = true;
3556template <typename _Tp>
3557 inline constexpr bool is_pointer_v<_Tp* volatile> = true;
3558template <typename _Tp>
3559 inline constexpr bool is_pointer_v<_Tp* const volatile> = true;
3560#endif
3561
3562template <typename _Tp>
3563 inline constexpr bool is_lvalue_reference_v = false;
3564template <typename _Tp>
3565 inline constexpr bool is_lvalue_reference_v<_Tp&> = true;
3566template <typename _Tp>
3567 inline constexpr bool is_rvalue_reference_v = false;
3568template <typename _Tp>
3569 inline constexpr bool is_rvalue_reference_v<_Tp&&> = true;
3570
3571#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_object_pointer)
3572template <typename _Tp>
3573 inline constexpr bool is_member_object_pointer_v =
3574 __is_member_object_pointer(_Tp);
3575#else
3576template <typename _Tp>
3577 inline constexpr bool is_member_object_pointer_v =
3579#endif
3580
3581#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_function_pointer)
3582template <typename _Tp>
3583 inline constexpr bool is_member_function_pointer_v =
3584 __is_member_function_pointer(_Tp);
3585#else
3586template <typename _Tp>
3587 inline constexpr bool is_member_function_pointer_v =
3589#endif
3590
3591#if __cpp_impl_reflection >= 202506L // C++ >= 26
3592template <typename _Tp>
3593 inline constexpr bool is_reflection_v = false;
3594template <>
3595 inline constexpr bool is_reflection_v<decltype(^^int)> = true;
3596template <>
3597 inline constexpr bool is_reflection_v<const decltype(^^int)> = true;
3598template <>
3599 inline constexpr bool is_reflection_v<volatile decltype(^^int)> = true;
3600template <>
3601 inline constexpr bool is_reflection_v<const volatile decltype(^^int)> = true;
3602#endif
3603
3604template <typename _Tp>
3605 inline constexpr bool is_enum_v = __is_enum(_Tp);
3606template <typename _Tp>
3607 inline constexpr bool is_union_v = __is_union(_Tp);
3608template <typename _Tp>
3609 inline constexpr bool is_class_v = __is_class(_Tp);
3610// is_function_v is defined below, after is_const_v.
3611
3612#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_reference)
3613template <typename _Tp>
3614 inline constexpr bool is_reference_v = __is_reference(_Tp);
3615#else
3616template <typename _Tp>
3617 inline constexpr bool is_reference_v = false;
3618template <typename _Tp>
3619 inline constexpr bool is_reference_v<_Tp&> = true;
3620template <typename _Tp>
3621 inline constexpr bool is_reference_v<_Tp&&> = true;
3622#endif
3623
3624template <typename _Tp>
3625 inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
3626template <typename _Tp>
3627 inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
3628
3629#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
3630template <typename _Tp>
3631 inline constexpr bool is_object_v = __is_object(_Tp);
3632#else
3633template <typename _Tp>
3634 inline constexpr bool is_object_v = is_object<_Tp>::value;
3635#endif
3636
3637template <typename _Tp>
3638 inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
3639template <typename _Tp>
3640 inline constexpr bool is_compound_v = !is_fundamental_v<_Tp>;
3641
3642#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_member_pointer)
3643template <typename _Tp>
3644 inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp);
3645#else
3646template <typename _Tp>
3647 inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
3648#endif
3649
3650#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_const)
3651template <typename _Tp>
3652 inline constexpr bool is_const_v = __is_const(_Tp);
3653#else
3654template <typename _Tp>
3655 inline constexpr bool is_const_v = false;
3656template <typename _Tp>
3657 inline constexpr bool is_const_v<const _Tp> = true;
3658#endif
3659
3660#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
3661template <typename _Tp>
3662 inline constexpr bool is_function_v = __is_function(_Tp);
3663#else
3664template <typename _Tp>
3665 inline constexpr bool is_function_v = !is_const_v<const _Tp>;
3666template <typename _Tp>
3667 inline constexpr bool is_function_v<_Tp&> = false;
3668template <typename _Tp>
3669 inline constexpr bool is_function_v<_Tp&&> = false;
3670#endif
3671
3672#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_volatile)
3673template <typename _Tp>
3674 inline constexpr bool is_volatile_v = __is_volatile(_Tp);
3675#else
3676template <typename _Tp>
3677 inline constexpr bool is_volatile_v = false;
3678template <typename _Tp>
3679 inline constexpr bool is_volatile_v<volatile _Tp> = true;
3680#endif
3681
3682template <typename _Tp>
3683 _GLIBCXX26_DEPRECATED_SUGGEST("is_trivially_default_constructible_v && is_trivially_copyable_v")
3684 inline constexpr bool is_trivial_v = __is_trivial(_Tp);
3685template <typename _Tp>
3686 inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
3687template <typename _Tp>
3688 inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
3689template <typename _Tp>
3690 _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout_v && is_trivial_v")
3691 inline constexpr bool is_pod_v = __is_pod(_Tp);
3692template <typename _Tp>
3693 _GLIBCXX17_DEPRECATED
3694 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
3695template <typename _Tp>
3696 inline constexpr bool is_empty_v = __is_empty(_Tp);
3697template <typename _Tp>
3698 inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
3699template <typename _Tp>
3700 inline constexpr bool is_abstract_v = __is_abstract(_Tp);
3701template <typename _Tp>
3702 inline constexpr bool is_final_v = __is_final(_Tp);
3703
3704template <typename _Tp>
3705 inline constexpr bool is_signed_v = is_signed<_Tp>::value;
3706template <typename _Tp>
3707 inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
3708
3709template <typename _Tp, typename... _Args>
3710 inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
3711template <typename _Tp>
3712 inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);
3713template <typename _Tp>
3714 inline constexpr bool is_copy_constructible_v
3715 = __is_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3716template <typename _Tp>
3717 inline constexpr bool is_move_constructible_v
3718 = __is_constructible(_Tp, __add_rval_ref_t<_Tp>);
3719
3720template <typename _Tp, typename _Up>
3721 inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Up);
3722template <typename _Tp>
3723 inline constexpr bool is_copy_assignable_v
3724 = __is_assignable(__add_lval_ref_t<_Tp>, __add_lval_ref_t<const _Tp>);
3725template <typename _Tp>
3726 inline constexpr bool is_move_assignable_v
3727 = __is_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3728
3729#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_destructible)
3730template <typename _Tp>
3731 inline constexpr bool is_destructible_v = __is_destructible(_Tp);
3732#else
3733template <typename _Tp>
3734 inline constexpr bool is_destructible_v = is_destructible<_Tp>::value;
3735#endif
3736
3737template <typename _Tp, typename... _Args>
3738 inline constexpr bool is_trivially_constructible_v
3739 = __is_trivially_constructible(_Tp, _Args...);
3740template <typename _Tp>
3741 inline constexpr bool is_trivially_default_constructible_v
3742 = __is_trivially_constructible(_Tp);
3743template <typename _Tp>
3744 inline constexpr bool is_trivially_copy_constructible_v
3745 = __is_trivially_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3746template <typename _Tp>
3747 inline constexpr bool is_trivially_move_constructible_v
3748 = __is_trivially_constructible(_Tp, __add_rval_ref_t<_Tp>);
3749
3750template <typename _Tp, typename _Up>
3751 inline constexpr bool is_trivially_assignable_v
3752 = __is_trivially_assignable(_Tp, _Up);
3753template <typename _Tp>
3754 inline constexpr bool is_trivially_copy_assignable_v
3755 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3756 __add_lval_ref_t<const _Tp>);
3757template <typename _Tp>
3758 inline constexpr bool is_trivially_move_assignable_v
3759 = __is_trivially_assignable(__add_lval_ref_t<_Tp>,
3760 __add_rval_ref_t<_Tp>);
3761
3762#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_trivially_destructible)
3763template <typename _Tp>
3764 inline constexpr bool is_trivially_destructible_v
3765 = __is_trivially_destructible(_Tp);
3766#elif __cpp_concepts
3767template <typename _Tp>
3768 inline constexpr bool is_trivially_destructible_v = false;
3769
3770template <typename _Tp>
3771 requires (!is_reference_v<_Tp>) && requires (_Tp& __t) { __t.~_Tp(); }
3772 inline constexpr bool is_trivially_destructible_v<_Tp>
3773 = __has_trivial_destructor(_Tp);
3774template <typename _Tp>
3775 inline constexpr bool is_trivially_destructible_v<_Tp&> = true;
3776template <typename _Tp>
3777 inline constexpr bool is_trivially_destructible_v<_Tp&&> = true;
3778template <typename _Tp, size_t _Nm>
3779 inline constexpr bool is_trivially_destructible_v<_Tp[_Nm]>
3780 = is_trivially_destructible_v<_Tp>;
3781#else
3782template <typename _Tp>
3783 inline constexpr bool is_trivially_destructible_v =
3785#endif
3786
3787template <typename _Tp, typename... _Args>
3788 inline constexpr bool is_nothrow_constructible_v
3789 = __is_nothrow_constructible(_Tp, _Args...);
3790template <typename _Tp>
3791 inline constexpr bool is_nothrow_default_constructible_v
3792 = __is_nothrow_constructible(_Tp);
3793template <typename _Tp>
3794 inline constexpr bool is_nothrow_copy_constructible_v
3795 = __is_nothrow_constructible(_Tp, __add_lval_ref_t<const _Tp>);
3796template <typename _Tp>
3797 inline constexpr bool is_nothrow_move_constructible_v
3798 = __is_nothrow_constructible(_Tp, __add_rval_ref_t<_Tp>);
3799
3800template <typename _Tp, typename _Up>
3801 inline constexpr bool is_nothrow_assignable_v
3802 = __is_nothrow_assignable(_Tp, _Up);
3803template <typename _Tp>
3804 inline constexpr bool is_nothrow_copy_assignable_v
3805 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>,
3806 __add_lval_ref_t<const _Tp>);
3807template <typename _Tp>
3808 inline constexpr bool is_nothrow_move_assignable_v
3809 = __is_nothrow_assignable(__add_lval_ref_t<_Tp>, __add_rval_ref_t<_Tp>);
3810
3811#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_destructible)
3812template <typename _Tp>
3813 inline constexpr bool is_nothrow_destructible_v
3814 = __is_nothrow_destructible(_Tp);
3815#else
3816template <typename _Tp>
3817 inline constexpr bool is_nothrow_destructible_v =
3819#endif
3820
3821template <typename _Tp>
3822 inline constexpr bool has_virtual_destructor_v
3823 = __has_virtual_destructor(_Tp);
3824
3825template <typename _Tp>
3826 inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value;
3827
3828#if _GLIBCXX_USE_BUILTIN_TRAIT(__array_rank) \
3829 && (!defined(__clang__) || __clang_major__ >= 20) // PR118559
3830template <typename _Tp>
3831 inline constexpr size_t rank_v = __array_rank(_Tp);
3832#else
3833template <typename _Tp>
3834 inline constexpr size_t rank_v = 0;
3835template <typename _Tp, size_t _Size>
3836 inline constexpr size_t rank_v<_Tp[_Size]> = 1 + rank_v<_Tp>;
3837template <typename _Tp>
3838 inline constexpr size_t rank_v<_Tp[]> = 1 + rank_v<_Tp>;
3839#endif
3840
3841template <typename _Tp, unsigned _Idx = 0>
3842 inline constexpr size_t extent_v = 0;
3843template <typename _Tp, size_t _Size>
3844 inline constexpr size_t extent_v<_Tp[_Size], 0> = _Size;
3845template <typename _Tp, unsigned _Idx, size_t _Size>
3846 inline constexpr size_t extent_v<_Tp[_Size], _Idx> = extent_v<_Tp, _Idx - 1>;
3847template <typename _Tp>
3848 inline constexpr size_t extent_v<_Tp[], 0> = 0;
3849template <typename _Tp, unsigned _Idx>
3850 inline constexpr size_t extent_v<_Tp[], _Idx> = extent_v<_Tp, _Idx - 1>;
3851
3852#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_same)
3853template <typename _Tp, typename _Up>
3854 inline constexpr bool is_same_v = __is_same(_Tp, _Up);
3855#else
3856template <typename _Tp, typename _Up>
3857 inline constexpr bool is_same_v = false;
3858template <typename _Tp>
3859 inline constexpr bool is_same_v<_Tp, _Tp> = true;
3860#endif
3861template <typename _Base, typename _Derived>
3862 inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
3863#ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
3864template <typename _Base, typename _Derived>
3865 inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived);
3866#endif
3867#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
3868template <typename _From, typename _To>
3869 inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
3870#else
3871template <typename _From, typename _To>
3872 inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value;
3873#endif
3874template<typename _Fn, typename... _Args>
3875 inline constexpr bool is_invocable_v
3876#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_invocable)
3877 = __is_invocable(_Fn, _Args...);
3878#else
3879 = is_invocable<_Fn, _Args...>::value;
3880#endif
3881template<typename _Fn, typename... _Args>
3882 inline constexpr bool is_nothrow_invocable_v
3883#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_nothrow_invocable)
3884 = __is_nothrow_invocable(_Fn, _Args...);
3885#else
3886 = is_nothrow_invocable<_Fn, _Args...>::value;
3887#endif
3888template<typename _Ret, typename _Fn, typename... _Args>
3889 inline constexpr bool is_invocable_r_v
3890 = is_invocable_r<_Ret, _Fn, _Args...>::value;
3891template<typename _Ret, typename _Fn, typename... _Args>
3892 inline constexpr bool is_nothrow_invocable_r_v
3893 = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
3894/// @}
3895#endif // __cpp_lib_type_trait_variable_templates
3896
3897#ifdef __cpp_lib_has_unique_object_representations // C++ >= 17 && HAS_UNIQ_OBJ_REP
3898 /// has_unique_object_representations
3899 /// @since C++17
3900 template<typename _Tp>
3901 struct has_unique_object_representations
3902 : bool_constant<__has_unique_object_representations(
3903 remove_cv_t<remove_all_extents_t<_Tp>>
3904 )>
3905 {
3906 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
3907 "template argument must be a complete class or an unbounded array");
3908 };
3909
3910# if __cpp_lib_type_trait_variable_templates // C++ >= 17
3911 /// @ingroup variable_templates
3912 template<typename _Tp>
3913 inline constexpr bool has_unique_object_representations_v
3914 = has_unique_object_representations<_Tp>::value;
3915# endif
3916#endif
3917
3918#ifdef __cpp_lib_is_aggregate // C++ >= 17 && builtin_is_aggregate
3919 /// is_aggregate - true if the type is an aggregate.
3920 /// @since C++17
3921 template<typename _Tp>
3922 struct is_aggregate
3923 : bool_constant<__is_aggregate(remove_cv_t<_Tp>)>
3924 { };
3925
3926# if __cpp_lib_type_trait_variable_templates // C++ >= 17
3927 /** is_aggregate_v - true if the type is an aggregate.
3928 * @ingroup variable_templates
3929 * @since C++17
3930 */
3931 template<typename _Tp>
3932 inline constexpr bool is_aggregate_v = __is_aggregate(remove_cv_t<_Tp>);
3933# endif
3934#endif
3935
3936#if __cpp_lib_is_structural >= 202603L // C++ >= 26
3937 /// is_structural - true if the type is a structural type.
3938 /// @since C++26
3939 template<typename _Tp>
3940 struct is_structural
3941 : bool_constant<__builtin_is_structural(_Tp)>
3942 { };
3943
3944 /** is_structural_v - true if the type is a structural only type.
3945 * @ingroup variable_templates
3946 * @since C++26
3947 */
3948 template<typename _Tp>
3949 inline constexpr bool is_structural_v
3950 = __builtin_is_structural(_Tp);
3951#endif
3952
3953 /** * Remove references and cv-qualifiers.
3954 * @since C++20
3955 * @{
3956 */
3957#ifdef __cpp_lib_remove_cvref // C++ >= 20
3958# if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_cvref)
3959 template<typename _Tp>
3960 struct remove_cvref
3961 { using type = __remove_cvref(_Tp); };
3962# else
3963 template<typename _Tp>
3964 struct remove_cvref
3965 { using type = typename remove_cv<_Tp>::type; };
3966
3967 template<typename _Tp>
3968 struct remove_cvref<_Tp&>
3969 { using type = typename remove_cv<_Tp>::type; };
3970
3971 template<typename _Tp>
3972 struct remove_cvref<_Tp&&>
3973 { using type = typename remove_cv<_Tp>::type; };
3974# endif
3975
3976 template<typename _Tp>
3977 using remove_cvref_t = typename remove_cvref<_Tp>::type;
3978 /// @}
3979#endif // __cpp_lib_remove_cvref
3980
3981#ifdef __cpp_lib_unwrap_ref // C++ >= 20
3982 /** Unwrap a reference_wrapper
3983 * @since C++20
3984 * @{
3985 */
3986 template<typename _Tp>
3987 struct unwrap_reference { using type = _Tp; };
3988
3989 template<typename _Tp>
3990 struct unwrap_reference<reference_wrapper<_Tp>> { using type = _Tp&; };
3991
3992 template<typename _Tp>
3993 using unwrap_reference_t = typename unwrap_reference<_Tp>::type;
3994 /// @}
3995
3996 /** Decay type and if it's a reference_wrapper, unwrap it
3997 * @since C++20
3998 * @{
3999 */
4000 template<typename _Tp>
4001 struct unwrap_ref_decay { using type = unwrap_reference_t<decay_t<_Tp>>; };
4002
4003 template<typename _Tp>
4004 using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
4005 /// @}
4006#endif // __cpp_lib_unwrap_ref
4007
4008#ifdef __cpp_lib_bounded_array_traits // C++ >= 20
4009 /// True for a type that is an array of known bound.
4010 /// @ingroup variable_templates
4011 /// @since C++20
4012# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_bounded_array)
4013 template<typename _Tp>
4014 inline constexpr bool is_bounded_array_v = __is_bounded_array(_Tp);
4015# else
4016 template<typename _Tp>
4017 inline constexpr bool is_bounded_array_v = false;
4018
4019 template<typename _Tp, size_t _Size>
4020 inline constexpr bool is_bounded_array_v<_Tp[_Size]> = true;
4021# endif
4022
4023 /// True for a type that is an array of unknown bound.
4024 /// @ingroup variable_templates
4025 /// @since C++20
4026# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_unbounded_array)
4027 template<typename _Tp>
4028 inline constexpr bool is_unbounded_array_v = __is_unbounded_array(_Tp);
4029# else
4030 template<typename _Tp>
4031 inline constexpr bool is_unbounded_array_v = false;
4032
4033 template<typename _Tp>
4034 inline constexpr bool is_unbounded_array_v<_Tp[]> = true;
4035# endif
4036
4037 /// True for a type that is an array of known bound.
4038 /// @since C++20
4039 template<typename _Tp>
4040 struct is_bounded_array
4041 : public bool_constant<is_bounded_array_v<_Tp>>
4042 { };
4043
4044 /// True for a type that is an array of unknown bound.
4045 /// @since C++20
4046 template<typename _Tp>
4047 struct is_unbounded_array
4048 : public bool_constant<is_unbounded_array_v<_Tp>>
4049 { };
4050#endif // __cpp_lib_bounded_array_traits
4051
4052#if __has_builtin(__is_layout_compatible) && __cplusplus >= 202002L
4053
4054 /// @since C++20
4055 template<typename _Tp, typename _Up>
4057 : bool_constant<__is_layout_compatible(_Tp, _Up)>
4058 { };
4059
4060 /// @ingroup variable_templates
4061 /// @since C++20
4062 template<typename _Tp, typename _Up>
4063 constexpr bool is_layout_compatible_v
4064 = __is_layout_compatible(_Tp, _Up);
4065
4066#if __has_builtin(__builtin_is_corresponding_member)
4067# ifndef __cpp_lib_is_layout_compatible
4068# error "libstdc++ bug: is_corresponding_member and is_layout_compatible are provided but their FTM is not set"
4069# endif
4070
4071 /// @since C++20
4072 template<typename _S1, typename _S2, typename _M1, typename _M2>
4073 constexpr bool
4074 is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept
4075 { return __builtin_is_corresponding_member(__m1, __m2); }
4076#endif
4077#endif
4078
4079#if __has_builtin(__is_pointer_interconvertible_base_of) \
4080 && __cplusplus >= 202002L
4081 /// True if `_Derived` is standard-layout and has a base class of type `_Base`
4082 /// @since C++20
4083 template<typename _Base, typename _Derived>
4085 : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)>
4086 { };
4087
4088 /// @ingroup variable_templates
4089 /// @since C++20
4090 template<typename _Base, typename _Derived>
4092 = __is_pointer_interconvertible_base_of(_Base, _Derived);
4093
4094#if __has_builtin(__builtin_is_pointer_interconvertible_with_class)
4095# ifndef __cpp_lib_is_pointer_interconvertible
4096# error "libstdc++ bug: is_pointer_interconvertible available but FTM is not set"
4097# endif
4098
4099 /// True if `__mp` points to the first member of a standard-layout type
4100 /// @returns true if `s.*__mp` is pointer-interconvertible with `s`
4101 /// @since C++20
4102 template<typename _Tp, typename _Mem>
4103 constexpr bool
4104 is_pointer_interconvertible_with_class(_Mem _Tp::*__mp) noexcept
4105 { return __builtin_is_pointer_interconvertible_with_class(__mp); }
4106#endif
4107#endif
4108
4109#ifdef __cpp_lib_is_scoped_enum // C++ >= 23
4110 /// True if the type is a scoped enumeration type.
4111 /// @since C++23
4112
4113# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
4114 template<typename _Tp>
4115 struct is_scoped_enum
4116 : bool_constant<__is_scoped_enum(_Tp)>
4117 { };
4118# else
4119 template<typename _Tp>
4120 struct is_scoped_enum
4121 : false_type
4122 { };
4123
4124 template<typename _Tp>
4125 requires __is_enum(_Tp)
4126 && requires(remove_cv_t<_Tp> __t) { __t = __t; } // fails if incomplete
4127 struct is_scoped_enum<_Tp>
4128 : bool_constant<!requires(_Tp __t, void(*__f)(int)) { __f(__t); }>
4129 { };
4130# endif
4131
4132 /// @ingroup variable_templates
4133 /// @since C++23
4134# if _GLIBCXX_USE_BUILTIN_TRAIT(__is_scoped_enum)
4135 template<typename _Tp>
4136 inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp);
4137# else
4138 template<typename _Tp>
4139 inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value;
4140# endif
4141#endif
4142
4143#ifdef __cpp_lib_is_implicit_lifetime // C++ >= 23
4144 /// True if the type is an implicit-lifetime type.
4145 /// @since C++23
4146
4147 template<typename _Tp>
4148 struct is_implicit_lifetime
4149 : bool_constant<__builtin_is_implicit_lifetime(_Tp)>
4150 { };
4151
4152 /// @ingroup variable_templates
4153 /// @since C++23
4154 template<typename _Tp>
4155 inline constexpr bool is_implicit_lifetime_v
4156 = __builtin_is_implicit_lifetime(_Tp);
4157#endif
4158
4159#ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp
4160 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
4161 /// direct-initialization, and a temporary object would be bound to
4162 /// the reference, false otherwise.
4163 /// @since C++23
4164 template<typename _Tp, typename _Up>
4165 struct reference_constructs_from_temporary
4166 : public bool_constant<__reference_constructs_from_temporary(_Tp, _Up)>
4167 {
4168 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
4169 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
4170 "template argument must be a complete class or an unbounded array");
4171 };
4172
4173 /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
4174 /// copy-initialization, and a temporary object would be bound to
4175 /// the reference, false otherwise.
4176 /// @since C++23
4177 template<typename _Tp, typename _Up>
4178 struct reference_converts_from_temporary
4179 : public bool_constant<__reference_converts_from_temporary(_Tp, _Up)>
4180 {
4181 static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{})
4182 && std::__is_complete_or_unbounded(__type_identity<_Up>{}),
4183 "template argument must be a complete class or an unbounded array");
4184 };
4185
4186 /// @ingroup variable_templates
4187 /// @since C++23
4188 template<typename _Tp, typename _Up>
4189 inline constexpr bool reference_constructs_from_temporary_v
4190 = reference_constructs_from_temporary<_Tp, _Up>::value;
4191
4192 /// @ingroup variable_templates
4193 /// @since C++23
4194 template<typename _Tp, typename _Up>
4195 inline constexpr bool reference_converts_from_temporary_v
4196 = reference_converts_from_temporary<_Tp, _Up>::value;
4197#endif // __cpp_lib_reference_from_temporary
4198
4199#ifdef __cpp_lib_is_constant_evaluated // C++ >= 20 && HAVE_IS_CONST_EVAL
4200 /// Returns true only when called during constant evaluation.
4201 /// @since C++20
4202 [[__gnu__::__always_inline__]]
4203 constexpr bool
4204 is_constant_evaluated() noexcept
4205 {
4206#if __cpp_if_consteval >= 202106L
4207 if consteval { return true; } else { return false; }
4208#else
4209 return __builtin_is_constant_evaluated();
4210#endif
4211 }
4212#endif
4213
4214#if __cplusplus >= 202002L
4215 /// @cond undocumented
4216 template<typename _From, typename _To>
4217 using __copy_cv = typename __match_cv_qualifiers<_From, _To>::__type;
4218
4219 template<typename _Xp, typename _Yp>
4220 using __cond_res
4221 = decltype(false ? declval<_Xp(&)()>()() : declval<_Yp(&)()>()());
4222
4223 template<typename _Ap, typename _Bp, typename = void>
4224 struct __common_ref_impl
4225 { };
4226
4227 // [meta.trans.other], COMMON-REF(A, B)
4228 template<typename _Ap, typename _Bp>
4229 using __common_ref = typename __common_ref_impl<_Ap, _Bp>::type;
4230
4231 // COND-RES(COPYCV(X, Y) &, COPYCV(Y, X) &)
4232 template<typename _Xp, typename _Yp>
4233 using __condres_cvref
4234 = __cond_res<__copy_cv<_Xp, _Yp>&, __copy_cv<_Yp, _Xp>&>;
4235
4236 // If A and B are both lvalue reference types, ...
4237 template<typename _Xp, typename _Yp>
4238 struct __common_ref_impl<_Xp&, _Yp&, __void_t<__condres_cvref<_Xp, _Yp>>>
4240 __condres_cvref<_Xp, _Yp>>
4241 { };
4242
4243 // let C be remove_reference_t<COMMON-REF(X&, Y&)>&&
4244 template<typename _Xp, typename _Yp>
4245 using __common_ref_C = remove_reference_t<__common_ref<_Xp&, _Yp&>>&&;
4246
4247 // If A and B are both rvalue reference types, ...
4248 template<typename _Xp, typename _Yp>
4249 struct __common_ref_impl<_Xp&&, _Yp&&,
4250 _Require<is_convertible<_Xp&&, __common_ref_C<_Xp, _Yp>>,
4251 is_convertible<_Yp&&, __common_ref_C<_Xp, _Yp>>>>
4252 { using type = __common_ref_C<_Xp, _Yp>; };
4253
4254 // let D be COMMON-REF(const X&, Y&)
4255 template<typename _Xp, typename _Yp>
4256 using __common_ref_D = __common_ref<const _Xp&, _Yp&>;
4257
4258 // If A is an rvalue reference and B is an lvalue reference, ...
4259 template<typename _Xp, typename _Yp>
4260 struct __common_ref_impl<_Xp&&, _Yp&,
4261 _Require<is_convertible<_Xp&&, __common_ref_D<_Xp, _Yp>>>>
4262 { using type = __common_ref_D<_Xp, _Yp>; };
4263
4264 // If A is an lvalue reference and B is an rvalue reference, ...
4265 template<typename _Xp, typename _Yp>
4266 struct __common_ref_impl<_Xp&, _Yp&&>
4267 : __common_ref_impl<_Yp&&, _Xp&>
4268 { };
4269 /// @endcond
4270
4271 template<typename _Tp, typename _Up,
4272 template<typename> class _TQual, template<typename> class _UQual>
4273 struct basic_common_reference
4274 { };
4275
4276 /// @cond undocumented
4277 template<typename _Tp>
4278 struct __xref
4279 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>; };
4280
4281 template<typename _Tp>
4282 struct __xref<_Tp&>
4283 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&; };
4284
4285 template<typename _Tp>
4286 struct __xref<_Tp&&>
4287 { template<typename _Up> using __type = __copy_cv<_Tp, _Up>&&; };
4288
4289 template<typename _Tp1, typename _Tp2>
4290 using __basic_common_ref
4291 = typename basic_common_reference<remove_cvref_t<_Tp1>,
4292 remove_cvref_t<_Tp2>,
4293 __xref<_Tp1>::template __type,
4294 __xref<_Tp2>::template __type>::type;
4295 /// @endcond
4296
4297 template<typename... _Tp>
4298 struct common_reference;
4300 template<typename... _Tp>
4301 using common_reference_t = typename common_reference<_Tp...>::type;
4302
4303 // If sizeof...(T) is zero, there shall be no member type.
4304 template<>
4305 struct common_reference<>
4306 { };
4307
4308 // If sizeof...(T) is one ...
4309 template<typename _Tp0>
4310 struct common_reference<_Tp0>
4311 { using type = _Tp0; };
4312
4313 /// @cond undocumented
4314 template<typename _Tp1, typename _Tp2, int _Bullet = 1>
4315 struct __common_reference_impl
4316 : __common_reference_impl<_Tp1, _Tp2, _Bullet + 1>
4317 { };
4318
4319 // If sizeof...(T) is two ...
4320 template<typename _Tp1, typename _Tp2>
4321 struct common_reference<_Tp1, _Tp2>
4322 : __common_reference_impl<_Tp1, _Tp2>
4323 { };
4324
4325 // If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, ...
4326 template<typename _Tp1, typename _Tp2>
4327 requires is_reference_v<_Tp1> && is_reference_v<_Tp2>
4328 && requires { typename __common_ref<_Tp1, _Tp2>; }
4329#if __cpp_lib_common_reference // C++ >= 20
4330 && is_convertible_v<add_pointer_t<_Tp1>,
4332 && is_convertible_v<add_pointer_t<_Tp2>,
4334#endif
4335 struct __common_reference_impl<_Tp1, _Tp2, 1>
4336 { using type = __common_ref<_Tp1, _Tp2>; };
4337
4338 // Otherwise, if basic_common_reference<...>::type is well-formed, ...
4339 template<typename _Tp1, typename _Tp2>
4340 requires requires { typename __basic_common_ref<_Tp1, _Tp2>; }
4341 struct __common_reference_impl<_Tp1, _Tp2, 2>
4342 { using type = __basic_common_ref<_Tp1, _Tp2>; };
4343
4344 // Otherwise, if COND-RES(T1, T2) is well-formed, ...
4345 template<typename _Tp1, typename _Tp2>
4346 requires requires { typename __cond_res<_Tp1, _Tp2>; }
4347 struct __common_reference_impl<_Tp1, _Tp2, 3>
4348 { using type = __cond_res<_Tp1, _Tp2>; };
4349
4350 // Otherwise, if common_type_t<T1, T2> is well-formed, ...
4351 template<typename _Tp1, typename _Tp2>
4352 requires requires { typename common_type_t<_Tp1, _Tp2>; }
4353 struct __common_reference_impl<_Tp1, _Tp2, 4>
4354 { using type = common_type_t<_Tp1, _Tp2>; };
4355
4356 // Otherwise, there shall be no member type.
4357 template<typename _Tp1, typename _Tp2>
4358 struct __common_reference_impl<_Tp1, _Tp2, 5>
4359 { };
4360
4361 // Otherwise, if sizeof...(T) is greater than two, ...
4362 template<typename _Tp1, typename _Tp2, typename... _Rest>
4363 struct common_reference<_Tp1, _Tp2, _Rest...>
4364 : __common_type_fold<common_reference<_Tp1, _Tp2>,
4365 __common_type_pack<_Rest...>>
4366 { };
4367
4368 // Reuse __common_type_fold for common_reference<T1, T2, Rest...>
4369 template<typename _Tp1, typename _Tp2, typename... _Rest>
4370 struct __common_type_fold<common_reference<_Tp1, _Tp2>,
4371 __common_type_pack<_Rest...>,
4372 void_t<common_reference_t<_Tp1, _Tp2>>>
4373 : public common_reference<common_reference_t<_Tp1, _Tp2>, _Rest...>
4374 { };
4375 /// @endcond
4376
4377#endif // C++20
4378
4379#if __cplusplus >= 201103L
4380 // Stores a tuple of indices. Used by tuple and pair, and by bind() to
4381 // extract the elements in a tuple.
4382 template<size_t... _Indexes> struct _Index_tuple { };
4383
4384 // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
4385 template<size_t _Num>
4386 struct _Build_index_tuple
4387 {
4388#if __has_builtin(__make_integer_seq)
4389 template<typename, size_t... _Indices>
4390 using _IdxTuple = _Index_tuple<_Indices...>;
4391
4392 // Clang defines __make_integer_seq for this purpose.
4393 using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
4394#else
4395 // For GCC and other compilers, use __integer_pack instead.
4396 using __type = _Index_tuple<__integer_pack(_Num)...>;
4397#endif
4398 };
4399#endif // C++11
4400
4401 /// @} group metaprogramming
4402
4403_GLIBCXX_END_NAMESPACE_VERSION
4404} // namespace std
4405} // extern "C++"
4406
4407#endif // C++11
4408
4409#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:4072
typename common_reference< _Tp... >::type common_reference_t
Definition type_traits:4299
typename result_of< _Tp >::type result_of_t
Alias template for result_of.
Definition type_traits:2983
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:2971
typename underlying_type< _Tp >::type underlying_type_t
Alias template for underlying_type.
Definition type_traits:2979
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:2955
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:2975
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:4102
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
Definition type_traits:2967
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:4062
constexpr bool is_pointer_interconvertible_base_of_v
Definition type_traits:4090
typename decay< _Tp >::type decay_t
Alias template for decay.
Definition type_traits:2963
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:4084