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