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