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