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