From Jason Turner

[type.traits]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpi5mr76ok/{from.md → to.md} +464 -102
tmp/tmpi5mr76ok/{from.md → to.md} RENAMED
@@ -53,11 +53,11 @@ Unless otherwise specified, the behavior of a program that adds
53
  specializations for any of the templates specified in [[type.traits]] is
54
  undefined.
55
 
56
  Unless otherwise specified, an incomplete type may be used to
57
  instantiate a template specified in [[type.traits]]. The behavior of a
58
- program is undefined if:
59
 
60
  - an instantiation of a template specified in [[type.traits]] directly
61
  or indirectly depends on an incompletely-defined object type `T`, and
62
  - that instantiation could yield a different result were `T`
63
  hypothetically completed.
@@ -73,10 +73,26 @@ namespace std {
73
  template<bool B>
74
  using bool_constant = integral_constant<bool, B>;
75
  using true_type = bool_constant<true>;
76
  using false_type = bool_constant<false>;
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  // [meta.unary.cat], primary type categories
79
  template<class T> struct is_void;
80
  template<class T> struct is_null_pointer;
81
  template<class T> struct is_integral;
82
  template<class T> struct is_floating_point;
@@ -88,10 +104,11 @@ namespace std {
88
  template<class T> struct is_member_function_pointer;
89
  template<class T> struct is_enum;
90
  template<class T> struct is_union;
91
  template<class T> struct is_class;
92
  template<class T> struct is_function;
 
93
 
94
  // [meta.unary.comp], composite type categories
95
  template<class T> struct is_reference;
96
  template<class T> struct is_arithmetic;
97
  template<class T> struct is_fundamental;
@@ -101,18 +118,20 @@ namespace std {
101
  template<class T> struct is_member_pointer;
102
 
103
  // [meta.unary.prop], type properties
104
  template<class T> struct is_const;
105
  template<class T> struct is_volatile;
106
- template<class T> struct is_trivial;
107
  template<class T> struct is_trivially_copyable;
 
 
108
  template<class T> struct is_standard_layout;
109
  template<class T> struct is_empty;
110
  template<class T> struct is_polymorphic;
111
  template<class T> struct is_abstract;
112
  template<class T> struct is_final;
113
  template<class T> struct is_aggregate;
 
114
 
115
  template<class T> struct is_signed;
116
  template<class T> struct is_unsigned;
117
  template<class T> struct is_bounded_array;
118
  template<class T> struct is_unbounded_array;
@@ -153,10 +172,11 @@ namespace std {
153
 
154
  template<class T, class U> struct is_nothrow_swappable_with;
155
  template<class T> struct is_nothrow_swappable;
156
 
157
  template<class T> struct is_nothrow_destructible;
 
158
 
159
  template<class T> struct is_implicit_lifetime;
160
 
161
  template<class T> struct has_virtual_destructor;
162
 
@@ -171,10 +191,11 @@ namespace std {
171
  template<class T, unsigned I = 0> struct extent;
172
 
173
  // [meta.rel], type relations
174
  template<class T, class U> struct is_same;
175
  template<class Base, class Derived> struct is_base_of;
 
176
  template<class From, class To> struct is_convertible;
177
  template<class From, class To> struct is_nothrow_convertible;
178
  template<class T, class U> struct is_layout_compatible;
179
  template<class Base, class Derived> struct is_pointer_interconvertible_base_of;
180
 
@@ -182,69 +203,72 @@ namespace std {
182
  template<class R, class Fn, class... ArgTypes> struct is_invocable_r;
183
 
184
  template<class Fn, class... ArgTypes> struct is_nothrow_invocable;
185
  template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
186
 
 
 
 
187
  // [meta.trans.cv], const-volatile modifications
188
  template<class T> struct remove_const;
189
  template<class T> struct remove_volatile;
190
  template<class T> struct remove_cv;
191
  template<class T> struct add_const;
192
  template<class T> struct add_volatile;
193
  template<class T> struct add_cv;
194
 
195
  template<class T>
196
- using remove_const_t = typename remove_const<T>::type;
197
  template<class T>
198
- using remove_volatile_t = typename remove_volatile<T>::type;
199
  template<class T>
200
- using remove_cv_t = typename remove_cv<T>::type;
201
  template<class T>
202
- using add_const_t = typename add_const<T>::type;
203
  template<class T>
204
- using add_volatile_t = typename add_volatile<T>::type;
205
  template<class T>
206
- using add_cv_t = typename add_cv<T>::type;
207
 
208
  // [meta.trans.ref], reference modifications
209
  template<class T> struct remove_reference;
210
  template<class T> struct add_lvalue_reference;
211
  template<class T> struct add_rvalue_reference;
212
 
213
  template<class T>
214
- using remove_reference_t = typename remove_reference<T>::type;
215
  template<class T>
216
- using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
217
  template<class T>
218
- using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
219
 
220
  // [meta.trans.sign], sign modifications
221
  template<class T> struct make_signed;
222
  template<class T> struct make_unsigned;
223
 
224
  template<class T>
225
- using make_signed_t = typename make_signed<T>::type;
226
  template<class T>
227
- using make_unsigned_t = typename make_unsigned<T>::type;
228
 
229
  // [meta.trans.arr], array modifications
230
  template<class T> struct remove_extent;
231
  template<class T> struct remove_all_extents;
232
 
233
  template<class T>
234
- using remove_extent_t = typename remove_extent<T>::type;
235
  template<class T>
236
- using remove_all_extents_t = typename remove_all_extents<T>::type;
237
 
238
  // [meta.trans.ptr], pointer modifications
239
  template<class T> struct remove_pointer;
240
  template<class T> struct add_pointer;
241
 
242
  template<class T>
243
- using remove_pointer_t = typename remove_pointer<T>::type;
244
  template<class T>
245
- using add_pointer_t = typename add_pointer<T>::type;
246
 
247
  // [meta.trans.other], other transformations
248
  template<class T> struct type_identity;
249
  template<class T> struct remove_cvref;
250
  template<class T> struct decay;
@@ -254,35 +278,38 @@ namespace std {
254
  template<class T, class U, template<class> class TQual, template<class> class UQual>
255
  struct basic_common_reference { };
256
  template<class... T> struct common_reference;
257
  template<class T> struct underlying_type;
258
  template<class Fn, class... ArgTypes> struct invoke_result;
 
259
  template<class T> struct unwrap_reference;
260
  template<class T> struct unwrap_ref_decay;
261
 
262
  template<class T>
263
- using type_identity_t = typename type_identity<T>::type;
264
  template<class T>
265
- using remove_cvref_t = typename remove_cvref<T>::type;
266
  template<class T>
267
- using decay_t = typename decay<T>::type;
268
  template<bool B, class T = void>
269
- using enable_if_t = typename enable_if<B, T>::type;
270
  template<bool B, class T, class F>
271
- using conditional_t = typename conditional<B, T, F>::type;
272
  template<class... T>
273
- using common_type_t = typename common_type<T...>::type;
274
  template<class... T>
275
- using common_reference_t = typename common_reference<T...>::type;
276
  template<class T>
277
- using underlying_type_t = typename underlying_type<T>::type;
278
  template<class Fn, class... ArgTypes>
279
- using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
 
 
280
  template<class T>
281
- using unwrap_reference_t = typename unwrap_reference<T>::type;
282
  template<class T>
283
- using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
284
  template<class...>
285
  using void_t = void;
286
 
287
  // [meta.logical], logical operator traits
288
  template<class... B> struct conjunction;
@@ -316,10 +343,12 @@ namespace std {
316
  constexpr bool is_union_v = is_union<T>::value;
317
  template<class T>
318
  constexpr bool is_class_v = is_class<T>::value;
319
  template<class T>
320
  constexpr bool is_function_v = is_function<T>::value;
 
 
321
 
322
  // [meta.unary.comp], composite type categories
323
  template<class T>
324
  constexpr bool is_reference_v = is_reference<T>::value;
325
  template<class T>
@@ -338,14 +367,14 @@ namespace std {
338
  // [meta.unary.prop], type properties
339
  template<class T>
340
  constexpr bool is_const_v = is_const<T>::value;
341
  template<class T>
342
  constexpr bool is_volatile_v = is_volatile<T>::value;
343
- template<class T>
344
- constexpr bool is_trivial_v = is_trivial<T>::value;
345
  template<class T>
346
  constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
 
 
347
  template<class T>
348
  constexpr bool is_standard_layout_v = is_standard_layout<T>::value;
349
  template<class T>
350
  constexpr bool is_empty_v = is_empty<T>::value;
351
  template<class T>
@@ -354,10 +383,12 @@ namespace std {
354
  constexpr bool is_abstract_v = is_abstract<T>::value;
355
  template<class T>
356
  constexpr bool is_final_v = is_final<T>::value;
357
  template<class T>
358
  constexpr bool is_aggregate_v = is_aggregate<T>::value;
 
 
359
  template<class T>
360
  constexpr bool is_signed_v = is_signed<T>::value;
361
  template<class T>
362
  constexpr bool is_unsigned_v = is_unsigned<T>::value;
363
  template<class T>
@@ -385,43 +416,35 @@ namespace std {
385
  template<class T>
386
  constexpr bool is_swappable_v = is_swappable<T>::value;
387
  template<class T>
388
  constexpr bool is_destructible_v = is_destructible<T>::value;
389
  template<class T, class... Args>
390
- constexpr bool is_trivially_constructible_v
391
- = is_trivially_constructible<T, Args...>::value;
392
  template<class T>
393
  constexpr bool is_trivially_default_constructible_v
394
  = is_trivially_default_constructible<T>::value;
395
  template<class T>
396
- constexpr bool is_trivially_copy_constructible_v
397
- = is_trivially_copy_constructible<T>::value;
398
  template<class T>
399
- constexpr bool is_trivially_move_constructible_v
400
- = is_trivially_move_constructible<T>::value;
401
  template<class T, class U>
402
  constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
403
  template<class T>
404
- constexpr bool is_trivially_copy_assignable_v
405
- = is_trivially_copy_assignable<T>::value;
406
  template<class T>
407
- constexpr bool is_trivially_move_assignable_v
408
- = is_trivially_move_assignable<T>::value;
409
  template<class T>
410
  constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
411
  template<class T, class... Args>
412
- constexpr bool is_nothrow_constructible_v
413
- = is_nothrow_constructible<T, Args...>::value;
414
  template<class T>
415
  constexpr bool is_nothrow_default_constructible_v
416
  = is_nothrow_default_constructible<T>::value;
417
  template<class T>
418
- constexpr bool is_nothrow_copy_constructible_v
419
- = is_nothrow_copy_constructible<T>::value;
420
  template<class T>
421
- constexpr bool is_nothrow_move_constructible_v
422
- = is_nothrow_move_constructible<T>::value;
423
  template<class T, class U>
424
  constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
425
  template<class T>
426
  constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value;
427
  template<class T>
@@ -430,12 +453,16 @@ namespace std {
430
  constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value;
431
  template<class T>
432
  constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value;
433
  template<class T>
434
  constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value;
 
 
435
  template<class T>
436
  constexpr bool is_implicit_lifetime_v = is_implicit_lifetime<T>::value;
 
 
437
  template<class T>
438
  constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
439
  template<class T>
440
  constexpr bool has_unique_object_representations_v
441
  = has_unique_object_representations<T>::value;
@@ -457,10 +484,12 @@ namespace std {
457
  // [meta.rel], type relations
458
  template<class T, class U>
459
  constexpr bool is_same_v = is_same<T, U>::value;
460
  template<class Base, class Derived>
461
  constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
 
 
462
  template<class From, class To>
463
  constexpr bool is_convertible_v = is_convertible<From, To>::value;
464
  template<class From, class To>
465
  constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
466
  template<class T, class U>
@@ -473,12 +502,15 @@ namespace std {
473
  template<class R, class Fn, class... ArgTypes>
474
  constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value;
475
  template<class Fn, class... ArgTypes>
476
  constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value;
477
  template<class R, class Fn, class... ArgTypes>
478
- constexpr bool is_nothrow_invocable_r_v
479
- = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
 
 
 
480
 
481
  // [meta.logical], logical operator traits
482
  template<class... B>
483
  constexpr bool conjunction_v = conjunction<B...>::value;
484
  template<class... B>
@@ -492,10 +524,11 @@ namespace std {
492
  template<class S1, class S2, class M1, class M2>
493
  constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
494
 
495
  // [meta.const.eval], constant evaluation context
496
  constexpr bool is_constant_evaluated() noexcept;
 
497
  }
498
  ```
499
 
500
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
501
 
@@ -515,10 +548,268 @@ namespace std {
515
 
516
  The class template `integral_constant`, alias template `bool_constant`,
517
  and its associated *typedef-name*s `true_type` and `false_type` are used
518
  as base classes to define the interface for various type traits.
519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
521
 
522
  #### General <a id="meta.unary.general">[[meta.unary.general]]</a>
523
 
524
  Subclause [[meta.unary]] contains templates that may be used to query
@@ -528,32 +819,33 @@ Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
528
  with a base characteristic of `true_type` if the corresponding condition
529
  is `true`, otherwise `false_type`.
530
 
531
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
532
 
533
- The primary type categories correspond to the descriptions given in
534
- subclause  [[basic.types]] of the C++ standard.
 
535
 
536
  For any given type `T`, the result of applying one of these templates to
537
  `T` and to cv `T` shall yield the same result.
538
 
539
  [*Note 1*: For any given type `T`, exactly one of the primary type
540
  categories has a `value` member that evaluates to `true`. — *end note*]
541
 
542
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
543
 
544
- These templates provide convenient compositions of the primary type
545
- categories, corresponding to the descriptions given in subclause 
546
- [[basic.types]].
547
 
548
  For any given type `T`, the result of applying one of these templates to
549
  `T` and to cv `T` shall yield the same result.
550
 
551
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
552
 
553
- These templates provide access to some of the more important properties
554
- of types.
555
 
556
  It is unspecified whether the library defines any full or partial
557
  specializations of any of these templates.
558
 
559
  For all of the class templates `X` declared in this subclause,
@@ -639,71 +931,80 @@ effects such as the instantiation of class template specializations and
639
  function template specializations, the generation of implicitly-defined
640
  functions, and so on. Such side effects are not in the “immediate
641
  context” and can result in the program being ill-formed. — *end note*]
642
 
643
  The predicate condition for a template specialization
644
- `has_unique_object_representations<T>` shall be satisfied if and only
645
- if:
646
 
647
  - `T` is trivially copyable, and
648
  - any two objects of type `T` with the same value have the same object
649
- representation, where two objects of array or non-union class type are
650
- considered to have the same value if their respective sequences of
651
- direct subobjects have the same values, and two objects of union type
652
- are considered to have the same value if they have the same active
653
- member and the corresponding members have the same value.
 
 
654
 
655
  The set of scalar types for which this condition holds is
656
  *implementation-defined*.
657
 
658
  [*Note 4*: If a type has padding bits, the condition does not hold;
659
  otherwise, the condition holds true for integral types. — *end note*]
660
 
661
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
662
 
663
- This subclause contains templates that may be used to query properties
664
- of types at compile time.
665
 
666
  Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
667
  with a base characteristic of `integral_constant<size_t, Value>`.
668
 
669
  [*Example 1*:
670
 
671
  ``` cpp
672
  // the following assertions hold:
673
- assert(rank_v<int> == 0);
674
- assert(rank_v<int[2]> == 1);
675
- assert(rank_v<int[][4]> == 2);
676
  ```
677
 
678
  — *end example*]
679
 
680
  [*Example 2*:
681
 
682
  ``` cpp
683
  // the following assertions hold:
684
- assert(extent_v<int> == 0);
685
- assert(extent_v<int[2]> == 2);
686
- assert(extent_v<int[2][4]> == 2);
687
- assert(extent_v<int[][4]> == 0);
688
- assert((extent_v<int, 1>) == 0);
689
- assert((extent_v<int[2], 1>) == 0);
690
- assert((extent_v<int[2][4], 1>) == 4);
691
- assert((extent_v<int[][4], 1>) == 4);
692
  ```
693
 
694
  — *end example*]
695
 
696
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
697
 
698
- This subclause contains templates that may be used to query
699
  relationships between types at compile time.
700
 
701
  Each of these templates shall be a *Cpp17BinaryTypeTrait* [[meta.rqmts]]
702
  with a base characteristic of `true_type` if the corresponding condition
703
  is true, otherwise `false_type`.
704
 
 
 
 
 
 
 
 
 
705
  For the purpose of defining the templates in this subclause, a function
706
  call expression `declval<T>()` for any type `T` is considered to be a
707
  trivial [[term.trivial.type]], [[special]] function call that is not an
708
  odr-use [[term.odr.use]] of `declval` in the context of the
709
  corresponding definition notwithstanding the restrictions of 
@@ -738,19 +1039,19 @@ implicit conversions to the return type of the function:
738
  To test() {
739
  return declval<From>();
740
  }
741
  ```
742
 
743
- [*Note 1*: This requirement gives well-defined results for reference
744
  types, array types, function types, and cv `void`. — *end note*]
745
 
746
  Access checking is performed in a context unrelated to `To` and `From`.
747
  Only the validity of the immediate context of the *expression* of the
748
  `return` statement [[stmt.return]] (including initialization of the
749
  returned object or reference) is considered.
750
 
751
- [*Note 2*: The initialization can result in side effects such as the
752
  instantiation of class template specializations and function template
753
  specializations, the generation of implicitly-defined functions, and so
754
  on. Such side effects are not in the “immediate context” and can result
755
  in the program being ill-formed. — *end note*]
756
 
@@ -764,44 +1065,59 @@ transform one type to another following some predefined rule.
764
  Each of the templates in [[meta.trans]] shall be a
765
  *Cpp17TransformationTrait* [[meta.rqmts]].
766
 
767
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
768
 
 
 
 
769
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
770
 
 
 
771
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
772
 
 
 
 
773
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
774
 
 
 
775
  [*Example 1*:
776
 
777
  ``` cpp
778
  // the following assertions hold:
779
- assert((is_same_v<remove_extent_t<int>, int>));
780
- assert((is_same_v<remove_extent_t<int[2]>, int>));
781
- assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
782
- assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
783
  ```
784
 
785
  — *end example*]
786
 
787
  [*Example 2*:
788
 
789
  ``` cpp
790
  // the following assertions hold:
791
- assert((is_same_v<remove_all_extents_t<int>, int>));
792
- assert((is_same_v<remove_all_extents_t<int[2]>, int>));
793
- assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
794
- assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
795
  ```
796
 
797
  — *end example*]
798
 
799
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
800
 
 
 
801
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
802
 
 
 
 
803
  [*Note 1*: The compilation of the expression can result in side effects
804
  such as the instantiation of class template specializations and function
805
  template specializations, the generation of implicitly-defined
806
  functions, and so on. Such side effects are not in the “immediate
807
  context” and can result in the program being ill-formed. — *end note*]
@@ -842,13 +1158,13 @@ Given types `A` and `B`, let `X` be `remove_reference_t<A>`, let `Y` be
842
  - Otherwise, `COMMON-REF(A, B)` is ill-formed.
843
 
844
  If any of the types computed above is ill-formed, then
845
  `COMMON-REF(A, B)` is ill-formed.
846
 
847
- Note A: For the `common_type` trait applied to a template parameter pack
848
- `T` of types, the member `type` shall be either defined or not present
849
- as follows:
850
 
851
  - If `sizeof...(T)` is zero, there shall be no member `type`.
852
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
853
  the pack `T`. The member *typedef-name* `type` shall denote the same
854
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
@@ -879,15 +1195,14 @@ as follows:
879
  constituting `T`. Let `C` denote the same type, if any, as
880
  `common_type_t<T1, T2>`. If there is such a type `C`, the member
881
  *typedef-name* `type` shall denote the same type, if any, as
882
  `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
883
 
884
- Note B: Notwithstanding the provisions of [[meta.type.synop]], and
885
- pursuant to [[namespace.std]], a program may specialize
886
- `common_type<T1, T2>` for types `T1` and `T2` such that
887
- `is_same_v<T1, decay_t<T1>>` and `is_same_v<T2, decay_t<T2>>` are each
888
- `true`.
889
 
890
  [*Note 3*: Such specializations are needed when only explicit
891
  conversions are desired between the template arguments. — *end note*]
892
 
893
  Such a specialization need not have a member named `type`, but if it
@@ -895,12 +1210,12 @@ does, the *qualified-id* `common_type<T1, T2>::type` shall denote a
895
  cv-unqualified non-reference type to which each of the types `T1` and
896
  `T2` is explicitly convertible. Moreover, `common_type_t<T1, T2>` shall
897
  denote the same type, if any, as does `common_type_t<T2, T1>`. No
898
  diagnostic is required for a violation of this Note’s rules.
899
 
900
- Note C: For the `common_reference` trait applied to a parameter pack `T`
901
- of types, the member `type` shall be either defined or not present as
902
  follows:
903
 
904
  - If `sizeof...(T)` is zero, there shall be no member `type`.
905
  - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
906
  the pack `T`. The member typedef `type` shall denote the same type as
@@ -926,12 +1241,12 @@ follows:
926
  `common_reference_t<T1, T2>`. Then:
927
  - If there is such a type `C`, the member typedef `type` shall denote
928
  the same type, if any, as `common_reference_t<C, Rest...>`.
929
  - Otherwise, there shall be no member `type`.
930
 
931
- Note D: Notwithstanding the provisions of [[meta.type.synop]], and
932
- pursuant to [[namespace.std]], a program may partially specialize
933
  `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
934
  that `is_same_v<T, decay_t<T>>` and `is_same_v<U, decay_t<U>>` are each
935
  `true`.
936
 
937
  [*Note 4*: Such specializations can be used to influence the result of
@@ -1101,19 +1416,19 @@ struct B { int b; }; // a standard-layout class
1101
  struct C: public A, public B { }; // not a standard-layout class
1102
 
1103
  static_assert( is_pointer_interconvertible_with_class( &C::b ) );
1104
  // Succeeds because, despite its appearance, &C::b has type
1105
  // ``pointer to member of B of type int''.
1106
- static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) );
1107
- // Forces the use of class C, and fails.
1108
 
1109
  static_assert( is_corresponding_member( &C::a, &C::b ) );
1110
  // Succeeds because, despite its appearance, &C::a and &C::b have types
1111
  // ``pointer to member of A of type int'' and
1112
  // ``pointer to member of B of type int'', respectively.
1113
- static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) );
1114
- // Forces the use of class C, and fails.
1115
  ```
1116
 
1117
  — *end example*]
1118
 
1119
  — *end note*]
@@ -1146,5 +1461,52 @@ constexpr void f(unsigned char *p, int n) {
1146
  }
1147
  ```
1148
 
1149
  — *end example*]
1150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  specializations for any of the templates specified in [[type.traits]] is
54
  undefined.
55
 
56
  Unless otherwise specified, an incomplete type may be used to
57
  instantiate a template specified in [[type.traits]]. The behavior of a
58
+ program is undefined if
59
 
60
  - an instantiation of a template specified in [[type.traits]] directly
61
  or indirectly depends on an incompletely-defined object type `T`, and
62
  - that instantiation could yield a different result were `T`
63
  hypothetically completed.
 
73
  template<bool B>
74
  using bool_constant = integral_constant<bool, B>;
75
  using true_type = bool_constant<true>;
76
  using false_type = bool_constant<false>;
77
 
78
+ // [const.wrap.class], class template constant_wrapper
79
+ template<class T>
80
+ struct cw-fixed-value; // exposition only
81
+
82
+ template<cw-fixed-value X, class = typename decltype(X)::type>
83
+ struct constant_wrapper;
84
+
85
+ template<class T>
86
+ concept constexpr-param = // exposition only
87
+ requires { typename constant_wrapper<T::value>; };
88
+
89
+ struct cw-operators; // exposition only
90
+
91
+ template<cw-fixed-value X>
92
+ constexpr auto cw = constant_wrapper<X>{};
93
+
94
  // [meta.unary.cat], primary type categories
95
  template<class T> struct is_void;
96
  template<class T> struct is_null_pointer;
97
  template<class T> struct is_integral;
98
  template<class T> struct is_floating_point;
 
104
  template<class T> struct is_member_function_pointer;
105
  template<class T> struct is_enum;
106
  template<class T> struct is_union;
107
  template<class T> struct is_class;
108
  template<class T> struct is_function;
109
+ template<class T> struct is_reflection;
110
 
111
  // [meta.unary.comp], composite type categories
112
  template<class T> struct is_reference;
113
  template<class T> struct is_arithmetic;
114
  template<class T> struct is_fundamental;
 
118
  template<class T> struct is_member_pointer;
119
 
120
  // [meta.unary.prop], type properties
121
  template<class T> struct is_const;
122
  template<class T> struct is_volatile;
 
123
  template<class T> struct is_trivially_copyable;
124
+ template<class T> struct is_trivially_relocatable;
125
+ template<class T> struct is_replaceable;
126
  template<class T> struct is_standard_layout;
127
  template<class T> struct is_empty;
128
  template<class T> struct is_polymorphic;
129
  template<class T> struct is_abstract;
130
  template<class T> struct is_final;
131
  template<class T> struct is_aggregate;
132
+ template<class T> struct is_consteval_only;
133
 
134
  template<class T> struct is_signed;
135
  template<class T> struct is_unsigned;
136
  template<class T> struct is_bounded_array;
137
  template<class T> struct is_unbounded_array;
 
172
 
173
  template<class T, class U> struct is_nothrow_swappable_with;
174
  template<class T> struct is_nothrow_swappable;
175
 
176
  template<class T> struct is_nothrow_destructible;
177
+ template<class T> struct is_nothrow_relocatable;
178
 
179
  template<class T> struct is_implicit_lifetime;
180
 
181
  template<class T> struct has_virtual_destructor;
182
 
 
191
  template<class T, unsigned I = 0> struct extent;
192
 
193
  // [meta.rel], type relations
194
  template<class T, class U> struct is_same;
195
  template<class Base, class Derived> struct is_base_of;
196
+ template<class Base, class Derived> struct is_virtual_base_of;
197
  template<class From, class To> struct is_convertible;
198
  template<class From, class To> struct is_nothrow_convertible;
199
  template<class T, class U> struct is_layout_compatible;
200
  template<class Base, class Derived> struct is_pointer_interconvertible_base_of;
201
 
 
203
  template<class R, class Fn, class... ArgTypes> struct is_invocable_r;
204
 
205
  template<class Fn, class... ArgTypes> struct is_nothrow_invocable;
206
  template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
207
 
208
+ template<class Fn, class Tuple> struct is_applicable;
209
+ template<class Fn, class Tuple> struct is_nothrow_applicable;
210
+
211
  // [meta.trans.cv], const-volatile modifications
212
  template<class T> struct remove_const;
213
  template<class T> struct remove_volatile;
214
  template<class T> struct remove_cv;
215
  template<class T> struct add_const;
216
  template<class T> struct add_volatile;
217
  template<class T> struct add_cv;
218
 
219
  template<class T>
220
+ using remove_const_t = remove_const<T>::type;
221
  template<class T>
222
+ using remove_volatile_t = remove_volatile<T>::type;
223
  template<class T>
224
+ using remove_cv_t = remove_cv<T>::type;
225
  template<class T>
226
+ using add_const_t = add_const<T>::type;
227
  template<class T>
228
+ using add_volatile_t = add_volatile<T>::type;
229
  template<class T>
230
+ using add_cv_t = add_cv<T>::type;
231
 
232
  // [meta.trans.ref], reference modifications
233
  template<class T> struct remove_reference;
234
  template<class T> struct add_lvalue_reference;
235
  template<class T> struct add_rvalue_reference;
236
 
237
  template<class T>
238
+ using remove_reference_t = remove_reference<T>::type;
239
  template<class T>
240
+ using add_lvalue_reference_t = add_lvalue_reference<T>::type;
241
  template<class T>
242
+ using add_rvalue_reference_t = add_rvalue_reference<T>::type;
243
 
244
  // [meta.trans.sign], sign modifications
245
  template<class T> struct make_signed;
246
  template<class T> struct make_unsigned;
247
 
248
  template<class T>
249
+ using make_signed_t = make_signed<T>::type;
250
  template<class T>
251
+ using make_unsigned_t = make_unsigned<T>::type;
252
 
253
  // [meta.trans.arr], array modifications
254
  template<class T> struct remove_extent;
255
  template<class T> struct remove_all_extents;
256
 
257
  template<class T>
258
+ using remove_extent_t = remove_extent<T>::type;
259
  template<class T>
260
+ using remove_all_extents_t = remove_all_extents<T>::type;
261
 
262
  // [meta.trans.ptr], pointer modifications
263
  template<class T> struct remove_pointer;
264
  template<class T> struct add_pointer;
265
 
266
  template<class T>
267
+ using remove_pointer_t = remove_pointer<T>::type;
268
  template<class T>
269
+ using add_pointer_t = add_pointer<T>::type;
270
 
271
  // [meta.trans.other], other transformations
272
  template<class T> struct type_identity;
273
  template<class T> struct remove_cvref;
274
  template<class T> struct decay;
 
278
  template<class T, class U, template<class> class TQual, template<class> class UQual>
279
  struct basic_common_reference { };
280
  template<class... T> struct common_reference;
281
  template<class T> struct underlying_type;
282
  template<class Fn, class... ArgTypes> struct invoke_result;
283
+ template<class Fn, class Tuple> struct apply_result;
284
  template<class T> struct unwrap_reference;
285
  template<class T> struct unwrap_ref_decay;
286
 
287
  template<class T>
288
+ using type_identity_t = type_identity<T>::type;
289
  template<class T>
290
+ using remove_cvref_t = remove_cvref<T>::type;
291
  template<class T>
292
+ using decay_t = decay<T>::type;
293
  template<bool B, class T = void>
294
+ using enable_if_t = enable_if<B, T>::type;
295
  template<bool B, class T, class F>
296
+ using conditional_t = conditional<B, T, F>::type;
297
  template<class... T>
298
+ using common_type_t = common_type<T...>::type;
299
  template<class... T>
300
+ using common_reference_t = common_reference<T...>::type;
301
  template<class T>
302
+ using underlying_type_t = underlying_type<T>::type;
303
  template<class Fn, class... ArgTypes>
304
+ using invoke_result_t = invoke_result<Fn, ArgTypes...>::type;
305
+ template<class Fn, class Tuple>
306
+ using apply_result_t = apply_result<Fn, Tuple>::type;
307
  template<class T>
308
+ using unwrap_reference_t = unwrap_reference<T>::type;
309
  template<class T>
310
+ using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;
311
  template<class...>
312
  using void_t = void;
313
 
314
  // [meta.logical], logical operator traits
315
  template<class... B> struct conjunction;
 
343
  constexpr bool is_union_v = is_union<T>::value;
344
  template<class T>
345
  constexpr bool is_class_v = is_class<T>::value;
346
  template<class T>
347
  constexpr bool is_function_v = is_function<T>::value;
348
+ template<class T>
349
+ constexpr bool is_reflection_v = is_reflection<T>::value;
350
 
351
  // [meta.unary.comp], composite type categories
352
  template<class T>
353
  constexpr bool is_reference_v = is_reference<T>::value;
354
  template<class T>
 
367
  // [meta.unary.prop], type properties
368
  template<class T>
369
  constexpr bool is_const_v = is_const<T>::value;
370
  template<class T>
371
  constexpr bool is_volatile_v = is_volatile<T>::value;
 
 
372
  template<class T>
373
  constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
374
+ template<class T>
375
+ constexpr bool is_trivially_relocatable_v = is_trivially_relocatable<T>::value;
376
  template<class T>
377
  constexpr bool is_standard_layout_v = is_standard_layout<T>::value;
378
  template<class T>
379
  constexpr bool is_empty_v = is_empty<T>::value;
380
  template<class T>
 
383
  constexpr bool is_abstract_v = is_abstract<T>::value;
384
  template<class T>
385
  constexpr bool is_final_v = is_final<T>::value;
386
  template<class T>
387
  constexpr bool is_aggregate_v = is_aggregate<T>::value;
388
+ template<class T>
389
+ constexpr bool is_consteval_only_v = is_consteval_only<T>::value;
390
  template<class T>
391
  constexpr bool is_signed_v = is_signed<T>::value;
392
  template<class T>
393
  constexpr bool is_unsigned_v = is_unsigned<T>::value;
394
  template<class T>
 
416
  template<class T>
417
  constexpr bool is_swappable_v = is_swappable<T>::value;
418
  template<class T>
419
  constexpr bool is_destructible_v = is_destructible<T>::value;
420
  template<class T, class... Args>
421
+ constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value;
 
422
  template<class T>
423
  constexpr bool is_trivially_default_constructible_v
424
  = is_trivially_default_constructible<T>::value;
425
  template<class T>
426
+ constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value;
 
427
  template<class T>
428
+ constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value;
 
429
  template<class T, class U>
430
  constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
431
  template<class T>
432
+ constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<T>::value;
 
433
  template<class T>
434
+ constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<T>::value;
 
435
  template<class T>
436
  constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
437
  template<class T, class... Args>
438
+ constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value;
 
439
  template<class T>
440
  constexpr bool is_nothrow_default_constructible_v
441
  = is_nothrow_default_constructible<T>::value;
442
  template<class T>
443
+ constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value;
 
444
  template<class T>
445
+ constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value;
 
446
  template<class T, class U>
447
  constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
448
  template<class T>
449
  constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value;
450
  template<class T>
 
453
  constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value;
454
  template<class T>
455
  constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value;
456
  template<class T>
457
  constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value;
458
+ template<class T>
459
+ constexpr bool is_nothrow_relocatable_v = is_nothrow_relocatable<T>::value;
460
  template<class T>
461
  constexpr bool is_implicit_lifetime_v = is_implicit_lifetime<T>::value;
462
+ template<class T>
463
+ constexpr bool is_replaceable_v = is_replaceable<T>::value;
464
  template<class T>
465
  constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
466
  template<class T>
467
  constexpr bool has_unique_object_representations_v
468
  = has_unique_object_representations<T>::value;
 
484
  // [meta.rel], type relations
485
  template<class T, class U>
486
  constexpr bool is_same_v = is_same<T, U>::value;
487
  template<class Base, class Derived>
488
  constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
489
+ template<class Base, class Derived>
490
+ constexpr bool is_virtual_base_of_v = is_virtual_base_of<Base, Derived>::value;
491
  template<class From, class To>
492
  constexpr bool is_convertible_v = is_convertible<From, To>::value;
493
  template<class From, class To>
494
  constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
495
  template<class T, class U>
 
502
  template<class R, class Fn, class... ArgTypes>
503
  constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value;
504
  template<class Fn, class... ArgTypes>
505
  constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value;
506
  template<class R, class Fn, class... ArgTypes>
507
+ constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
508
+ template<class Fn, class Tuple>
509
+ constexpr bool is_applicable_v = is_applicable<Fn, Tuple>::value;
510
+ template<class Fn, class Tuple>
511
+ constexpr bool is_nothrow_applicable_v = is_nothrow_applicable<Fn, Tuple>::value;
512
 
513
  // [meta.logical], logical operator traits
514
  template<class... B>
515
  constexpr bool conjunction_v = conjunction<B...>::value;
516
  template<class... B>
 
524
  template<class S1, class S2, class M1, class M2>
525
  constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
526
 
527
  // [meta.const.eval], constant evaluation context
528
  constexpr bool is_constant_evaluated() noexcept;
529
+ consteval bool is_within_lifetime(const auto*) noexcept;
530
  }
531
  ```
532
 
533
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
534
 
 
548
 
549
  The class template `integral_constant`, alias template `bool_constant`,
550
  and its associated *typedef-name*s `true_type` and `false_type` are used
551
  as base classes to define the interface for various type traits.
552
 
553
+ ### Class template `constant_wrapper` <a id="const.wrap.class">[[const.wrap.class]]</a>
554
+
555
+ ``` cpp
556
+ namespace std {
557
+ template<class T>
558
+ struct cw-fixed-value { // exposition only
559
+ using type = T; // exposition only
560
+ constexpr cw-fixed-value(type v) noexcept : data(v) {}
561
+ T data; // exposition only
562
+ };
563
+
564
+ template<class T, size_t Extent>
565
+ struct cw-fixed-value<T[Extent]> { // exposition only
566
+ using type = T[Extent]; // exposition only
567
+ constexpr cw-fixed-value(T (&arr)[Extent]) noexcept;
568
+ T data[Extent]; // exposition only
569
+ };
570
+
571
+ template<class T, size_t Extent>
572
+ cw-fixed-value(T (&)[Extent]) -> cw-fixed-value<T[Extent]>; // exposition only
573
+
574
+ struct cw-operators { // exposition only
575
+ // unary operators
576
+ template<constexpr-param T>
577
+ friend constexpr auto operator+(T) noexcept -> constant_wrapper<(+T::value)>
578
+ { return {}; }
579
+ template<constexpr-param T>
580
+ friend constexpr auto operator-(T) noexcept -> constant_wrapper<(-T::value)>
581
+ { return {}; }
582
+ template<constexpr-param T>
583
+ friend constexpr auto operator~(T) noexcept -> constant_wrapper<(~T::value)>
584
+ { return {}; }
585
+ template<constexpr-param T>
586
+ friend constexpr auto operator!(T) noexcept -> constant_wrapper<(!T::value)>
587
+ { return {}; }
588
+ template<constexpr-param T>
589
+ friend constexpr auto operator&(T) noexcept -> constant_wrapper<(&T::value)>
590
+ { return {}; }
591
+ template<constexpr-param T>
592
+ friend constexpr auto operator*(T) noexcept -> constant_wrapper<(*T::value)>
593
+ { return {}; }
594
+
595
+ // binary operators
596
+ template<constexpr-param L, constexpr-param R>
597
+ friend constexpr auto operator+(L, R) noexcept -> constant_wrapper<(L::value + R::value)>
598
+ { return {}; }
599
+ template<constexpr-param L, constexpr-param R>
600
+ friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)>
601
+ { return {}; }
602
+ template<constexpr-param L, constexpr-param R>
603
+ friend constexpr auto operator*(L, R) noexcept -> constant_wrapper<(L::value * R::value)>
604
+ { return {}; }
605
+ template<constexpr-param L, constexpr-param R>
606
+ friend constexpr auto operator/(L, R) noexcept -> constant_wrapper<(L::value / R::value)>
607
+ { return {}; }
608
+ template<constexpr-param L, constexpr-param R>
609
+ friend constexpr auto operator%(L, R) noexcept -> constant_wrapper<(L::value % R::value)>
610
+ { return {}; }
611
+
612
+ template<constexpr-param L, constexpr-param R>
613
+ friend constexpr auto operator<<(L, R) noexcept -> constant_wrapper<(L::value << R::value)>
614
+ { return {}; }
615
+ template<constexpr-param L, constexpr-param R>
616
+ friend constexpr auto operator>>(L, R) noexcept -> constant_wrapper<(L::value >> R::value)>
617
+ { return {}; }
618
+ template<constexpr-param L, constexpr-param R>
619
+ friend constexpr auto operator&(L, R) noexcept -> constant_wrapper<(L::value & R::value)>
620
+ { return {}; }
621
+ template<constexpr-param L, constexpr-param R>
622
+ friend constexpr auto operator|(L, R) noexcept -> constant_wrapper<(L::value | R::value)>
623
+ { return {}; }
624
+ template<constexpr-param L, constexpr-param R>
625
+ friend constexpr auto operator^(L, R) noexcept -> constant_wrapper<(L::value ^ R::value)>
626
+ { return {}; }
627
+
628
+ template<constexpr-param L, constexpr-param R>
629
+ requires (!is_constructible_v<bool, decltype(L::value)> ||
630
+ !is_constructible_v<bool, decltype(R::value)>)
631
+ friend constexpr auto operator&&(L, R) noexcept
632
+ -> constant_wrapper<(L::value && R::value)>
633
+ { return {}; }
634
+ template<constexpr-param L, constexpr-param R>
635
+ requires (!is_constructible_v<bool, decltype(L::value)> ||
636
+ !is_constructible_v<bool, decltype(R::value)>)
637
+ friend constexpr auto operator||(L, R) noexcept
638
+ -> constant_wrapper<(L::value || R::value)>
639
+ { return {}; }
640
+
641
+ // comparisons
642
+ template<constexpr-param L, constexpr-param R>
643
+ friend constexpr auto operator<=>(L, R) noexcept
644
+ -> constant_wrapper<(L::value <=> R::value)>
645
+ { return {}; }
646
+ template<constexpr-param L, constexpr-param R>
647
+ friend constexpr auto operator<(L, R) noexcept -> constant_wrapper<(L::value < R::value)>
648
+ { return {}; }
649
+ template<constexpr-param L, constexpr-param R>
650
+ friend constexpr auto operator<=(L, R) noexcept -> constant_wrapper<(L::value <= R::value)>
651
+ { return {}; }
652
+ template<constexpr-param L, constexpr-param R>
653
+ friend constexpr auto operator==(L, R) noexcept -> constant_wrapper<(L::value == R::value)>
654
+ { return {}; }
655
+ template<constexpr-param L, constexpr-param R>
656
+ friend constexpr auto operator!=(L, R) noexcept -> constant_wrapper<(L::value != R::value)>
657
+ { return {}; }
658
+ template<constexpr-param L, constexpr-param R>
659
+ friend constexpr auto operator>(L, R) noexcept -> constant_wrapper<(L::value > R::value)>
660
+ { return {}; }
661
+ template<constexpr-param L, constexpr-param R>
662
+ friend constexpr auto operator>=(L, R) noexcept -> constant_wrapper<(L::value >= R::value)>
663
+ { return {}; }
664
+
665
+ template<constexpr-param L, constexpr-param R>
666
+ friend constexpr auto operator,(L, R) noexcept = delete;
667
+ template<constexpr-param L, constexpr-param R>
668
+ friend constexpr auto operator->*(L, R) noexcept -> constant_wrapper<L::value->*(R::value)>
669
+ { return {}; }
670
+
671
+ // call and index
672
+ template<constexpr-param T, constexpr-param... Args>
673
+ constexpr auto operator()(this T, Args...) noexcept
674
+ requires requires { constant_wrapper<T::value(Args::value...)>(); }
675
+ { return constant_wrapper<T::value(Args::value...)>{}; }
676
+ template<constexpr-param T, constexpr-param... Args>
677
+ constexpr auto operator[](this T, Args...) noexcept
678
+ -> constant_wrapper<(T::value[Args::value...])>
679
+ { return {}; }
680
+
681
+ // pseudo-mutators
682
+ template<constexpr-param T>
683
+ constexpr auto operator++(this T) noexcept
684
+ requires requires(T::value_type x) { ++x; }
685
+ { return constant_wrapper<[] { auto c = T::value; return ++c; }()>{}; }
686
+ template<constexpr-param T>
687
+ constexpr auto operator++(this T, int) noexcept
688
+ requires requires(T::value_type x) { x++; }
689
+ { return constant_wrapper<[] { auto c = T::value; return c++; }()>{}; }
690
+
691
+ template<constexpr-param T>
692
+ constexpr auto operator--(this T) noexcept
693
+ requires requires(T::value_type x) { --x; }
694
+ { return constant_wrapper<[] { auto c = T::value; return --c; }()>{}; }
695
+ template<constexpr-param T>
696
+ constexpr auto operator--(this T, int) noexcept
697
+ requires requires(T::value_type x) { x--; }
698
+ { return constant_wrapper<[] { auto c = T::value; return c--; }()>{}; }
699
+
700
+ template<constexpr-param T, constexpr-param R>
701
+ constexpr auto operator+=(this T, R) noexcept
702
+ requires requires(T::value_type x) { x += R::value; }
703
+ { return constant_wrapper<[] { auto v = T::value; return v += R::value; }()>{}; }
704
+ template<constexpr-param T, constexpr-param R>
705
+ constexpr auto operator-=(this T, R) noexcept
706
+ requires requires(T::value_type x) { x -= R::value; }
707
+ { return constant_wrapper<[] { auto v = T::value; return v -= R::value; }()>{}; }
708
+ template<constexpr-param T, constexpr-param R>
709
+ constexpr auto operator*=(this T, R) noexcept
710
+ requires requires(T::value_type x) { x *= R::value; }
711
+ { return constant_wrapper<[] { auto v = T::value; return v *= R::value; }()>{}; }
712
+ template<constexpr-param T, constexpr-param R>
713
+ constexpr auto operator/=(this T, R) noexcept
714
+ requires requires(T::value_type x) { x /= R::value; }
715
+ { return constant_wrapper<[] { auto v = T::value; return v /= R::value; }()>{}; }
716
+ template<constexpr-param T, constexpr-param R>
717
+ constexpr auto operator%=(this T, R) noexcept
718
+ requires requires(T::value_type x) { x %= R::value; }
719
+ { return constant_wrapper<[] { auto v = T::value; return v %= R::value; }()>{}; }
720
+ template<constexpr-param T, constexpr-param R>
721
+ constexpr auto operator&=(this T, R) noexcept
722
+ requires requires(T::value_type x) { x &= R::value; }
723
+ { return constant_wrapper<[] { auto v = T::value; return v &= R::value; }()>{}; }
724
+ template<constexpr-param T, constexpr-param R>
725
+ constexpr auto operator|=(this T, R) noexcept
726
+ requires requires(T::value_type x) { x |= R::value; }
727
+ { return constant_wrapper<[] { auto v = T::value; return v |= R::value; }()>{}; }
728
+ template<constexpr-param T, constexpr-param R>
729
+ constexpr auto operator^=(this T, R) noexcept
730
+ requires requires(T::value_type x) { x ^= R::value; }
731
+ { return constant_wrapper<[] { auto v = T::value; return v ^= R::value; }()>{}; }
732
+ template<constexpr-param T, constexpr-param R>
733
+ constexpr auto operator<<=(this T, R) noexcept
734
+ requires requires(T::value_type x) { x <<= R::value; }
735
+ { return constant_wrapper<[] { auto v = T::value; return v <<= R::value; }()>{}; }
736
+ template<constexpr-param T, constexpr-param R>
737
+ constexpr auto operator>>=(this T, R) noexcept
738
+ requires requires(T::value_type x) { x >>= R::value; }
739
+ { return constant_wrapper<[] { auto v = T::value; return v >>= R::value; }()>{}; }
740
+ };
741
+
742
+ template<cw-fixed-value X, class>
743
+ struct constant_wrapper : cw-operators {
744
+ static constexpr const auto & value = X.data;
745
+ using type = constant_wrapper;
746
+ using value_type = decltype(X)::type;
747
+
748
+ template<constexpr-param R>
749
+ constexpr auto operator=(R) const noexcept
750
+ requires requires(value_type x) { x = R::value; }
751
+ { return constant_wrapper<[] { auto v = value; return v = R::value; }()>{}; }
752
+
753
+ constexpr operator decltype(auto)() const noexcept { return value; }
754
+ };
755
+ }
756
+ ```
757
+
758
+ The class template `constant_wrapper` aids in metaprogramming by
759
+ ensuring that the evaluation of expressions comprised entirely of
760
+ `constant_wrapper` are core constant expressions [[expr.const]],
761
+ regardless of the context in which they appear. In particular, this
762
+ enables use of `constant_wrapper` values that are passed as arguments to
763
+ constexpr functions to be used in constant expressions.
764
+
765
+ [*Note 1*: The unnamed second template parameter to `constant_wrapper`
766
+ is present to aid argument-dependent lookup [[basic.lookup.argdep]] in
767
+ finding overloads for which `constant_wrapper`’s wrapped value is a
768
+ suitable argument, but for which the `constant_wrapper` itself is
769
+ not. — *end note*]
770
+
771
+ [*Example 1*:
772
+
773
+ ``` cpp
774
+ constexpr auto initial_phase(auto quantity_1, auto quantity_2) {
775
+ return quantity_1 + quantity_2;
776
+ }
777
+
778
+ constexpr auto middle_phase(auto tbd) {
779
+ return tbd;
780
+ }
781
+
782
+ void final_phase(auto gathered, auto available) {
783
+ if constexpr (gathered == available)
784
+ std::cout << "Profit!\n";
785
+ }
786
+
787
+ void impeccable_underground_planning() {
788
+ auto gathered_quantity = middle_phase(initial_phase(std::cw<42>, std::cw<13>));
789
+ static_assert(gathered_quantity == 55);
790
+ auto all_available = std::cw<55>;
791
+ final_phase(gathered_quantity, all_available);
792
+ }
793
+
794
+ void deeply_flawed_underground_planning() {
795
+ constexpr auto gathered_quantity = middle_phase(initial_phase(42, 13));
796
+ constexpr auto all_available = 55;
797
+ final_phase(gathered_quantity, all_available); // error: gathered == available
798
+ // is not a constant expression
799
+ }
800
+ ```
801
+
802
+ — *end example*]
803
+
804
+ ``` cpp
805
+ constexpr cw-fixed-value(T (&arr)[Extent]) noexcept;
806
+ ```
807
+
808
+ *Effects:* Initialize elements of *data* with corresponding elements of
809
+ `arr`.
810
+
811
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
812
 
813
  #### General <a id="meta.unary.general">[[meta.unary.general]]</a>
814
 
815
  Subclause [[meta.unary]] contains templates that may be used to query
 
819
  with a base characteristic of `true_type` if the corresponding condition
820
  is `true`, otherwise `false_type`.
821
 
822
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
823
 
824
+ The primary type categories specified in [[meta.unary.cat]] correspond
825
+ to the descriptions given in subclause  [[basic.types]] of the C++
826
+ standard.
827
 
828
  For any given type `T`, the result of applying one of these templates to
829
  `T` and to cv `T` shall yield the same result.
830
 
831
  [*Note 1*: For any given type `T`, exactly one of the primary type
832
  categories has a `value` member that evaluates to `true`. — *end note*]
833
 
834
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
835
 
836
+ The templates specified in [[meta.unary.comp]] provide convenient
837
+ compositions of the primary type categories, corresponding to the
838
+ descriptions given in subclause  [[basic.types]].
839
 
840
  For any given type `T`, the result of applying one of these templates to
841
  `T` and to cv `T` shall yield the same result.
842
 
843
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
844
 
845
+ The templates specified in [[meta.unary.prop]] provide access to some of
846
+ the more important properties of types.
847
 
848
  It is unspecified whether the library defines any full or partial
849
  specializations of any of these templates.
850
 
851
  For all of the class templates `X` declared in this subclause,
 
931
  function template specializations, the generation of implicitly-defined
932
  functions, and so on. Such side effects are not in the “immediate
933
  context” and can result in the program being ill-formed. — *end note*]
934
 
935
  The predicate condition for a template specialization
936
+ `has_unique_object_representations<T>` shall be satisfied if and only if
 
937
 
938
  - `T` is trivially copyable, and
939
  - any two objects of type `T` with the same value have the same object
940
+ representation, where
941
+ - two objects of array or non-union class type are considered to have
942
+ the same value if their respective sequences of direct subobjects
943
+ have the same values, and
944
+ - two objects of union type are considered to have the same value if
945
+ they have the same active member and the corresponding members have
946
+ the same value.
947
 
948
  The set of scalar types for which this condition holds is
949
  *implementation-defined*.
950
 
951
  [*Note 4*: If a type has padding bits, the condition does not hold;
952
  otherwise, the condition holds true for integral types. — *end note*]
953
 
954
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
955
 
956
+ The templates specified in [[meta.unary.prop.query]] may be used to
957
+ query properties of types at compile time.
958
 
959
  Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
960
  with a base characteristic of `integral_constant<size_t, Value>`.
961
 
962
  [*Example 1*:
963
 
964
  ``` cpp
965
  // the following assertions hold:
966
+ static_assert(rank_v<int> == 0);
967
+ static_assert(rank_v<int[2]> == 1);
968
+ static_assert(rank_v<int[][4]> == 2);
969
  ```
970
 
971
  — *end example*]
972
 
973
  [*Example 2*:
974
 
975
  ``` cpp
976
  // the following assertions hold:
977
+ static_assert(extent_v<int> == 0);
978
+ static_assert(extent_v<int[2]> == 2);
979
+ static_assert(extent_v<int[2][4]> == 2);
980
+ static_assert(extent_v<int[][4]> == 0);
981
+ static_assert(extent_v<int, 1> == 0);
982
+ static_assert(extent_v<int[2], 1> == 0);
983
+ static_assert(extent_v<int[2][4], 1> == 4);
984
+ static_assert(extent_v<int[][4], 1> == 4);
985
  ```
986
 
987
  — *end example*]
988
 
989
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
990
 
991
+ The templates specified in [[meta.rel]] may be used to query
992
  relationships between types at compile time.
993
 
994
  Each of these templates shall be a *Cpp17BinaryTypeTrait* [[meta.rqmts]]
995
  with a base characteristic of `true_type` if the corresponding condition
996
  is true, otherwise `false_type`.
997
 
998
+ Let `ELEMS-OF(T)` be the parameter pack `get<N>(declval<T>())`, where
999
+ *`N`* is the pack of `size_t` template arguments of the specialization
1000
+ of `index_sequence` denoted by
1001
+ `make_index_sequence<tuple_size_v<remove_reference_t<T>>>`.
1002
+
1003
+ [*Note 1*: Virtual base classes that are private, protected, or
1004
+ ambiguous are, nonetheless, virtual base classes. — *end note*]
1005
+
1006
  For the purpose of defining the templates in this subclause, a function
1007
  call expression `declval<T>()` for any type `T` is considered to be a
1008
  trivial [[term.trivial.type]], [[special]] function call that is not an
1009
  odr-use [[term.odr.use]] of `declval` in the context of the
1010
  corresponding definition notwithstanding the restrictions of 
 
1039
  To test() {
1040
  return declval<From>();
1041
  }
1042
  ```
1043
 
1044
+ [*Note 2*: This requirement gives well-defined results for reference
1045
  types, array types, function types, and cv `void`. — *end note*]
1046
 
1047
  Access checking is performed in a context unrelated to `To` and `From`.
1048
  Only the validity of the immediate context of the *expression* of the
1049
  `return` statement [[stmt.return]] (including initialization of the
1050
  returned object or reference) is considered.
1051
 
1052
+ [*Note 3*: The initialization can result in side effects such as the
1053
  instantiation of class template specializations and function template
1054
  specializations, the generation of implicitly-defined functions, and so
1055
  on. Such side effects are not in the “immediate context” and can result
1056
  in the program being ill-formed. — *end note*]
1057
 
 
1065
  Each of the templates in [[meta.trans]] shall be a
1066
  *Cpp17TransformationTrait* [[meta.rqmts]].
1067
 
1068
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
1069
 
1070
+ The templates specified in [[meta.trans.cv]] add or remove
1071
+ cv-qualifications [[basic.type.qualifier]].
1072
+
1073
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
1074
 
1075
+ The templates specified in [[meta.trans.ref]] add or remove references.
1076
+
1077
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
1078
 
1079
+ The templates specified in [[meta.trans.sign]] convert an integer type
1080
+ to its corresponding signed or unsigned type.
1081
+
1082
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
1083
 
1084
+ The templates specified in [[meta.trans.arr]] modify array types.
1085
+
1086
  [*Example 1*:
1087
 
1088
  ``` cpp
1089
  // the following assertions hold:
1090
+ static_assert(is_same_v<remove_extent_t<int>, int>);
1091
+ static_assert(is_same_v<remove_extent_t<int[2]>, int>);
1092
+ static_assert(is_same_v<remove_extent_t<int[2][3]>, int[3]>);
1093
+ static_assert(is_same_v<remove_extent_t<int[][3]>, int[3]>);
1094
  ```
1095
 
1096
  — *end example*]
1097
 
1098
  [*Example 2*:
1099
 
1100
  ``` cpp
1101
  // the following assertions hold:
1102
+ static_assert(is_same_v<remove_all_extents_t<int>, int>);
1103
+ static_assert(is_same_v<remove_all_extents_t<int[2]>, int>);
1104
+ static_assert(is_same_v<remove_all_extents_t<int[2][3]>, int>);
1105
+ static_assert(is_same_v<remove_all_extents_t<int[][3]>, int>);
1106
  ```
1107
 
1108
  — *end example*]
1109
 
1110
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
1111
 
1112
+ The templates specified in [[meta.trans.ptr]] add or remove pointers.
1113
+
1114
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
1115
 
1116
+ The templates specified in [[meta.trans.other]] perform other
1117
+ modifications of a type.
1118
+
1119
  [*Note 1*: The compilation of the expression can result in side effects
1120
  such as the instantiation of class template specializations and function
1121
  template specializations, the generation of implicitly-defined
1122
  functions, and so on. Such side effects are not in the “immediate
1123
  context” and can result in the program being ill-formed. — *end note*]
 
1158
  - Otherwise, `COMMON-REF(A, B)` is ill-formed.
1159
 
1160
  If any of the types computed above is ill-formed, then
1161
  `COMMON-REF(A, B)` is ill-formed.
1162
 
1163
+ For the `common_type` trait applied to a template parameter pack `T` of
1164
+ types, the member `type` shall be either defined or not present as
1165
+ follows:
1166
 
1167
  - If `sizeof...(T)` is zero, there shall be no member `type`.
1168
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
1169
  the pack `T`. The member *typedef-name* `type` shall denote the same
1170
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
 
1195
  constituting `T`. Let `C` denote the same type, if any, as
1196
  `common_type_t<T1, T2>`. If there is such a type `C`, the member
1197
  *typedef-name* `type` shall denote the same type, if any, as
1198
  `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
1199
 
1200
+ Notwithstanding the provisions of [[meta.rqmts]], and pursuant to
1201
+ [[namespace.std]], a program may specialize `common_type<T1, T2>` for
1202
+ types `T1` and `T2` such that `is_same_v<T1, decay_t<T1>>` and
1203
+ `is_same_v<T2, decay_t<T2>>` are each `true`.
 
1204
 
1205
  [*Note 3*: Such specializations are needed when only explicit
1206
  conversions are desired between the template arguments. — *end note*]
1207
 
1208
  Such a specialization need not have a member named `type`, but if it
 
1210
  cv-unqualified non-reference type to which each of the types `T1` and
1211
  `T2` is explicitly convertible. Moreover, `common_type_t<T1, T2>` shall
1212
  denote the same type, if any, as does `common_type_t<T2, T1>`. No
1213
  diagnostic is required for a violation of this Note’s rules.
1214
 
1215
+ For the `common_reference` trait applied to a parameter pack `T` of
1216
+ types, the member `type` shall be either defined or not present as
1217
  follows:
1218
 
1219
  - If `sizeof...(T)` is zero, there shall be no member `type`.
1220
  - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
1221
  the pack `T`. The member typedef `type` shall denote the same type as
 
1241
  `common_reference_t<T1, T2>`. Then:
1242
  - If there is such a type `C`, the member typedef `type` shall denote
1243
  the same type, if any, as `common_reference_t<C, Rest...>`.
1244
  - Otherwise, there shall be no member `type`.
1245
 
1246
+ Notwithstanding the provisions of [[meta.rqmts]], and pursuant to
1247
+ [[namespace.std]], a program may partially specialize
1248
  `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
1249
  that `is_same_v<T, decay_t<T>>` and `is_same_v<U, decay_t<U>>` are each
1250
  `true`.
1251
 
1252
  [*Note 4*: Such specializations can be used to influence the result of
 
1416
  struct C: public A, public B { }; // not a standard-layout class
1417
 
1418
  static_assert( is_pointer_interconvertible_with_class( &C::b ) );
1419
  // Succeeds because, despite its appearance, &C::b has type
1420
  // ``pointer to member of B of type int''.
1421
+ static_assert( !is_pointer_interconvertible_with_class<C, int>( &C::b ) );
1422
+ // Forces the use of class C, and the result is false.
1423
 
1424
  static_assert( is_corresponding_member( &C::a, &C::b ) );
1425
  // Succeeds because, despite its appearance, &C::a and &C::b have types
1426
  // ``pointer to member of A of type int'' and
1427
  // ``pointer to member of B of type int'', respectively.
1428
+ static_assert( !is_corresponding_member<C, C, int, int>( &C::a, &C::b ) );
1429
+ // Forces the use of class C, and the result is false.
1430
  ```
1431
 
1432
  — *end example*]
1433
 
1434
  — *end note*]
 
1461
  }
1462
  ```
1463
 
1464
  — *end example*]
1465
 
1466
+ ``` cpp
1467
+ consteval bool is_within_lifetime(const auto* p) noexcept;
1468
+ ```
1469
+
1470
+ *Returns:* `true` if `p` is a pointer to an object that is within its
1471
+ lifetime [[basic.life]]; otherwise, `false`.
1472
+
1473
+ *Remarks:* During the evaluation of an expression `E` as a core constant
1474
+ expression, a call to this function is ill-formed unless `p` points to
1475
+ an object that is usable in constant expressions or whose complete
1476
+ object’s lifetime began within `E`.
1477
+
1478
+ [*Example 2*:
1479
+
1480
+ ``` cpp
1481
+ struct OptBool {
1482
+ union { bool b; char c; };
1483
+
1484
+ // note: this assumes common implementation properties for bool and char:
1485
+ // * sizeof(bool) == sizeof(char), and
1486
+ // * the value representations for true and false are distinct
1487
+ // from the value representation for 2
1488
+ constexpr OptBool() : c(2) { }
1489
+ constexpr OptBool(bool b) : b(b) { }
1490
+
1491
+ constexpr auto has_value() const -> bool {
1492
+ if consteval {
1493
+ return std::is_within_lifetime(&b); // during constant evaluation, cannot read from c
1494
+ } else {
1495
+ return c != 2; // during runtime, must read from c
1496
+ }
1497
+ }
1498
+
1499
+ constexpr auto operator*() const -> const bool& {
1500
+ return b;
1501
+ }
1502
+ };
1503
+
1504
+ constexpr OptBool disengaged;
1505
+ constexpr OptBool engaged(true);
1506
+ static_assert(!disengaged.has_value());
1507
+ static_assert(engaged.has_value());
1508
+ static_assert(*engaged);
1509
+ ```
1510
+
1511
+ — *end example*]
1512
+