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