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