From Jason Turner

[meta]

Large diff (156.4 KB) - rendering may be slow on some devices

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmponlrupu2/{from.md → to.md} +3401 -115
tmp/tmponlrupu2/{from.md → to.md} RENAMED
@@ -6,19 +6,20 @@ This Clause describes metaprogramming facilities. These facilities are
6
  summarized in [[meta.summary]].
7
 
8
  **Table: Metaprogramming library summary** <a id="meta.summary">[meta.summary]</a>
9
 
10
  | Subclause | | Header |
11
- | --------------- | ------------------- | --------------- |
12
  | [[intseq]] | Integer sequences | `<utility>` |
13
  | [[type.traits]] | Type traits | `<type_traits>` |
 
14
  | [[ratio]] | Rational arithmetic | `<ratio>` |
15
 
16
 
17
  ## Compile-time integer sequences <a id="intseq">[[intseq]]</a>
18
 
19
- ### In general <a id="intseq.general">[[intseq.general]]</a>
20
 
21
  The library provides a class template that can represent an integer
22
  sequence. When used as an argument to a function template the template
23
  parameter pack defining the sequence can be deduced and used in a pack
24
  expansion.
@@ -48,13 +49,13 @@ template<class T, T N>
48
  ```
49
 
50
  *Mandates:* `N` ≥ 0.
51
 
52
  The alias template `make_integer_sequence` denotes a specialization of
53
- `integer_sequence` with `N` non-type template arguments. The type
54
  `make_integer_sequence<T, N>` is an alias for the type
55
- `integer_sequence<T, 0, 1, ..., N-1>`.
56
 
57
  [*Note 1*: `make_integer_sequence<int, 0>` is an alias for the type
58
  `integer_sequence<int>`. — *end note*]
59
 
60
  ## Metaprogramming and type traits <a id="type.traits">[[type.traits]]</a>
@@ -112,11 +113,11 @@ Unless otherwise specified, the behavior of a program that adds
112
  specializations for any of the templates specified in [[type.traits]] is
113
  undefined.
114
 
115
  Unless otherwise specified, an incomplete type may be used to
116
  instantiate a template specified in [[type.traits]]. The behavior of a
117
- program is undefined if:
118
 
119
  - an instantiation of a template specified in [[type.traits]] directly
120
  or indirectly depends on an incompletely-defined object type `T`, and
121
  - that instantiation could yield a different result were `T`
122
  hypothetically completed.
@@ -132,10 +133,26 @@ namespace std {
132
  template<bool B>
133
  using bool_constant = integral_constant<bool, B>;
134
  using true_type = bool_constant<true>;
135
  using false_type = bool_constant<false>;
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  // [meta.unary.cat], primary type categories
138
  template<class T> struct is_void;
139
  template<class T> struct is_null_pointer;
140
  template<class T> struct is_integral;
141
  template<class T> struct is_floating_point;
@@ -147,10 +164,11 @@ namespace std {
147
  template<class T> struct is_member_function_pointer;
148
  template<class T> struct is_enum;
149
  template<class T> struct is_union;
150
  template<class T> struct is_class;
151
  template<class T> struct is_function;
 
152
 
153
  // [meta.unary.comp], composite type categories
154
  template<class T> struct is_reference;
155
  template<class T> struct is_arithmetic;
156
  template<class T> struct is_fundamental;
@@ -160,18 +178,20 @@ namespace std {
160
  template<class T> struct is_member_pointer;
161
 
162
  // [meta.unary.prop], type properties
163
  template<class T> struct is_const;
164
  template<class T> struct is_volatile;
165
- template<class T> struct is_trivial;
166
  template<class T> struct is_trivially_copyable;
 
 
167
  template<class T> struct is_standard_layout;
168
  template<class T> struct is_empty;
169
  template<class T> struct is_polymorphic;
170
  template<class T> struct is_abstract;
171
  template<class T> struct is_final;
172
  template<class T> struct is_aggregate;
 
173
 
174
  template<class T> struct is_signed;
175
  template<class T> struct is_unsigned;
176
  template<class T> struct is_bounded_array;
177
  template<class T> struct is_unbounded_array;
@@ -212,10 +232,11 @@ namespace std {
212
 
213
  template<class T, class U> struct is_nothrow_swappable_with;
214
  template<class T> struct is_nothrow_swappable;
215
 
216
  template<class T> struct is_nothrow_destructible;
 
217
 
218
  template<class T> struct is_implicit_lifetime;
219
 
220
  template<class T> struct has_virtual_destructor;
221
 
@@ -230,10 +251,11 @@ namespace std {
230
  template<class T, unsigned I = 0> struct extent;
231
 
232
  // [meta.rel], type relations
233
  template<class T, class U> struct is_same;
234
  template<class Base, class Derived> struct is_base_of;
 
235
  template<class From, class To> struct is_convertible;
236
  template<class From, class To> struct is_nothrow_convertible;
237
  template<class T, class U> struct is_layout_compatible;
238
  template<class Base, class Derived> struct is_pointer_interconvertible_base_of;
239
 
@@ -241,69 +263,72 @@ namespace std {
241
  template<class R, class Fn, class... ArgTypes> struct is_invocable_r;
242
 
243
  template<class Fn, class... ArgTypes> struct is_nothrow_invocable;
244
  template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
245
 
 
 
 
246
  // [meta.trans.cv], const-volatile modifications
247
  template<class T> struct remove_const;
248
  template<class T> struct remove_volatile;
249
  template<class T> struct remove_cv;
250
  template<class T> struct add_const;
251
  template<class T> struct add_volatile;
252
  template<class T> struct add_cv;
253
 
254
  template<class T>
255
- using remove_const_t = typename remove_const<T>::type;
256
  template<class T>
257
- using remove_volatile_t = typename remove_volatile<T>::type;
258
  template<class T>
259
- using remove_cv_t = typename remove_cv<T>::type;
260
  template<class T>
261
- using add_const_t = typename add_const<T>::type;
262
  template<class T>
263
- using add_volatile_t = typename add_volatile<T>::type;
264
  template<class T>
265
- using add_cv_t = typename add_cv<T>::type;
266
 
267
  // [meta.trans.ref], reference modifications
268
  template<class T> struct remove_reference;
269
  template<class T> struct add_lvalue_reference;
270
  template<class T> struct add_rvalue_reference;
271
 
272
  template<class T>
273
- using remove_reference_t = typename remove_reference<T>::type;
274
  template<class T>
275
- using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
276
  template<class T>
277
- using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
278
 
279
  // [meta.trans.sign], sign modifications
280
  template<class T> struct make_signed;
281
  template<class T> struct make_unsigned;
282
 
283
  template<class T>
284
- using make_signed_t = typename make_signed<T>::type;
285
  template<class T>
286
- using make_unsigned_t = typename make_unsigned<T>::type;
287
 
288
  // [meta.trans.arr], array modifications
289
  template<class T> struct remove_extent;
290
  template<class T> struct remove_all_extents;
291
 
292
  template<class T>
293
- using remove_extent_t = typename remove_extent<T>::type;
294
  template<class T>
295
- using remove_all_extents_t = typename remove_all_extents<T>::type;
296
 
297
  // [meta.trans.ptr], pointer modifications
298
  template<class T> struct remove_pointer;
299
  template<class T> struct add_pointer;
300
 
301
  template<class T>
302
- using remove_pointer_t = typename remove_pointer<T>::type;
303
  template<class T>
304
- using add_pointer_t = typename add_pointer<T>::type;
305
 
306
  // [meta.trans.other], other transformations
307
  template<class T> struct type_identity;
308
  template<class T> struct remove_cvref;
309
  template<class T> struct decay;
@@ -313,35 +338,38 @@ namespace std {
313
  template<class T, class U, template<class> class TQual, template<class> class UQual>
314
  struct basic_common_reference { };
315
  template<class... T> struct common_reference;
316
  template<class T> struct underlying_type;
317
  template<class Fn, class... ArgTypes> struct invoke_result;
 
318
  template<class T> struct unwrap_reference;
319
  template<class T> struct unwrap_ref_decay;
320
 
321
  template<class T>
322
- using type_identity_t = typename type_identity<T>::type;
323
  template<class T>
324
- using remove_cvref_t = typename remove_cvref<T>::type;
325
  template<class T>
326
- using decay_t = typename decay<T>::type;
327
  template<bool B, class T = void>
328
- using enable_if_t = typename enable_if<B, T>::type;
329
  template<bool B, class T, class F>
330
- using conditional_t = typename conditional<B, T, F>::type;
331
  template<class... T>
332
- using common_type_t = typename common_type<T...>::type;
333
  template<class... T>
334
- using common_reference_t = typename common_reference<T...>::type;
335
  template<class T>
336
- using underlying_type_t = typename underlying_type<T>::type;
337
  template<class Fn, class... ArgTypes>
338
- using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
 
 
339
  template<class T>
340
- using unwrap_reference_t = typename unwrap_reference<T>::type;
341
  template<class T>
342
- using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
343
  template<class...>
344
  using void_t = void;
345
 
346
  // [meta.logical], logical operator traits
347
  template<class... B> struct conjunction;
@@ -375,10 +403,12 @@ namespace std {
375
  constexpr bool is_union_v = is_union<T>::value;
376
  template<class T>
377
  constexpr bool is_class_v = is_class<T>::value;
378
  template<class T>
379
  constexpr bool is_function_v = is_function<T>::value;
 
 
380
 
381
  // [meta.unary.comp], composite type categories
382
  template<class T>
383
  constexpr bool is_reference_v = is_reference<T>::value;
384
  template<class T>
@@ -397,14 +427,14 @@ namespace std {
397
  // [meta.unary.prop], type properties
398
  template<class T>
399
  constexpr bool is_const_v = is_const<T>::value;
400
  template<class T>
401
  constexpr bool is_volatile_v = is_volatile<T>::value;
402
- template<class T>
403
- constexpr bool is_trivial_v = is_trivial<T>::value;
404
  template<class T>
405
  constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
 
 
406
  template<class T>
407
  constexpr bool is_standard_layout_v = is_standard_layout<T>::value;
408
  template<class T>
409
  constexpr bool is_empty_v = is_empty<T>::value;
410
  template<class T>
@@ -413,10 +443,12 @@ namespace std {
413
  constexpr bool is_abstract_v = is_abstract<T>::value;
414
  template<class T>
415
  constexpr bool is_final_v = is_final<T>::value;
416
  template<class T>
417
  constexpr bool is_aggregate_v = is_aggregate<T>::value;
 
 
418
  template<class T>
419
  constexpr bool is_signed_v = is_signed<T>::value;
420
  template<class T>
421
  constexpr bool is_unsigned_v = is_unsigned<T>::value;
422
  template<class T>
@@ -444,43 +476,35 @@ namespace std {
444
  template<class T>
445
  constexpr bool is_swappable_v = is_swappable<T>::value;
446
  template<class T>
447
  constexpr bool is_destructible_v = is_destructible<T>::value;
448
  template<class T, class... Args>
449
- constexpr bool is_trivially_constructible_v
450
- = is_trivially_constructible<T, Args...>::value;
451
  template<class T>
452
  constexpr bool is_trivially_default_constructible_v
453
  = is_trivially_default_constructible<T>::value;
454
  template<class T>
455
- constexpr bool is_trivially_copy_constructible_v
456
- = is_trivially_copy_constructible<T>::value;
457
  template<class T>
458
- constexpr bool is_trivially_move_constructible_v
459
- = is_trivially_move_constructible<T>::value;
460
  template<class T, class U>
461
  constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
462
  template<class T>
463
- constexpr bool is_trivially_copy_assignable_v
464
- = is_trivially_copy_assignable<T>::value;
465
  template<class T>
466
- constexpr bool is_trivially_move_assignable_v
467
- = is_trivially_move_assignable<T>::value;
468
  template<class T>
469
  constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
470
  template<class T, class... Args>
471
- constexpr bool is_nothrow_constructible_v
472
- = is_nothrow_constructible<T, Args...>::value;
473
  template<class T>
474
  constexpr bool is_nothrow_default_constructible_v
475
  = is_nothrow_default_constructible<T>::value;
476
  template<class T>
477
- constexpr bool is_nothrow_copy_constructible_v
478
- = is_nothrow_copy_constructible<T>::value;
479
  template<class T>
480
- constexpr bool is_nothrow_move_constructible_v
481
- = is_nothrow_move_constructible<T>::value;
482
  template<class T, class U>
483
  constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
484
  template<class T>
485
  constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value;
486
  template<class T>
@@ -489,12 +513,16 @@ namespace std {
489
  constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value;
490
  template<class T>
491
  constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value;
492
  template<class T>
493
  constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value;
 
 
494
  template<class T>
495
  constexpr bool is_implicit_lifetime_v = is_implicit_lifetime<T>::value;
 
 
496
  template<class T>
497
  constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
498
  template<class T>
499
  constexpr bool has_unique_object_representations_v
500
  = has_unique_object_representations<T>::value;
@@ -516,10 +544,12 @@ namespace std {
516
  // [meta.rel], type relations
517
  template<class T, class U>
518
  constexpr bool is_same_v = is_same<T, U>::value;
519
  template<class Base, class Derived>
520
  constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
 
 
521
  template<class From, class To>
522
  constexpr bool is_convertible_v = is_convertible<From, To>::value;
523
  template<class From, class To>
524
  constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
525
  template<class T, class U>
@@ -532,12 +562,15 @@ namespace std {
532
  template<class R, class Fn, class... ArgTypes>
533
  constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value;
534
  template<class Fn, class... ArgTypes>
535
  constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value;
536
  template<class R, class Fn, class... ArgTypes>
537
- constexpr bool is_nothrow_invocable_r_v
538
- = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
 
 
 
539
 
540
  // [meta.logical], logical operator traits
541
  template<class... B>
542
  constexpr bool conjunction_v = conjunction<B...>::value;
543
  template<class... B>
@@ -551,10 +584,11 @@ namespace std {
551
  template<class S1, class S2, class M1, class M2>
552
  constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
553
 
554
  // [meta.const.eval], constant evaluation context
555
  constexpr bool is_constant_evaluated() noexcept;
 
556
  }
557
  ```
558
 
559
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
560
 
@@ -574,10 +608,268 @@ namespace std {
574
 
575
  The class template `integral_constant`, alias template `bool_constant`,
576
  and its associated *typedef-name*s `true_type` and `false_type` are used
577
  as base classes to define the interface for various type traits.
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
580
 
581
  #### General <a id="meta.unary.general">[[meta.unary.general]]</a>
582
 
583
  Subclause [[meta.unary]] contains templates that may be used to query
@@ -587,32 +879,33 @@ Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
587
  with a base characteristic of `true_type` if the corresponding condition
588
  is `true`, otherwise `false_type`.
589
 
590
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
591
 
592
- The primary type categories correspond to the descriptions given in
593
- subclause  [[basic.types]] of the C++ standard.
 
594
 
595
  For any given type `T`, the result of applying one of these templates to
596
  `T` and to cv `T` shall yield the same result.
597
 
598
  [*Note 1*: For any given type `T`, exactly one of the primary type
599
  categories has a `value` member that evaluates to `true`. — *end note*]
600
 
601
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
602
 
603
- These templates provide convenient compositions of the primary type
604
- categories, corresponding to the descriptions given in subclause 
605
- [[basic.types]].
606
 
607
  For any given type `T`, the result of applying one of these templates to
608
  `T` and to cv `T` shall yield the same result.
609
 
610
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
611
 
612
- These templates provide access to some of the more important properties
613
- of types.
614
 
615
  It is unspecified whether the library defines any full or partial
616
  specializations of any of these templates.
617
 
618
  For all of the class templates `X` declared in this subclause,
@@ -698,71 +991,80 @@ effects such as the instantiation of class template specializations and
698
  function template specializations, the generation of implicitly-defined
699
  functions, and so on. Such side effects are not in the “immediate
700
  context” and can result in the program being ill-formed. — *end note*]
701
 
702
  The predicate condition for a template specialization
703
- `has_unique_object_representations<T>` shall be satisfied if and only
704
- if:
705
 
706
  - `T` is trivially copyable, and
707
  - any two objects of type `T` with the same value have the same object
708
- representation, where two objects of array or non-union class type are
709
- considered to have the same value if their respective sequences of
710
- direct subobjects have the same values, and two objects of union type
711
- are considered to have the same value if they have the same active
712
- member and the corresponding members have the same value.
 
 
713
 
714
  The set of scalar types for which this condition holds is
715
  *implementation-defined*.
716
 
717
  [*Note 4*: If a type has padding bits, the condition does not hold;
718
  otherwise, the condition holds true for integral types. — *end note*]
719
 
720
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
721
 
722
- This subclause contains templates that may be used to query properties
723
- of types at compile time.
724
 
725
  Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
726
  with a base characteristic of `integral_constant<size_t, Value>`.
727
 
728
  [*Example 1*:
729
 
730
  ``` cpp
731
  // the following assertions hold:
732
- assert(rank_v<int> == 0);
733
- assert(rank_v<int[2]> == 1);
734
- assert(rank_v<int[][4]> == 2);
735
  ```
736
 
737
  — *end example*]
738
 
739
  [*Example 2*:
740
 
741
  ``` cpp
742
  // the following assertions hold:
743
- assert(extent_v<int> == 0);
744
- assert(extent_v<int[2]> == 2);
745
- assert(extent_v<int[2][4]> == 2);
746
- assert(extent_v<int[][4]> == 0);
747
- assert((extent_v<int, 1>) == 0);
748
- assert((extent_v<int[2], 1>) == 0);
749
- assert((extent_v<int[2][4], 1>) == 4);
750
- assert((extent_v<int[][4], 1>) == 4);
751
  ```
752
 
753
  — *end example*]
754
 
755
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
756
 
757
- This subclause contains templates that may be used to query
758
  relationships between types at compile time.
759
 
760
  Each of these templates shall be a *Cpp17BinaryTypeTrait* [[meta.rqmts]]
761
  with a base characteristic of `true_type` if the corresponding condition
762
  is true, otherwise `false_type`.
763
 
 
 
 
 
 
 
 
 
764
  For the purpose of defining the templates in this subclause, a function
765
  call expression `declval<T>()` for any type `T` is considered to be a
766
  trivial [[term.trivial.type]], [[special]] function call that is not an
767
  odr-use [[term.odr.use]] of `declval` in the context of the
768
  corresponding definition notwithstanding the restrictions of 
@@ -797,19 +1099,19 @@ implicit conversions to the return type of the function:
797
  To test() {
798
  return declval<From>();
799
  }
800
  ```
801
 
802
- [*Note 1*: This requirement gives well-defined results for reference
803
  types, array types, function types, and cv `void`. — *end note*]
804
 
805
  Access checking is performed in a context unrelated to `To` and `From`.
806
  Only the validity of the immediate context of the *expression* of the
807
  `return` statement [[stmt.return]] (including initialization of the
808
  returned object or reference) is considered.
809
 
810
- [*Note 2*: The initialization can result in side effects such as the
811
  instantiation of class template specializations and function template
812
  specializations, the generation of implicitly-defined functions, and so
813
  on. Such side effects are not in the “immediate context” and can result
814
  in the program being ill-formed. — *end note*]
815
 
@@ -823,44 +1125,59 @@ transform one type to another following some predefined rule.
823
  Each of the templates in [[meta.trans]] shall be a
824
  *Cpp17TransformationTrait* [[meta.rqmts]].
825
 
826
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
827
 
 
 
 
828
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
829
 
 
 
830
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
831
 
 
 
 
832
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
833
 
 
 
834
  [*Example 1*:
835
 
836
  ``` cpp
837
  // the following assertions hold:
838
- assert((is_same_v<remove_extent_t<int>, int>));
839
- assert((is_same_v<remove_extent_t<int[2]>, int>));
840
- assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
841
- assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
842
  ```
843
 
844
  — *end example*]
845
 
846
  [*Example 2*:
847
 
848
  ``` cpp
849
  // the following assertions hold:
850
- assert((is_same_v<remove_all_extents_t<int>, int>));
851
- assert((is_same_v<remove_all_extents_t<int[2]>, int>));
852
- assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
853
- assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
854
  ```
855
 
856
  — *end example*]
857
 
858
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
859
 
 
 
860
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
861
 
 
 
 
862
  [*Note 1*: The compilation of the expression can result in side effects
863
  such as the instantiation of class template specializations and function
864
  template specializations, the generation of implicitly-defined
865
  functions, and so on. Such side effects are not in the “immediate
866
  context” and can result in the program being ill-formed. — *end note*]
@@ -901,13 +1218,13 @@ Given types `A` and `B`, let `X` be `remove_reference_t<A>`, let `Y` be
901
  - Otherwise, `COMMON-REF(A, B)` is ill-formed.
902
 
903
  If any of the types computed above is ill-formed, then
904
  `COMMON-REF(A, B)` is ill-formed.
905
 
906
- Note A: For the `common_type` trait applied to a template parameter pack
907
- `T` of types, the member `type` shall be either defined or not present
908
- as follows:
909
 
910
  - If `sizeof...(T)` is zero, there shall be no member `type`.
911
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
912
  the pack `T`. The member *typedef-name* `type` shall denote the same
913
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
@@ -938,15 +1255,14 @@ as follows:
938
  constituting `T`. Let `C` denote the same type, if any, as
939
  `common_type_t<T1, T2>`. If there is such a type `C`, the member
940
  *typedef-name* `type` shall denote the same type, if any, as
941
  `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
942
 
943
- Note B: Notwithstanding the provisions of [[meta.type.synop]], and
944
- pursuant to [[namespace.std]], a program may specialize
945
- `common_type<T1, T2>` for types `T1` and `T2` such that
946
- `is_same_v<T1, decay_t<T1>>` and `is_same_v<T2, decay_t<T2>>` are each
947
- `true`.
948
 
949
  [*Note 3*: Such specializations are needed when only explicit
950
  conversions are desired between the template arguments. — *end note*]
951
 
952
  Such a specialization need not have a member named `type`, but if it
@@ -954,12 +1270,12 @@ does, the *qualified-id* `common_type<T1, T2>::type` shall denote a
954
  cv-unqualified non-reference type to which each of the types `T1` and
955
  `T2` is explicitly convertible. Moreover, `common_type_t<T1, T2>` shall
956
  denote the same type, if any, as does `common_type_t<T2, T1>`. No
957
  diagnostic is required for a violation of this Note’s rules.
958
 
959
- Note C: For the `common_reference` trait applied to a parameter pack `T`
960
- of types, the member `type` shall be either defined or not present as
961
  follows:
962
 
963
  - If `sizeof...(T)` is zero, there shall be no member `type`.
964
  - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
965
  the pack `T`. The member typedef `type` shall denote the same type as
@@ -985,12 +1301,12 @@ follows:
985
  `common_reference_t<T1, T2>`. Then:
986
  - If there is such a type `C`, the member typedef `type` shall denote
987
  the same type, if any, as `common_reference_t<C, Rest...>`.
988
  - Otherwise, there shall be no member `type`.
989
 
990
- Note D: Notwithstanding the provisions of [[meta.type.synop]], and
991
- pursuant to [[namespace.std]], a program may partially specialize
992
  `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
993
  that `is_same_v<T, decay_t<T>>` and `is_same_v<U, decay_t<U>>` are each
994
  `true`.
995
 
996
  [*Note 4*: Such specializations can be used to influence the result of
@@ -1160,19 +1476,19 @@ struct B { int b; }; // a standard-layout class
1160
  struct C: public A, public B { }; // not a standard-layout class
1161
 
1162
  static_assert( is_pointer_interconvertible_with_class( &C::b ) );
1163
  // Succeeds because, despite its appearance, &C::b has type
1164
  // ``pointer to member of B of type int''.
1165
- static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) );
1166
- // Forces the use of class C, and fails.
1167
 
1168
  static_assert( is_corresponding_member( &C::a, &C::b ) );
1169
  // Succeeds because, despite its appearance, &C::a and &C::b have types
1170
  // ``pointer to member of A of type int'' and
1171
  // ``pointer to member of B of type int'', respectively.
1172
- static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) );
1173
- // Forces the use of class C, and fails.
1174
  ```
1175
 
1176
  — *end example*]
1177
 
1178
  — *end note*]
@@ -1205,13 +1521,2917 @@ constexpr void f(unsigned char *p, int n) {
1205
  }
1206
  ```
1207
 
1208
  — *end example*]
1209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1210
  ## Compile-time rational arithmetic <a id="ratio">[[ratio]]</a>
1211
 
1212
- ### In general <a id="ratio.general">[[ratio.general]]</a>
1213
 
1214
  Subclause  [[ratio]] describes the ratio library. It provides a class
1215
  template `ratio` which exactly represents any finite rational number
1216
  with a numerator and denominator representable by compile-time constants
1217
  of type `intmax_t`.
@@ -1255,10 +4475,12 @@ namespace std {
1255
  constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
1256
  template<class R1, class R2>
1257
  constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
1258
 
1259
  // [ratio.si], convenience SI typedefs
 
 
1260
  using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; // see below
1261
  using zepto = ratio<1, 1'000'000'000'000'000'000'000>; // see below
1262
  using atto = ratio<1, 1'000'000'000'000'000'000>;
1263
  using femto = ratio<1, 1'000'000'000'000'000>;
1264
  using pico = ratio<1, 1'000'000'000'000>;
@@ -1275,10 +4497,12 @@ namespace std {
1275
  using tera = ratio< 1'000'000'000'000, 1>;
1276
  using peta = ratio< 1'000'000'000'000'000, 1>;
1277
  using exa = ratio< 1'000'000'000'000'000'000, 1>;
1278
  using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; // see below
1279
  using yotta = ratio< 1'000'000'000'000'000'000'000'000, 1>; // see below
 
 
1280
  }
1281
  ```
1282
 
1283
  ### Class template `ratio` <a id="ratio.ratio">[[ratio.ratio]]</a>
1284
 
@@ -1397,55 +4621,105 @@ template<class R1, class R2>
1397
  struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };
1398
  ```
1399
 
1400
  ### SI types for `ratio` <a id="ratio.si">[[ratio.si]]</a>
1401
 
1402
- For each of the *typedef-name*s `yocto`, `zepto`, `zetta`, and `yotta`,
1403
- if both of the constants used in its specification are representable by
1404
- `intmax_t`, the typedef is defined; if either of the constants is not
1405
- representable by `intmax_t`, the typedef is not defined.
 
1406
 
1407
  <!-- Link reference definitions -->
1408
  [array]: containers.md#array
 
1409
  [basic.compound]: basic.md#basic.compound
1410
  [basic.fundamental]: basic.md#basic.fundamental
 
 
 
 
 
 
 
1411
  [basic.type.qualifier]: basic.md#basic.type.qualifier
1412
  [basic.types]: basic.md#basic.types
1413
  [basic.types.general]: basic.md#basic.types.general
1414
  [class.abstract]: class.md#class.abstract
1415
- [class.derived]: class.md#class.derived
 
1416
  [class.dtor]: class.md#class.dtor
 
1417
  [class.mem]: class.md#class.mem
 
1418
  [class.pre]: class.md#class.pre
1419
  [class.prop]: class.md#class.prop
1420
  [class.temporary]: basic.md#class.temporary
 
1421
  [class.virtual]: class.md#class.virtual
 
 
1422
  [conv.rank]: basic.md#conv.rank
1423
  [dcl.array]: dcl.md#dcl.array
1424
  [dcl.enum]: dcl.md#dcl.enum
 
 
 
 
1425
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
 
 
1426
  [dcl.ref]: dcl.md#dcl.ref
 
1427
  [declval]: utilities.md#declval
1428
  [defns.referenceable]: intro.md#defns.referenceable
 
 
1429
  [expr.alignof]: expr.md#expr.alignof
 
 
 
 
1430
  [expr.type]: expr.md#expr.type
1431
  [expr.unary.noexcept]: expr.md#expr.unary.noexcept
1432
- [func.require]: utilities.md#func.require
1433
  [functional.syn]: utilities.md#functional.syn
 
 
1434
  [intseq]: #intseq
1435
  [intseq.general]: #intseq.general
1436
  [intseq.intseq]: #intseq.intseq
1437
  [intseq.make]: #intseq.make
 
 
 
1438
  [meta]: #meta
1439
  [meta.const.eval]: #meta.const.eval
 
1440
  [meta.general]: #meta.general
1441
  [meta.help]: #meta.help
1442
  [meta.logical]: #meta.logical
1443
  [meta.member]: #meta.member
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1444
  [meta.rel]: #meta.rel
1445
  [meta.rqmts]: #meta.rqmts
 
1446
  [meta.summary]: #meta.summary
 
1447
  [meta.trans]: #meta.trans
1448
  [meta.trans.arr]: #meta.trans.arr
1449
  [meta.trans.cv]: #meta.trans.cv
1450
  [meta.trans.general]: #meta.trans.general
1451
  [meta.trans.other]: #meta.trans.other
@@ -1458,10 +4732,13 @@ representable by `intmax_t`, the typedef is not defined.
1458
  [meta.unary.comp]: #meta.unary.comp
1459
  [meta.unary.general]: #meta.unary.general
1460
  [meta.unary.prop]: #meta.unary.prop
1461
  [meta.unary.prop.query]: #meta.unary.prop.query
1462
  [namespace.std]: library.md#namespace.std
 
 
 
1463
  [ratio]: #ratio
1464
  [ratio.arithmetic]: #ratio.arithmetic
1465
  [ratio.comparison]: #ratio.comparison
1466
  [ratio.general]: #ratio.general
1467
  [ratio.ratio]: #ratio.ratio
@@ -1469,16 +4746,25 @@ representable by `intmax_t`, the typedef is not defined.
1469
  [ratio.syn]: #ratio.syn
1470
  [special]: class.md#special
1471
  [stmt.return]: stmt.md#stmt.return
1472
  [support.signal]: support.md#support.signal
1473
  [swappable.requirements]: library.md#swappable.requirements
1474
- [term.layout.compatible.type]: basic.md#term.layout.compatible.type
 
 
 
 
 
 
 
 
 
1475
  [term.object.type]: basic.md#term.object.type
1476
  [term.odr.use]: basic.md#term.odr.use
1477
  [term.scalar.type]: basic.md#term.scalar.type
1478
  [term.standard.layout.type]: basic.md#term.standard.layout.type
1479
- [term.trivial.type]: basic.md#term.trivial.type
1480
  [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
1481
  [term.unevaluated.operand]: expr.md#term.unevaluated.operand
1482
  [tuple.apply]: utilities.md#tuple.apply
1483
  [type.traits]: #type.traits
1484
  [type.traits.general]: #type.traits.general
 
6
  summarized in [[meta.summary]].
7
 
8
  **Table: Metaprogramming library summary** <a id="meta.summary">[meta.summary]</a>
9
 
10
  | Subclause | | Header |
11
+ | ------------------- | ------------------- | --------------- |
12
  | [[intseq]] | Integer sequences | `<utility>` |
13
  | [[type.traits]] | Type traits | `<type_traits>` |
14
+ | [[meta.reflection]] | Reflection | `<meta>` |
15
  | [[ratio]] | Rational arithmetic | `<ratio>` |
16
 
17
 
18
  ## Compile-time integer sequences <a id="intseq">[[intseq]]</a>
19
 
20
+ ### General <a id="intseq.general">[[intseq.general]]</a>
21
 
22
  The library provides a class template that can represent an integer
23
  sequence. When used as an argument to a function template the template
24
  parameter pack defining the sequence can be deduced and used in a pack
25
  expansion.
 
49
  ```
50
 
51
  *Mandates:* `N` ≥ 0.
52
 
53
  The alias template `make_integer_sequence` denotes a specialization of
54
+ `integer_sequence` with `N` constant template arguments. The type
55
  `make_integer_sequence<T, N>` is an alias for the type
56
+ `integer_sequence<T, 0, 1, `…`, N - 1>`.
57
 
58
  [*Note 1*: `make_integer_sequence<int, 0>` is an alias for the type
59
  `integer_sequence<int>`. — *end note*]
60
 
61
  ## Metaprogramming and type traits <a id="type.traits">[[type.traits]]</a>
 
113
  specializations for any of the templates specified in [[type.traits]] is
114
  undefined.
115
 
116
  Unless otherwise specified, an incomplete type may be used to
117
  instantiate a template specified in [[type.traits]]. The behavior of a
118
+ program is undefined if
119
 
120
  - an instantiation of a template specified in [[type.traits]] directly
121
  or indirectly depends on an incompletely-defined object type `T`, and
122
  - that instantiation could yield a different result were `T`
123
  hypothetically completed.
 
133
  template<bool B>
134
  using bool_constant = integral_constant<bool, B>;
135
  using true_type = bool_constant<true>;
136
  using false_type = bool_constant<false>;
137
 
138
+ // [const.wrap.class], class template constant_wrapper
139
+ template<class T>
140
+ struct cw-fixed-value; // exposition only
141
+
142
+ template<cw-fixed-value X, class = typename decltype(X)::type>
143
+ struct constant_wrapper;
144
+
145
+ template<class T>
146
+ concept constexpr-param = // exposition only
147
+ requires { typename constant_wrapper<T::value>; };
148
+
149
+ struct cw-operators; // exposition only
150
+
151
+ template<cw-fixed-value X>
152
+ constexpr auto cw = constant_wrapper<X>{};
153
+
154
  // [meta.unary.cat], primary type categories
155
  template<class T> struct is_void;
156
  template<class T> struct is_null_pointer;
157
  template<class T> struct is_integral;
158
  template<class T> struct is_floating_point;
 
164
  template<class T> struct is_member_function_pointer;
165
  template<class T> struct is_enum;
166
  template<class T> struct is_union;
167
  template<class T> struct is_class;
168
  template<class T> struct is_function;
169
+ template<class T> struct is_reflection;
170
 
171
  // [meta.unary.comp], composite type categories
172
  template<class T> struct is_reference;
173
  template<class T> struct is_arithmetic;
174
  template<class T> struct is_fundamental;
 
178
  template<class T> struct is_member_pointer;
179
 
180
  // [meta.unary.prop], type properties
181
  template<class T> struct is_const;
182
  template<class T> struct is_volatile;
 
183
  template<class T> struct is_trivially_copyable;
184
+ template<class T> struct is_trivially_relocatable;
185
+ template<class T> struct is_replaceable;
186
  template<class T> struct is_standard_layout;
187
  template<class T> struct is_empty;
188
  template<class T> struct is_polymorphic;
189
  template<class T> struct is_abstract;
190
  template<class T> struct is_final;
191
  template<class T> struct is_aggregate;
192
+ template<class T> struct is_consteval_only;
193
 
194
  template<class T> struct is_signed;
195
  template<class T> struct is_unsigned;
196
  template<class T> struct is_bounded_array;
197
  template<class T> struct is_unbounded_array;
 
232
 
233
  template<class T, class U> struct is_nothrow_swappable_with;
234
  template<class T> struct is_nothrow_swappable;
235
 
236
  template<class T> struct is_nothrow_destructible;
237
+ template<class T> struct is_nothrow_relocatable;
238
 
239
  template<class T> struct is_implicit_lifetime;
240
 
241
  template<class T> struct has_virtual_destructor;
242
 
 
251
  template<class T, unsigned I = 0> struct extent;
252
 
253
  // [meta.rel], type relations
254
  template<class T, class U> struct is_same;
255
  template<class Base, class Derived> struct is_base_of;
256
+ template<class Base, class Derived> struct is_virtual_base_of;
257
  template<class From, class To> struct is_convertible;
258
  template<class From, class To> struct is_nothrow_convertible;
259
  template<class T, class U> struct is_layout_compatible;
260
  template<class Base, class Derived> struct is_pointer_interconvertible_base_of;
261
 
 
263
  template<class R, class Fn, class... ArgTypes> struct is_invocable_r;
264
 
265
  template<class Fn, class... ArgTypes> struct is_nothrow_invocable;
266
  template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
267
 
268
+ template<class Fn, class Tuple> struct is_applicable;
269
+ template<class Fn, class Tuple> struct is_nothrow_applicable;
270
+
271
  // [meta.trans.cv], const-volatile modifications
272
  template<class T> struct remove_const;
273
  template<class T> struct remove_volatile;
274
  template<class T> struct remove_cv;
275
  template<class T> struct add_const;
276
  template<class T> struct add_volatile;
277
  template<class T> struct add_cv;
278
 
279
  template<class T>
280
+ using remove_const_t = remove_const<T>::type;
281
  template<class T>
282
+ using remove_volatile_t = remove_volatile<T>::type;
283
  template<class T>
284
+ using remove_cv_t = remove_cv<T>::type;
285
  template<class T>
286
+ using add_const_t = add_const<T>::type;
287
  template<class T>
288
+ using add_volatile_t = add_volatile<T>::type;
289
  template<class T>
290
+ using add_cv_t = add_cv<T>::type;
291
 
292
  // [meta.trans.ref], reference modifications
293
  template<class T> struct remove_reference;
294
  template<class T> struct add_lvalue_reference;
295
  template<class T> struct add_rvalue_reference;
296
 
297
  template<class T>
298
+ using remove_reference_t = remove_reference<T>::type;
299
  template<class T>
300
+ using add_lvalue_reference_t = add_lvalue_reference<T>::type;
301
  template<class T>
302
+ using add_rvalue_reference_t = add_rvalue_reference<T>::type;
303
 
304
  // [meta.trans.sign], sign modifications
305
  template<class T> struct make_signed;
306
  template<class T> struct make_unsigned;
307
 
308
  template<class T>
309
+ using make_signed_t = make_signed<T>::type;
310
  template<class T>
311
+ using make_unsigned_t = make_unsigned<T>::type;
312
 
313
  // [meta.trans.arr], array modifications
314
  template<class T> struct remove_extent;
315
  template<class T> struct remove_all_extents;
316
 
317
  template<class T>
318
+ using remove_extent_t = remove_extent<T>::type;
319
  template<class T>
320
+ using remove_all_extents_t = remove_all_extents<T>::type;
321
 
322
  // [meta.trans.ptr], pointer modifications
323
  template<class T> struct remove_pointer;
324
  template<class T> struct add_pointer;
325
 
326
  template<class T>
327
+ using remove_pointer_t = remove_pointer<T>::type;
328
  template<class T>
329
+ using add_pointer_t = add_pointer<T>::type;
330
 
331
  // [meta.trans.other], other transformations
332
  template<class T> struct type_identity;
333
  template<class T> struct remove_cvref;
334
  template<class T> struct decay;
 
338
  template<class T, class U, template<class> class TQual, template<class> class UQual>
339
  struct basic_common_reference { };
340
  template<class... T> struct common_reference;
341
  template<class T> struct underlying_type;
342
  template<class Fn, class... ArgTypes> struct invoke_result;
343
+ template<class Fn, class Tuple> struct apply_result;
344
  template<class T> struct unwrap_reference;
345
  template<class T> struct unwrap_ref_decay;
346
 
347
  template<class T>
348
+ using type_identity_t = type_identity<T>::type;
349
  template<class T>
350
+ using remove_cvref_t = remove_cvref<T>::type;
351
  template<class T>
352
+ using decay_t = decay<T>::type;
353
  template<bool B, class T = void>
354
+ using enable_if_t = enable_if<B, T>::type;
355
  template<bool B, class T, class F>
356
+ using conditional_t = conditional<B, T, F>::type;
357
  template<class... T>
358
+ using common_type_t = common_type<T...>::type;
359
  template<class... T>
360
+ using common_reference_t = common_reference<T...>::type;
361
  template<class T>
362
+ using underlying_type_t = underlying_type<T>::type;
363
  template<class Fn, class... ArgTypes>
364
+ using invoke_result_t = invoke_result<Fn, ArgTypes...>::type;
365
+ template<class Fn, class Tuple>
366
+ using apply_result_t = apply_result<Fn, Tuple>::type;
367
  template<class T>
368
+ using unwrap_reference_t = unwrap_reference<T>::type;
369
  template<class T>
370
+ using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;
371
  template<class...>
372
  using void_t = void;
373
 
374
  // [meta.logical], logical operator traits
375
  template<class... B> struct conjunction;
 
403
  constexpr bool is_union_v = is_union<T>::value;
404
  template<class T>
405
  constexpr bool is_class_v = is_class<T>::value;
406
  template<class T>
407
  constexpr bool is_function_v = is_function<T>::value;
408
+ template<class T>
409
+ constexpr bool is_reflection_v = is_reflection<T>::value;
410
 
411
  // [meta.unary.comp], composite type categories
412
  template<class T>
413
  constexpr bool is_reference_v = is_reference<T>::value;
414
  template<class T>
 
427
  // [meta.unary.prop], type properties
428
  template<class T>
429
  constexpr bool is_const_v = is_const<T>::value;
430
  template<class T>
431
  constexpr bool is_volatile_v = is_volatile<T>::value;
 
 
432
  template<class T>
433
  constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
434
+ template<class T>
435
+ constexpr bool is_trivially_relocatable_v = is_trivially_relocatable<T>::value;
436
  template<class T>
437
  constexpr bool is_standard_layout_v = is_standard_layout<T>::value;
438
  template<class T>
439
  constexpr bool is_empty_v = is_empty<T>::value;
440
  template<class T>
 
443
  constexpr bool is_abstract_v = is_abstract<T>::value;
444
  template<class T>
445
  constexpr bool is_final_v = is_final<T>::value;
446
  template<class T>
447
  constexpr bool is_aggregate_v = is_aggregate<T>::value;
448
+ template<class T>
449
+ constexpr bool is_consteval_only_v = is_consteval_only<T>::value;
450
  template<class T>
451
  constexpr bool is_signed_v = is_signed<T>::value;
452
  template<class T>
453
  constexpr bool is_unsigned_v = is_unsigned<T>::value;
454
  template<class T>
 
476
  template<class T>
477
  constexpr bool is_swappable_v = is_swappable<T>::value;
478
  template<class T>
479
  constexpr bool is_destructible_v = is_destructible<T>::value;
480
  template<class T, class... Args>
481
+ constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value;
 
482
  template<class T>
483
  constexpr bool is_trivially_default_constructible_v
484
  = is_trivially_default_constructible<T>::value;
485
  template<class T>
486
+ constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value;
 
487
  template<class T>
488
+ constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value;
 
489
  template<class T, class U>
490
  constexpr bool is_trivially_assignable_v = is_trivially_assignable<T, U>::value;
491
  template<class T>
492
+ constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<T>::value;
 
493
  template<class T>
494
+ constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<T>::value;
 
495
  template<class T>
496
  constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
497
  template<class T, class... Args>
498
+ constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value;
 
499
  template<class T>
500
  constexpr bool is_nothrow_default_constructible_v
501
  = is_nothrow_default_constructible<T>::value;
502
  template<class T>
503
+ constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value;
 
504
  template<class T>
505
+ constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value;
 
506
  template<class T, class U>
507
  constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<T, U>::value;
508
  template<class T>
509
  constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value;
510
  template<class T>
 
513
  constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<T, U>::value;
514
  template<class T>
515
  constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value;
516
  template<class T>
517
  constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value;
518
+ template<class T>
519
+ constexpr bool is_nothrow_relocatable_v = is_nothrow_relocatable<T>::value;
520
  template<class T>
521
  constexpr bool is_implicit_lifetime_v = is_implicit_lifetime<T>::value;
522
+ template<class T>
523
+ constexpr bool is_replaceable_v = is_replaceable<T>::value;
524
  template<class T>
525
  constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
526
  template<class T>
527
  constexpr bool has_unique_object_representations_v
528
  = has_unique_object_representations<T>::value;
 
544
  // [meta.rel], type relations
545
  template<class T, class U>
546
  constexpr bool is_same_v = is_same<T, U>::value;
547
  template<class Base, class Derived>
548
  constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
549
+ template<class Base, class Derived>
550
+ constexpr bool is_virtual_base_of_v = is_virtual_base_of<Base, Derived>::value;
551
  template<class From, class To>
552
  constexpr bool is_convertible_v = is_convertible<From, To>::value;
553
  template<class From, class To>
554
  constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
555
  template<class T, class U>
 
562
  template<class R, class Fn, class... ArgTypes>
563
  constexpr bool is_invocable_r_v = is_invocable_r<R, Fn, ArgTypes...>::value;
564
  template<class Fn, class... ArgTypes>
565
  constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<Fn, ArgTypes...>::value;
566
  template<class R, class Fn, class... ArgTypes>
567
+ constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
568
+ template<class Fn, class Tuple>
569
+ constexpr bool is_applicable_v = is_applicable<Fn, Tuple>::value;
570
+ template<class Fn, class Tuple>
571
+ constexpr bool is_nothrow_applicable_v = is_nothrow_applicable<Fn, Tuple>::value;
572
 
573
  // [meta.logical], logical operator traits
574
  template<class... B>
575
  constexpr bool conjunction_v = conjunction<B...>::value;
576
  template<class... B>
 
584
  template<class S1, class S2, class M1, class M2>
585
  constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
586
 
587
  // [meta.const.eval], constant evaluation context
588
  constexpr bool is_constant_evaluated() noexcept;
589
+ consteval bool is_within_lifetime(const auto*) noexcept;
590
  }
591
  ```
592
 
593
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
594
 
 
608
 
609
  The class template `integral_constant`, alias template `bool_constant`,
610
  and its associated *typedef-name*s `true_type` and `false_type` are used
611
  as base classes to define the interface for various type traits.
612
 
613
+ ### Class template `constant_wrapper` <a id="const.wrap.class">[[const.wrap.class]]</a>
614
+
615
+ ``` cpp
616
+ namespace std {
617
+ template<class T>
618
+ struct cw-fixed-value { // exposition only
619
+ using type = T; // exposition only
620
+ constexpr cw-fixed-value(type v) noexcept : data(v) {}
621
+ T data; // exposition only
622
+ };
623
+
624
+ template<class T, size_t Extent>
625
+ struct cw-fixed-value<T[Extent]> { // exposition only
626
+ using type = T[Extent]; // exposition only
627
+ constexpr cw-fixed-value(T (&arr)[Extent]) noexcept;
628
+ T data[Extent]; // exposition only
629
+ };
630
+
631
+ template<class T, size_t Extent>
632
+ cw-fixed-value(T (&)[Extent]) -> cw-fixed-value<T[Extent]>; // exposition only
633
+
634
+ struct cw-operators { // exposition only
635
+ // unary operators
636
+ template<constexpr-param T>
637
+ friend constexpr auto operator+(T) noexcept -> constant_wrapper<(+T::value)>
638
+ { return {}; }
639
+ template<constexpr-param T>
640
+ friend constexpr auto operator-(T) noexcept -> constant_wrapper<(-T::value)>
641
+ { return {}; }
642
+ template<constexpr-param T>
643
+ friend constexpr auto operator~(T) noexcept -> constant_wrapper<(~T::value)>
644
+ { return {}; }
645
+ template<constexpr-param T>
646
+ friend constexpr auto operator!(T) noexcept -> constant_wrapper<(!T::value)>
647
+ { return {}; }
648
+ template<constexpr-param T>
649
+ friend constexpr auto operator&(T) noexcept -> constant_wrapper<(&T::value)>
650
+ { return {}; }
651
+ template<constexpr-param T>
652
+ friend constexpr auto operator*(T) noexcept -> constant_wrapper<(*T::value)>
653
+ { return {}; }
654
+
655
+ // binary operators
656
+ template<constexpr-param L, constexpr-param R>
657
+ friend constexpr auto operator+(L, R) noexcept -> constant_wrapper<(L::value + R::value)>
658
+ { return {}; }
659
+ template<constexpr-param L, constexpr-param R>
660
+ friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)>
661
+ { return {}; }
662
+ template<constexpr-param L, constexpr-param R>
663
+ friend constexpr auto operator*(L, R) noexcept -> constant_wrapper<(L::value * R::value)>
664
+ { return {}; }
665
+ template<constexpr-param L, constexpr-param R>
666
+ friend constexpr auto operator/(L, R) noexcept -> constant_wrapper<(L::value / R::value)>
667
+ { return {}; }
668
+ template<constexpr-param L, constexpr-param R>
669
+ friend constexpr auto operator%(L, R) noexcept -> constant_wrapper<(L::value % R::value)>
670
+ { return {}; }
671
+
672
+ template<constexpr-param L, constexpr-param R>
673
+ friend constexpr auto operator<<(L, R) noexcept -> constant_wrapper<(L::value << R::value)>
674
+ { return {}; }
675
+ template<constexpr-param L, constexpr-param R>
676
+ friend constexpr auto operator>>(L, R) noexcept -> constant_wrapper<(L::value >> R::value)>
677
+ { return {}; }
678
+ template<constexpr-param L, constexpr-param R>
679
+ friend constexpr auto operator&(L, R) noexcept -> constant_wrapper<(L::value & R::value)>
680
+ { return {}; }
681
+ template<constexpr-param L, constexpr-param R>
682
+ friend constexpr auto operator|(L, R) noexcept -> constant_wrapper<(L::value | R::value)>
683
+ { return {}; }
684
+ template<constexpr-param L, constexpr-param R>
685
+ friend constexpr auto operator^(L, R) noexcept -> constant_wrapper<(L::value ^ R::value)>
686
+ { return {}; }
687
+
688
+ template<constexpr-param L, constexpr-param R>
689
+ requires (!is_constructible_v<bool, decltype(L::value)> ||
690
+ !is_constructible_v<bool, decltype(R::value)>)
691
+ friend constexpr auto operator&&(L, R) noexcept
692
+ -> constant_wrapper<(L::value && R::value)>
693
+ { return {}; }
694
+ template<constexpr-param L, constexpr-param R>
695
+ requires (!is_constructible_v<bool, decltype(L::value)> ||
696
+ !is_constructible_v<bool, decltype(R::value)>)
697
+ friend constexpr auto operator||(L, R) noexcept
698
+ -> constant_wrapper<(L::value || R::value)>
699
+ { return {}; }
700
+
701
+ // comparisons
702
+ template<constexpr-param L, constexpr-param R>
703
+ friend constexpr auto operator<=>(L, R) noexcept
704
+ -> constant_wrapper<(L::value <=> R::value)>
705
+ { return {}; }
706
+ template<constexpr-param L, constexpr-param R>
707
+ friend constexpr auto operator<(L, R) noexcept -> constant_wrapper<(L::value < R::value)>
708
+ { return {}; }
709
+ template<constexpr-param L, constexpr-param R>
710
+ friend constexpr auto operator<=(L, R) noexcept -> constant_wrapper<(L::value <= R::value)>
711
+ { return {}; }
712
+ template<constexpr-param L, constexpr-param R>
713
+ friend constexpr auto operator==(L, R) noexcept -> constant_wrapper<(L::value == R::value)>
714
+ { return {}; }
715
+ template<constexpr-param L, constexpr-param R>
716
+ friend constexpr auto operator!=(L, R) noexcept -> constant_wrapper<(L::value != R::value)>
717
+ { return {}; }
718
+ template<constexpr-param L, constexpr-param R>
719
+ friend constexpr auto operator>(L, R) noexcept -> constant_wrapper<(L::value > R::value)>
720
+ { return {}; }
721
+ template<constexpr-param L, constexpr-param R>
722
+ friend constexpr auto operator>=(L, R) noexcept -> constant_wrapper<(L::value >= R::value)>
723
+ { return {}; }
724
+
725
+ template<constexpr-param L, constexpr-param R>
726
+ friend constexpr auto operator,(L, R) noexcept = delete;
727
+ template<constexpr-param L, constexpr-param R>
728
+ friend constexpr auto operator->*(L, R) noexcept -> constant_wrapper<L::value->*(R::value)>
729
+ { return {}; }
730
+
731
+ // call and index
732
+ template<constexpr-param T, constexpr-param... Args>
733
+ constexpr auto operator()(this T, Args...) noexcept
734
+ requires requires { constant_wrapper<T::value(Args::value...)>(); }
735
+ { return constant_wrapper<T::value(Args::value...)>{}; }
736
+ template<constexpr-param T, constexpr-param... Args>
737
+ constexpr auto operator[](this T, Args...) noexcept
738
+ -> constant_wrapper<(T::value[Args::value...])>
739
+ { return {}; }
740
+
741
+ // pseudo-mutators
742
+ template<constexpr-param T>
743
+ constexpr auto operator++(this T) noexcept
744
+ requires requires(T::value_type x) { ++x; }
745
+ { return constant_wrapper<[] { auto c = T::value; return ++c; }()>{}; }
746
+ template<constexpr-param T>
747
+ constexpr auto operator++(this T, int) noexcept
748
+ requires requires(T::value_type x) { x++; }
749
+ { return constant_wrapper<[] { auto c = T::value; return c++; }()>{}; }
750
+
751
+ template<constexpr-param T>
752
+ constexpr auto operator--(this T) noexcept
753
+ requires requires(T::value_type x) { --x; }
754
+ { return constant_wrapper<[] { auto c = T::value; return --c; }()>{}; }
755
+ template<constexpr-param T>
756
+ constexpr auto operator--(this T, int) noexcept
757
+ requires requires(T::value_type x) { x--; }
758
+ { return constant_wrapper<[] { auto c = T::value; return c--; }()>{}; }
759
+
760
+ template<constexpr-param T, constexpr-param R>
761
+ constexpr auto operator+=(this T, R) noexcept
762
+ requires requires(T::value_type x) { x += R::value; }
763
+ { return constant_wrapper<[] { auto v = T::value; return v += R::value; }()>{}; }
764
+ template<constexpr-param T, constexpr-param R>
765
+ constexpr auto operator-=(this T, R) noexcept
766
+ requires requires(T::value_type x) { x -= R::value; }
767
+ { return constant_wrapper<[] { auto v = T::value; return v -= R::value; }()>{}; }
768
+ template<constexpr-param T, constexpr-param R>
769
+ constexpr auto operator*=(this T, R) noexcept
770
+ requires requires(T::value_type x) { x *= R::value; }
771
+ { return constant_wrapper<[] { auto v = T::value; return v *= R::value; }()>{}; }
772
+ template<constexpr-param T, constexpr-param R>
773
+ constexpr auto operator/=(this T, R) noexcept
774
+ requires requires(T::value_type x) { x /= R::value; }
775
+ { return constant_wrapper<[] { auto v = T::value; return v /= R::value; }()>{}; }
776
+ template<constexpr-param T, constexpr-param R>
777
+ constexpr auto operator%=(this T, R) noexcept
778
+ requires requires(T::value_type x) { x %= R::value; }
779
+ { return constant_wrapper<[] { auto v = T::value; return v %= R::value; }()>{}; }
780
+ template<constexpr-param T, constexpr-param R>
781
+ constexpr auto operator&=(this T, R) noexcept
782
+ requires requires(T::value_type x) { x &= R::value; }
783
+ { return constant_wrapper<[] { auto v = T::value; return v &= R::value; }()>{}; }
784
+ template<constexpr-param T, constexpr-param R>
785
+ constexpr auto operator|=(this T, R) noexcept
786
+ requires requires(T::value_type x) { x |= R::value; }
787
+ { return constant_wrapper<[] { auto v = T::value; return v |= R::value; }()>{}; }
788
+ template<constexpr-param T, constexpr-param R>
789
+ constexpr auto operator^=(this T, R) noexcept
790
+ requires requires(T::value_type x) { x ^= R::value; }
791
+ { return constant_wrapper<[] { auto v = T::value; return v ^= R::value; }()>{}; }
792
+ template<constexpr-param T, constexpr-param R>
793
+ constexpr auto operator<<=(this T, R) noexcept
794
+ requires requires(T::value_type x) { x <<= R::value; }
795
+ { return constant_wrapper<[] { auto v = T::value; return v <<= R::value; }()>{}; }
796
+ template<constexpr-param T, constexpr-param R>
797
+ constexpr auto operator>>=(this T, R) noexcept
798
+ requires requires(T::value_type x) { x >>= R::value; }
799
+ { return constant_wrapper<[] { auto v = T::value; return v >>= R::value; }()>{}; }
800
+ };
801
+
802
+ template<cw-fixed-value X, class>
803
+ struct constant_wrapper : cw-operators {
804
+ static constexpr const auto & value = X.data;
805
+ using type = constant_wrapper;
806
+ using value_type = decltype(X)::type;
807
+
808
+ template<constexpr-param R>
809
+ constexpr auto operator=(R) const noexcept
810
+ requires requires(value_type x) { x = R::value; }
811
+ { return constant_wrapper<[] { auto v = value; return v = R::value; }()>{}; }
812
+
813
+ constexpr operator decltype(auto)() const noexcept { return value; }
814
+ };
815
+ }
816
+ ```
817
+
818
+ The class template `constant_wrapper` aids in metaprogramming by
819
+ ensuring that the evaluation of expressions comprised entirely of
820
+ `constant_wrapper` are core constant expressions [[expr.const]],
821
+ regardless of the context in which they appear. In particular, this
822
+ enables use of `constant_wrapper` values that are passed as arguments to
823
+ constexpr functions to be used in constant expressions.
824
+
825
+ [*Note 1*: The unnamed second template parameter to `constant_wrapper`
826
+ is present to aid argument-dependent lookup [[basic.lookup.argdep]] in
827
+ finding overloads for which `constant_wrapper`’s wrapped value is a
828
+ suitable argument, but for which the `constant_wrapper` itself is
829
+ not. — *end note*]
830
+
831
+ [*Example 1*:
832
+
833
+ ``` cpp
834
+ constexpr auto initial_phase(auto quantity_1, auto quantity_2) {
835
+ return quantity_1 + quantity_2;
836
+ }
837
+
838
+ constexpr auto middle_phase(auto tbd) {
839
+ return tbd;
840
+ }
841
+
842
+ void final_phase(auto gathered, auto available) {
843
+ if constexpr (gathered == available)
844
+ std::cout << "Profit!\n";
845
+ }
846
+
847
+ void impeccable_underground_planning() {
848
+ auto gathered_quantity = middle_phase(initial_phase(std::cw<42>, std::cw<13>));
849
+ static_assert(gathered_quantity == 55);
850
+ auto all_available = std::cw<55>;
851
+ final_phase(gathered_quantity, all_available);
852
+ }
853
+
854
+ void deeply_flawed_underground_planning() {
855
+ constexpr auto gathered_quantity = middle_phase(initial_phase(42, 13));
856
+ constexpr auto all_available = 55;
857
+ final_phase(gathered_quantity, all_available); // error: gathered == available
858
+ // is not a constant expression
859
+ }
860
+ ```
861
+
862
+ — *end example*]
863
+
864
+ ``` cpp
865
+ constexpr cw-fixed-value(T (&arr)[Extent]) noexcept;
866
+ ```
867
+
868
+ *Effects:* Initialize elements of *data* with corresponding elements of
869
+ `arr`.
870
+
871
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
872
 
873
  #### General <a id="meta.unary.general">[[meta.unary.general]]</a>
874
 
875
  Subclause [[meta.unary]] contains templates that may be used to query
 
879
  with a base characteristic of `true_type` if the corresponding condition
880
  is `true`, otherwise `false_type`.
881
 
882
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
883
 
884
+ The primary type categories specified in [[meta.unary.cat]] correspond
885
+ to the descriptions given in subclause  [[basic.types]] of the C++
886
+ standard.
887
 
888
  For any given type `T`, the result of applying one of these templates to
889
  `T` and to cv `T` shall yield the same result.
890
 
891
  [*Note 1*: For any given type `T`, exactly one of the primary type
892
  categories has a `value` member that evaluates to `true`. — *end note*]
893
 
894
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
895
 
896
+ The templates specified in [[meta.unary.comp]] provide convenient
897
+ compositions of the primary type categories, corresponding to the
898
+ descriptions given in subclause  [[basic.types]].
899
 
900
  For any given type `T`, the result of applying one of these templates to
901
  `T` and to cv `T` shall yield the same result.
902
 
903
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
904
 
905
+ The templates specified in [[meta.unary.prop]] provide access to some of
906
+ the more important properties of types.
907
 
908
  It is unspecified whether the library defines any full or partial
909
  specializations of any of these templates.
910
 
911
  For all of the class templates `X` declared in this subclause,
 
991
  function template specializations, the generation of implicitly-defined
992
  functions, and so on. Such side effects are not in the “immediate
993
  context” and can result in the program being ill-formed. — *end note*]
994
 
995
  The predicate condition for a template specialization
996
+ `has_unique_object_representations<T>` shall be satisfied if and only if
 
997
 
998
  - `T` is trivially copyable, and
999
  - any two objects of type `T` with the same value have the same object
1000
+ representation, where
1001
+ - two objects of array or non-union class type are considered to have
1002
+ the same value if their respective sequences of direct subobjects
1003
+ have the same values, and
1004
+ - two objects of union type are considered to have the same value if
1005
+ they have the same active member and the corresponding members have
1006
+ the same value.
1007
 
1008
  The set of scalar types for which this condition holds is
1009
  *implementation-defined*.
1010
 
1011
  [*Note 4*: If a type has padding bits, the condition does not hold;
1012
  otherwise, the condition holds true for integral types. — *end note*]
1013
 
1014
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
1015
 
1016
+ The templates specified in [[meta.unary.prop.query]] may be used to
1017
+ query properties of types at compile time.
1018
 
1019
  Each of these templates shall be a *Cpp17UnaryTypeTrait* [[meta.rqmts]]
1020
  with a base characteristic of `integral_constant<size_t, Value>`.
1021
 
1022
  [*Example 1*:
1023
 
1024
  ``` cpp
1025
  // the following assertions hold:
1026
+ static_assert(rank_v<int> == 0);
1027
+ static_assert(rank_v<int[2]> == 1);
1028
+ static_assert(rank_v<int[][4]> == 2);
1029
  ```
1030
 
1031
  — *end example*]
1032
 
1033
  [*Example 2*:
1034
 
1035
  ``` cpp
1036
  // the following assertions hold:
1037
+ static_assert(extent_v<int> == 0);
1038
+ static_assert(extent_v<int[2]> == 2);
1039
+ static_assert(extent_v<int[2][4]> == 2);
1040
+ static_assert(extent_v<int[][4]> == 0);
1041
+ static_assert(extent_v<int, 1> == 0);
1042
+ static_assert(extent_v<int[2], 1> == 0);
1043
+ static_assert(extent_v<int[2][4], 1> == 4);
1044
+ static_assert(extent_v<int[][4], 1> == 4);
1045
  ```
1046
 
1047
  — *end example*]
1048
 
1049
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
1050
 
1051
+ The templates specified in [[meta.rel]] may be used to query
1052
  relationships between types at compile time.
1053
 
1054
  Each of these templates shall be a *Cpp17BinaryTypeTrait* [[meta.rqmts]]
1055
  with a base characteristic of `true_type` if the corresponding condition
1056
  is true, otherwise `false_type`.
1057
 
1058
+ Let `ELEMS-OF(T)` be the parameter pack `get<N>(declval<T>())`, where
1059
+ *`N`* is the pack of `size_t` template arguments of the specialization
1060
+ of `index_sequence` denoted by
1061
+ `make_index_sequence<tuple_size_v<remove_reference_t<T>>>`.
1062
+
1063
+ [*Note 1*: Virtual base classes that are private, protected, or
1064
+ ambiguous are, nonetheless, virtual base classes. — *end note*]
1065
+
1066
  For the purpose of defining the templates in this subclause, a function
1067
  call expression `declval<T>()` for any type `T` is considered to be a
1068
  trivial [[term.trivial.type]], [[special]] function call that is not an
1069
  odr-use [[term.odr.use]] of `declval` in the context of the
1070
  corresponding definition notwithstanding the restrictions of 
 
1099
  To test() {
1100
  return declval<From>();
1101
  }
1102
  ```
1103
 
1104
+ [*Note 2*: This requirement gives well-defined results for reference
1105
  types, array types, function types, and cv `void`. — *end note*]
1106
 
1107
  Access checking is performed in a context unrelated to `To` and `From`.
1108
  Only the validity of the immediate context of the *expression* of the
1109
  `return` statement [[stmt.return]] (including initialization of the
1110
  returned object or reference) is considered.
1111
 
1112
+ [*Note 3*: The initialization can result in side effects such as the
1113
  instantiation of class template specializations and function template
1114
  specializations, the generation of implicitly-defined functions, and so
1115
  on. Such side effects are not in the “immediate context” and can result
1116
  in the program being ill-formed. — *end note*]
1117
 
 
1125
  Each of the templates in [[meta.trans]] shall be a
1126
  *Cpp17TransformationTrait* [[meta.rqmts]].
1127
 
1128
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
1129
 
1130
+ The templates specified in [[meta.trans.cv]] add or remove
1131
+ cv-qualifications [[basic.type.qualifier]].
1132
+
1133
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
1134
 
1135
+ The templates specified in [[meta.trans.ref]] add or remove references.
1136
+
1137
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
1138
 
1139
+ The templates specified in [[meta.trans.sign]] convert an integer type
1140
+ to its corresponding signed or unsigned type.
1141
+
1142
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
1143
 
1144
+ The templates specified in [[meta.trans.arr]] modify array types.
1145
+
1146
  [*Example 1*:
1147
 
1148
  ``` cpp
1149
  // the following assertions hold:
1150
+ static_assert(is_same_v<remove_extent_t<int>, int>);
1151
+ static_assert(is_same_v<remove_extent_t<int[2]>, int>);
1152
+ static_assert(is_same_v<remove_extent_t<int[2][3]>, int[3]>);
1153
+ static_assert(is_same_v<remove_extent_t<int[][3]>, int[3]>);
1154
  ```
1155
 
1156
  — *end example*]
1157
 
1158
  [*Example 2*:
1159
 
1160
  ``` cpp
1161
  // the following assertions hold:
1162
+ static_assert(is_same_v<remove_all_extents_t<int>, int>);
1163
+ static_assert(is_same_v<remove_all_extents_t<int[2]>, int>);
1164
+ static_assert(is_same_v<remove_all_extents_t<int[2][3]>, int>);
1165
+ static_assert(is_same_v<remove_all_extents_t<int[][3]>, int>);
1166
  ```
1167
 
1168
  — *end example*]
1169
 
1170
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
1171
 
1172
+ The templates specified in [[meta.trans.ptr]] add or remove pointers.
1173
+
1174
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
1175
 
1176
+ The templates specified in [[meta.trans.other]] perform other
1177
+ modifications of a type.
1178
+
1179
  [*Note 1*: The compilation of the expression can result in side effects
1180
  such as the instantiation of class template specializations and function
1181
  template specializations, the generation of implicitly-defined
1182
  functions, and so on. Such side effects are not in the “immediate
1183
  context” and can result in the program being ill-formed. — *end note*]
 
1218
  - Otherwise, `COMMON-REF(A, B)` is ill-formed.
1219
 
1220
  If any of the types computed above is ill-formed, then
1221
  `COMMON-REF(A, B)` is ill-formed.
1222
 
1223
+ For the `common_type` trait applied to a template parameter pack `T` of
1224
+ types, the member `type` shall be either defined or not present as
1225
+ follows:
1226
 
1227
  - If `sizeof...(T)` is zero, there shall be no member `type`.
1228
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
1229
  the pack `T`. The member *typedef-name* `type` shall denote the same
1230
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
 
1255
  constituting `T`. Let `C` denote the same type, if any, as
1256
  `common_type_t<T1, T2>`. If there is such a type `C`, the member
1257
  *typedef-name* `type` shall denote the same type, if any, as
1258
  `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
1259
 
1260
+ Notwithstanding the provisions of [[meta.rqmts]], and pursuant to
1261
+ [[namespace.std]], a program may specialize `common_type<T1, T2>` for
1262
+ types `T1` and `T2` such that `is_same_v<T1, decay_t<T1>>` and
1263
+ `is_same_v<T2, decay_t<T2>>` are each `true`.
 
1264
 
1265
  [*Note 3*: Such specializations are needed when only explicit
1266
  conversions are desired between the template arguments. — *end note*]
1267
 
1268
  Such a specialization need not have a member named `type`, but if it
 
1270
  cv-unqualified non-reference type to which each of the types `T1` and
1271
  `T2` is explicitly convertible. Moreover, `common_type_t<T1, T2>` shall
1272
  denote the same type, if any, as does `common_type_t<T2, T1>`. No
1273
  diagnostic is required for a violation of this Note’s rules.
1274
 
1275
+ For the `common_reference` trait applied to a parameter pack `T` of
1276
+ types, the member `type` shall be either defined or not present as
1277
  follows:
1278
 
1279
  - If `sizeof...(T)` is zero, there shall be no member `type`.
1280
  - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
1281
  the pack `T`. The member typedef `type` shall denote the same type as
 
1301
  `common_reference_t<T1, T2>`. Then:
1302
  - If there is such a type `C`, the member typedef `type` shall denote
1303
  the same type, if any, as `common_reference_t<C, Rest...>`.
1304
  - Otherwise, there shall be no member `type`.
1305
 
1306
+ Notwithstanding the provisions of [[meta.rqmts]], and pursuant to
1307
+ [[namespace.std]], a program may partially specialize
1308
  `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
1309
  that `is_same_v<T, decay_t<T>>` and `is_same_v<U, decay_t<U>>` are each
1310
  `true`.
1311
 
1312
  [*Note 4*: Such specializations can be used to influence the result of
 
1476
  struct C: public A, public B { }; // not a standard-layout class
1477
 
1478
  static_assert( is_pointer_interconvertible_with_class( &C::b ) );
1479
  // Succeeds because, despite its appearance, &C::b has type
1480
  // ``pointer to member of B of type int''.
1481
+ static_assert( !is_pointer_interconvertible_with_class<C, int>( &C::b ) );
1482
+ // Forces the use of class C, and the result is false.
1483
 
1484
  static_assert( is_corresponding_member( &C::a, &C::b ) );
1485
  // Succeeds because, despite its appearance, &C::a and &C::b have types
1486
  // ``pointer to member of A of type int'' and
1487
  // ``pointer to member of B of type int'', respectively.
1488
+ static_assert( !is_corresponding_member<C, C, int, int>( &C::a, &C::b ) );
1489
+ // Forces the use of class C, and the result is false.
1490
  ```
1491
 
1492
  — *end example*]
1493
 
1494
  — *end note*]
 
1521
  }
1522
  ```
1523
 
1524
  — *end example*]
1525
 
1526
+ ``` cpp
1527
+ consteval bool is_within_lifetime(const auto* p) noexcept;
1528
+ ```
1529
+
1530
+ *Returns:* `true` if `p` is a pointer to an object that is within its
1531
+ lifetime [[basic.life]]; otherwise, `false`.
1532
+
1533
+ *Remarks:* During the evaluation of an expression `E` as a core constant
1534
+ expression, a call to this function is ill-formed unless `p` points to
1535
+ an object that is usable in constant expressions or whose complete
1536
+ object’s lifetime began within `E`.
1537
+
1538
+ [*Example 2*:
1539
+
1540
+ ``` cpp
1541
+ struct OptBool {
1542
+ union { bool b; char c; };
1543
+
1544
+ // note: this assumes common implementation properties for bool and char:
1545
+ // * sizeof(bool) == sizeof(char), and
1546
+ // * the value representations for true and false are distinct
1547
+ // from the value representation for 2
1548
+ constexpr OptBool() : c(2) { }
1549
+ constexpr OptBool(bool b) : b(b) { }
1550
+
1551
+ constexpr auto has_value() const -> bool {
1552
+ if consteval {
1553
+ return std::is_within_lifetime(&b); // during constant evaluation, cannot read from c
1554
+ } else {
1555
+ return c != 2; // during runtime, must read from c
1556
+ }
1557
+ }
1558
+
1559
+ constexpr auto operator*() const -> const bool& {
1560
+ return b;
1561
+ }
1562
+ };
1563
+
1564
+ constexpr OptBool disengaged;
1565
+ constexpr OptBool engaged(true);
1566
+ static_assert(!disengaged.has_value());
1567
+ static_assert(engaged.has_value());
1568
+ static_assert(*engaged);
1569
+ ```
1570
+
1571
+ — *end example*]
1572
+
1573
+ ## Reflection <a id="meta.reflection">[[meta.reflection]]</a>
1574
+
1575
+ ### Header `<meta>` synopsis <a id="meta.syn">[[meta.syn]]</a>
1576
+
1577
+ ``` cpp
1578
+ #include <initializer_list> // see [initializer.list.syn]
1579
+
1580
+ namespace std {
1581
+ // [meta.string.literal], checking string literals
1582
+ consteval bool is_string_literal(const char* p);
1583
+ consteval bool is_string_literal(const wchar_t* p);
1584
+ consteval bool is_string_literal(const char8_t* p);
1585
+ consteval bool is_string_literal(const char16_t* p);
1586
+ consteval bool is_string_literal(const char32_t* p);
1587
+
1588
+ // [meta.define.static], promoting to static storage
1589
+ namespace meta {
1590
+ template<ranges::input_range R>
1591
+ consteval info reflect_constant_string(R&& r);
1592
+ template<ranges::input_range R>
1593
+ consteval info reflect_constant_array(R&& r);
1594
+ }
1595
+ template<ranges::input_range R>
1596
+ consteval const ranges::range_value_t<R>* define_static_string(R&& r);
1597
+ template<ranges::input_range R>
1598
+ consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
1599
+ template<class T>
1600
+ consteval const remove_cvref_t<T>* define_static_object(T&& r);
1601
+ }
1602
+
1603
+ namespace std::meta {
1604
+ using info = decltype(^^::);
1605
+
1606
+ // [meta.reflection.exception], class exception
1607
+ class exception;
1608
+
1609
+ // [meta.reflection.operators], operator representations
1610
+ enum class operators {
1611
+ see below;
1612
+ };
1613
+ using enum operators;
1614
+ consteval operators operator_of(info r);
1615
+ consteval string_view symbol_of(operators op);
1616
+ consteval u8string_view u8symbol_of(operators op);
1617
+
1618
+ // [meta.reflection.names], reflection names and locations
1619
+ consteval bool has_identifier(info r);
1620
+
1621
+ consteval string_view identifier_of(info r);
1622
+ consteval u8string_view u8identifier_of(info r);
1623
+
1624
+ consteval string_view display_string_of(info r);
1625
+ consteval u8string_view u8display_string_of(info r);
1626
+
1627
+ consteval source_location source_location_of(info r);
1628
+
1629
+ // [meta.reflection.queries], reflection queries
1630
+ consteval info type_of(info r);
1631
+ consteval info object_of(info r);
1632
+ consteval info constant_of(info r);
1633
+
1634
+ consteval bool is_public(info r);
1635
+ consteval bool is_protected(info r);
1636
+ consteval bool is_private(info r);
1637
+
1638
+ consteval bool is_virtual(info r);
1639
+ consteval bool is_pure_virtual(info r);
1640
+ consteval bool is_override(info r);
1641
+ consteval bool is_final(info r);
1642
+
1643
+ consteval bool is_deleted(info r);
1644
+ consteval bool is_defaulted(info r);
1645
+ consteval bool is_user_provided(info r);
1646
+ consteval bool is_user_declared(info r);
1647
+ consteval bool is_explicit(info r);
1648
+ consteval bool is_noexcept(info r);
1649
+
1650
+ consteval bool is_bit_field(info r);
1651
+ consteval bool is_enumerator(info r);
1652
+ consteval bool is_annotation(info r);
1653
+
1654
+ consteval bool is_const(info r);
1655
+ consteval bool is_volatile(info r);
1656
+ consteval bool is_mutable_member(info r);
1657
+ consteval bool is_lvalue_reference_qualified(info r);
1658
+ consteval bool is_rvalue_reference_qualified(info r);
1659
+
1660
+ consteval bool has_static_storage_duration(info r);
1661
+ consteval bool has_thread_storage_duration(info r);
1662
+ consteval bool has_automatic_storage_duration(info r);
1663
+
1664
+ consteval bool has_internal_linkage(info r);
1665
+ consteval bool has_module_linkage(info r);
1666
+ consteval bool has_external_linkage(info r);
1667
+ consteval bool has_c_language_linkage(info r);
1668
+ consteval bool has_linkage(info r);
1669
+
1670
+ consteval bool is_complete_type(info r);
1671
+ consteval bool is_enumerable_type(info r);
1672
+
1673
+ consteval bool is_variable(info r);
1674
+ consteval bool is_type(info r);
1675
+ consteval bool is_namespace(info r);
1676
+ consteval bool is_type_alias(info r);
1677
+ consteval bool is_namespace_alias(info r);
1678
+
1679
+ consteval bool is_function(info r);
1680
+ consteval bool is_conversion_function(info r);
1681
+ consteval bool is_operator_function(info r);
1682
+ consteval bool is_literal_operator(info r);
1683
+ consteval bool is_special_member_function(info r);
1684
+ consteval bool is_constructor(info r);
1685
+ consteval bool is_default_constructor(info r);
1686
+ consteval bool is_copy_constructor(info r);
1687
+ consteval bool is_move_constructor(info r);
1688
+ consteval bool is_assignment(info r);
1689
+ consteval bool is_copy_assignment(info r);
1690
+ consteval bool is_move_assignment(info r);
1691
+ consteval bool is_destructor(info r);
1692
+
1693
+ consteval bool is_function_parameter(info r);
1694
+ consteval bool is_explicit_object_parameter(info r);
1695
+ consteval bool has_default_argument(info r);
1696
+ consteval bool has_ellipsis_parameter(info r);
1697
+
1698
+ consteval bool is_template(info r);
1699
+ consteval bool is_function_template(info r);
1700
+ consteval bool is_variable_template(info r);
1701
+ consteval bool is_class_template(info r);
1702
+ consteval bool is_alias_template(info r);
1703
+ consteval bool is_conversion_function_template(info r);
1704
+ consteval bool is_operator_function_template(info r);
1705
+ consteval bool is_literal_operator_template(info r);
1706
+ consteval bool is_constructor_template(info r);
1707
+ consteval bool is_concept(info r);
1708
+
1709
+ consteval bool is_value(info r);
1710
+ consteval bool is_object(info r);
1711
+
1712
+ consteval bool is_structured_binding(info r);
1713
+
1714
+ consteval bool is_class_member(info r);
1715
+ consteval bool is_namespace_member(info r);
1716
+ consteval bool is_nonstatic_data_member(info r);
1717
+ consteval bool is_static_member(info r);
1718
+ consteval bool is_base(info r);
1719
+
1720
+ consteval bool has_default_member_initializer(info r);
1721
+
1722
+ consteval bool has_parent(info r);
1723
+ consteval info parent_of(info r);
1724
+
1725
+ consteval info dealias(info r);
1726
+
1727
+ consteval bool has_template_arguments(info r);
1728
+ consteval info template_of(info r);
1729
+ consteval vector<info> template_arguments_of(info r);
1730
+ consteval vector<info> parameters_of(info r);
1731
+ consteval info variable_of(info r);
1732
+ consteval info return_type_of(info r);
1733
+
1734
+ // [meta.reflection.access.context], access control context
1735
+ struct access_context;
1736
+
1737
+ // [meta.reflection.access.queries], member accessibility queries
1738
+ consteval bool is_accessible(info r, access_context ctx);
1739
+ consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
1740
+ consteval bool has_inaccessible_bases(info r, access_context ctx);
1741
+ consteval bool has_inaccessible_subobjects(info r, access_context ctx);
1742
+
1743
+ // [meta.reflection.member.queries], reflection member queries
1744
+ consteval vector<info> members_of(info r, access_context ctx);
1745
+ consteval vector<info> bases_of(info type, access_context ctx);
1746
+ consteval vector<info> static_data_members_of(info type, access_context ctx);
1747
+ consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
1748
+ consteval vector<info> subobjects_of(info type, access_context ctx);
1749
+ consteval vector<info> enumerators_of(info type_enum);
1750
+
1751
+ // [meta.reflection.layout], reflection layout queries
1752
+ struct member_offset;
1753
+ consteval member_offset offset_of(info r);
1754
+ consteval size_t size_of(info r);
1755
+ consteval size_t alignment_of(info r);
1756
+ consteval size_t bit_size_of(info r);
1757
+
1758
+ // [meta.reflection.annotation], annotation reflection
1759
+ consteval vector<info> annotations_of(info item);
1760
+ consteval vector<info> annotations_of_with_type(info item, info type);
1761
+
1762
+ // [meta.reflection.extract], value extraction
1763
+ template<class T>
1764
+ consteval T extract(info);
1765
+
1766
+ // [meta.reflection.substitute], reflection substitution
1767
+ template<class R>
1768
+ concept reflection_range = see below;
1769
+
1770
+ template<reflection_range R = initializer_list<info>>
1771
+ consteval bool can_substitute(info templ, R&& arguments);
1772
+ template<reflection_range R = initializer_list<info>>
1773
+ consteval info substitute(info templ, R&& arguments);
1774
+
1775
+ // [meta.reflection.result], expression result reflection
1776
+ template<class T>
1777
+ consteval info reflect_constant(T expr);
1778
+ template<class T>
1779
+ consteval info reflect_object(T& expr);
1780
+ template<class T>
1781
+ consteval info reflect_function(T& fn);
1782
+
1783
+ // [meta.reflection.define.aggregate], class definition generation
1784
+ struct data_member_options;
1785
+ consteval info data_member_spec(info type, data_member_options options);
1786
+ consteval bool is_data_member_spec(info r);
1787
+ template<reflection_range R = initializer_list<info>>
1788
+ consteval info define_aggregate(info type_class, R&&);
1789
+
1790
+ // associated with [meta.unary.cat], primary type categories
1791
+ consteval bool is_void_type(info type);
1792
+ consteval bool is_null_pointer_type(info type);
1793
+ consteval bool is_integral_type(info type);
1794
+ consteval bool is_floating_point_type(info type);
1795
+ consteval bool is_array_type(info type);
1796
+ consteval bool is_pointer_type(info type);
1797
+ consteval bool is_lvalue_reference_type(info type);
1798
+ consteval bool is_rvalue_reference_type(info type);
1799
+ consteval bool is_member_object_pointer_type(info type);
1800
+ consteval bool is_member_function_pointer_type(info type);
1801
+ consteval bool is_enum_type(info type);
1802
+ consteval bool is_union_type(info type);
1803
+ consteval bool is_class_type(info type);
1804
+ consteval bool is_function_type(info type);
1805
+ consteval bool is_reflection_type(info type);
1806
+
1807
+ // associated with [meta.unary.comp], composite type categories
1808
+ consteval bool is_reference_type(info type);
1809
+ consteval bool is_arithmetic_type(info type);
1810
+ consteval bool is_fundamental_type(info type);
1811
+ consteval bool is_object_type(info type);
1812
+ consteval bool is_scalar_type(info type);
1813
+ consteval bool is_compound_type(info type);
1814
+ consteval bool is_member_pointer_type(info type);
1815
+
1816
+ // associated with [meta.unary.prop], type properties
1817
+ consteval bool is_const_type(info type);
1818
+ consteval bool is_volatile_type(info type);
1819
+ consteval bool is_trivially_copyable_type(info type);
1820
+ consteval bool is_trivially_relocatable_type(info type);
1821
+ consteval bool is_replaceable_type(info type);
1822
+ consteval bool is_standard_layout_type(info type);
1823
+ consteval bool is_empty_type(info type);
1824
+ consteval bool is_polymorphic_type(info type);
1825
+ consteval bool is_abstract_type(info type);
1826
+ consteval bool is_final_type(info type);
1827
+ consteval bool is_aggregate_type(info type);
1828
+ consteval bool is_consteval_only_type(info type);
1829
+ consteval bool is_signed_type(info type);
1830
+ consteval bool is_unsigned_type(info type);
1831
+ consteval bool is_bounded_array_type(info type);
1832
+ consteval bool is_unbounded_array_type(info type);
1833
+ consteval bool is_scoped_enum_type(info type);
1834
+
1835
+ template<reflection_range R = initializer_list<info>>
1836
+ consteval bool is_constructible_type(info type, R&& type_args);
1837
+ consteval bool is_default_constructible_type(info type);
1838
+ consteval bool is_copy_constructible_type(info type);
1839
+ consteval bool is_move_constructible_type(info type);
1840
+
1841
+ consteval bool is_assignable_type(info type_dst, info type_src);
1842
+ consteval bool is_copy_assignable_type(info type);
1843
+ consteval bool is_move_assignable_type(info type);
1844
+
1845
+ consteval bool is_swappable_with_type(info type1, info type2);
1846
+ consteval bool is_swappable_type(info type);
1847
+
1848
+ consteval bool is_destructible_type(info type);
1849
+
1850
+ template<reflection_range R = initializer_list<info>>
1851
+ consteval bool is_trivially_constructible_type(info type, R&& type_args);
1852
+ consteval bool is_trivially_default_constructible_type(info type);
1853
+ consteval bool is_trivially_copy_constructible_type(info type);
1854
+ consteval bool is_trivially_move_constructible_type(info type);
1855
+
1856
+ consteval bool is_trivially_assignable_type(info type_dst, info type_src);
1857
+ consteval bool is_trivially_copy_assignable_type(info type);
1858
+ consteval bool is_trivially_move_assignable_type(info type);
1859
+ consteval bool is_trivially_destructible_type(info type);
1860
+
1861
+ template<reflection_range R = initializer_list<info>>
1862
+ consteval bool is_nothrow_constructible_type(info type, R&& type_args);
1863
+ consteval bool is_nothrow_default_constructible_type(info type);
1864
+ consteval bool is_nothrow_copy_constructible_type(info type);
1865
+ consteval bool is_nothrow_move_constructible_type(info type);
1866
+
1867
+ consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
1868
+ consteval bool is_nothrow_copy_assignable_type(info type);
1869
+ consteval bool is_nothrow_move_assignable_type(info type);
1870
+
1871
+ consteval bool is_nothrow_swappable_with_type(info type1, info type2);
1872
+ consteval bool is_nothrow_swappable_type(info type);
1873
+
1874
+ consteval bool is_nothrow_destructible_type(info type);
1875
+ consteval bool is_nothrow_relocatable_type(info type);
1876
+
1877
+ consteval bool is_implicit_lifetime_type(info type);
1878
+
1879
+ consteval bool has_virtual_destructor(info type);
1880
+
1881
+ consteval bool has_unique_object_representations(info type);
1882
+
1883
+ consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
1884
+ consteval bool reference_converts_from_temporary(info type_dst, info type_src);
1885
+
1886
+ // associated with [meta.unary.prop.query], type property queries
1887
+ consteval size_t rank(info type);
1888
+ consteval size_t extent(info type, unsigned i = 0);
1889
+
1890
+ // associated with [meta.rel], type relations
1891
+ consteval bool is_same_type(info type1, info type2);
1892
+ consteval bool is_base_of_type(info type_base, info type_derived);
1893
+ consteval bool is_virtual_base_of_type(info type_base, info type_derived);
1894
+ consteval bool is_convertible_type(info type_src, info type_dst);
1895
+ consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
1896
+ consteval bool is_layout_compatible_type(info type1, info type2);
1897
+ consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
1898
+
1899
+ template<reflection_range R = initializer_list<info>>
1900
+ consteval bool is_invocable_type(info type, R&& type_args);
1901
+ template<reflection_range R = initializer_list<info>>
1902
+ consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
1903
+
1904
+ template<reflection_range R = initializer_list<info>>
1905
+ consteval bool is_nothrow_invocable_type(info type, R&& type_args);
1906
+ template<reflection_range R = initializer_list<info>>
1907
+ consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
1908
+
1909
+ // associated with [meta.trans.cv], const-volatile modifications
1910
+ consteval info remove_const(info type);
1911
+ consteval info remove_volatile(info type);
1912
+ consteval info remove_cv(info type);
1913
+ consteval info add_const(info type);
1914
+ consteval info add_volatile(info type);
1915
+ consteval info add_cv(info type);
1916
+
1917
+ // associated with [meta.trans.ref], reference modifications
1918
+ consteval info remove_reference(info type);
1919
+ consteval info add_lvalue_reference(info type);
1920
+ consteval info add_rvalue_reference(info type);
1921
+
1922
+ // associated with [meta.trans.sign], sign modifications
1923
+ consteval info make_signed(info type);
1924
+ consteval info make_unsigned(info type);
1925
+
1926
+ // associated with [meta.trans.arr], array modifications
1927
+ consteval info remove_extent(info type);
1928
+ consteval info remove_all_extents(info type);
1929
+
1930
+ // associated with [meta.trans.ptr], pointer modifications
1931
+ consteval info remove_pointer(info type);
1932
+ consteval info add_pointer(info type);
1933
+
1934
+ // associated with [meta.trans.other], other transformations
1935
+ consteval info remove_cvref(info type);
1936
+ consteval info decay(info type);
1937
+ template<reflection_range R = initializer_list<info>>
1938
+ consteval info common_type(R&& type_args);
1939
+ template<reflection_range R = initializer_list<info>>
1940
+ consteval info common_reference(R&& type_args);
1941
+ consteval info underlying_type(info type);
1942
+ template<reflection_range R = initializer_list<info>>
1943
+ consteval info invoke_result(info type, R&& type_args);
1944
+ consteval info unwrap_reference(info type);
1945
+ consteval info unwrap_ref_decay(info type);
1946
+
1947
+ consteval size_t tuple_size(info type);
1948
+ consteval info tuple_element(size_t index, info type);
1949
+
1950
+ consteval size_t variant_size(info type);
1951
+ consteval info variant_alternative(size_t index, info type);
1952
+
1953
+ consteval strong_ordering type_order(info type_a, info type_b);
1954
+ }
1955
+ ```
1956
+
1957
+ Unless otherwise specified, each function, and each specialization of
1958
+ any function template, specified in this header is a designated
1959
+ addressable function [[namespace.std]].
1960
+
1961
+ The behavior of any function specified in namespace `std::meta` is
1962
+ *implementation-defined* when a reflection of a construct not otherwise
1963
+ specified by this document is provided as an argument.
1964
+
1965
+ [*Note 1*: Values of type `std::meta::info` can represent
1966
+ implementation-specific constructs [[basic.fundamental]]. — *end note*]
1967
+
1968
+ [*Note 2*:
1969
+
1970
+ Many of the functions specified in namespace `std::meta` have semantics
1971
+ that can be affected by the completeness of class types represented by
1972
+ reflection values. For such functions, for any reflection `r` such that
1973
+ `dealias(r)` represents a specialization of a templated class with a
1974
+ reachable definition, the specialization is implicitly instantiated
1975
+ [[temp.inst]].
1976
+
1977
+ [*Example 1*:
1978
+
1979
+ ``` cpp
1980
+ template<class T>
1981
+ struct X {
1982
+ T mem;
1983
+ };
1984
+
1985
+ static_assert(size_of(^^X<int>) == sizeof(int)); // instantiates X<int>
1986
+ ```
1987
+
1988
+ — *end example*]
1989
+
1990
+ — *end note*]
1991
+
1992
+ Any function in namespace `std::meta` whose return type is `string_view`
1993
+ or `u8string_view` returns an object *`V`* such that
1994
+ `V.data()[V.size()]` equals `'\0'`.
1995
+
1996
+ [*Example 2*:
1997
+
1998
+ ``` cpp
1999
+ struct C { };
2000
+
2001
+ constexpr string_view sv = identifier_of(^^C);
2002
+ static_assert(sv == "C");
2003
+ static_assert(sv.data()[0] == 'C');
2004
+ static_assert(sv.data()[1] == '{}0');
2005
+ ```
2006
+
2007
+ — *end example*]
2008
+
2009
+ For the purpose of exposition, throughout this clause `^^E` is used to
2010
+ indicate a reflection representing source construct `E`.
2011
+
2012
+ ### Checking string literals <a id="meta.string.literal">[[meta.string.literal]]</a>
2013
+
2014
+ ``` cpp
2015
+ consteval bool is_string_literal(const char* p);
2016
+ consteval bool is_string_literal(const wchar_t* p);
2017
+ consteval bool is_string_literal(const char8_t* p);
2018
+ consteval bool is_string_literal(const char16_t* p);
2019
+ consteval bool is_string_literal(const char32_t* p);
2020
+ ```
2021
+
2022
+ *Returns:*
2023
+
2024
+ - If `p` points to an unspecified object [[expr.const]], `false`.
2025
+ - Otherwise, if `p` points to a subobject of a string literal
2026
+ object [[lex.string]], `true`.
2027
+ - Otherwise, `false`.
2028
+
2029
+ ### Promoting to static storage <a id="meta.define.static">[[meta.define.static]]</a>
2030
+
2031
+ The functions in this subclause promote compile-time storage into static
2032
+ storage.
2033
+
2034
+ ``` cpp
2035
+ template<ranges::input_range R>
2036
+ consteval info reflect_constant_string(R&& r);
2037
+ ```
2038
+
2039
+ Let `CharT` be `ranges::range_value_t<R>`.
2040
+
2041
+ *Mandates:* `CharT` is one of `char`, `wchar_t`, `char8_t`, `char16_t`,
2042
+ `char32_t`.
2043
+
2044
+ Let V be the pack of values of type `CharT` whose elements are the
2045
+ corresponding elements of `r`, except that if `r` refers to a string
2046
+ literal object, then V does not include the trailing null terminator of
2047
+ `r`.
2048
+
2049
+ Let P be the template parameter object [[temp.param]] of type
2050
+ `const CharT[sizeof...(V) + 1]` initialized with `{`V`..., CharT()}`.
2051
+
2052
+ *Returns:* .
2053
+
2054
+ [*Note 1*: P is a potentially non-unique
2055
+ object [[intro.object]]. — *end note*]
2056
+
2057
+ ``` cpp
2058
+ template<ranges::input_range R>
2059
+ consteval info reflect_constant_array(R&& r);
2060
+ ```
2061
+
2062
+ Let `T` be `ranges::range_value_t<R>`.
2063
+
2064
+ *Mandates:* `T` is a structural type [[temp.param]],
2065
+ `is_constructible_v<T, ranges::range_reference_t<R>>` is `true`, and
2066
+ `is_copy_constructible_v<T>` is `true`.
2067
+
2068
+ Let V be the pack of values of type `info` of the same size as `r`,
2069
+ where the iᵗʰ element is `reflect_constant(``eᵢ``)`, where `eᵢ` is the
2070
+ iᵗʰ element of `r`.
2071
+
2072
+ Let P be
2073
+
2074
+ - If `sizeof...(`V`) > 0` is `true`, then the template parameter
2075
+ object [[temp.param]] of type `const T[sizeof...(`V`)]` initialized
2076
+ with `{[:`V`:]...}`.
2077
+ - Otherwise, the template parameter object of type `const array<T, 0>`
2078
+ initialized with `{}`.
2079
+
2080
+ *Returns:* .
2081
+
2082
+ *Throws:* `meta::exception` unless `reflect_constant(e)` is a constant
2083
+ subexpression for every element `e` of `r`.
2084
+
2085
+ [*Note 2*: P is a potentially non-unique
2086
+ object [[intro.object]]. — *end note*]
2087
+
2088
+ ``` cpp
2089
+ template<ranges::input_range R>
2090
+ consteval const ranges::range_value_t<R>* define_static_string(R&& r);
2091
+ ```
2092
+
2093
+ *Effects:* Equivalent to:
2094
+
2095
+ ``` cpp
2096
+ return meta::extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r));
2097
+ ```
2098
+
2099
+ ``` cpp
2100
+ template<ranges::input_range R>
2101
+ consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
2102
+ ```
2103
+
2104
+ *Effects:* Equivalent to:
2105
+
2106
+ ``` cpp
2107
+ using T = ranges::range_value_t<R>;
2108
+ meta::info array = meta::reflect_constant_array(r);
2109
+ if (meta::is_array_type(meta::type_of(array))) {
2110
+ return span<const T>(meta::extract<const T*>(array), meta::extent(meta::type_of(array)));
2111
+ } else {
2112
+ return span<const T>();
2113
+ }
2114
+ ```
2115
+
2116
+ ``` cpp
2117
+ template<class T>
2118
+ consteval const remove_cvref_t<T>* define_static_object(T&& t);
2119
+ ```
2120
+
2121
+ *Effects:* Equivalent to:
2122
+
2123
+ ``` cpp
2124
+ using U = remove_cvref_t<T>;
2125
+ if constexpr (meta::is_class_type(^^U)) {
2126
+ return addressof(meta::extract<const U&>(meta::reflect_constant(std::forward<T>(t))));
2127
+ } else {
2128
+ return define_static_array(span(addressof(t), 1)).data();
2129
+ }
2130
+ ```
2131
+
2132
+ [*Note 3*: For class types, `define_static_object` provides the address
2133
+ of the template parameter object [[temp.param]] that is
2134
+ template-argument equivalent to `t`. — *end note*]
2135
+
2136
+ ### Class `exception` <a id="meta.reflection.exception">[[meta.reflection.exception]]</a>
2137
+
2138
+ ``` cpp
2139
+ namespace std::meta {
2140
+ class exception : public std::exception {
2141
+ private:
2142
+ optional<string> what_; // exposition only
2143
+ u8string u8what_; // exposition only
2144
+ info from_; // exposition only
2145
+ source_location where_; // exposition only
2146
+
2147
+ public:
2148
+ consteval exception(u8string_view what, info from,
2149
+ source_location where = source_location::current()) noexcept;
2150
+
2151
+ consteval exception(string_view what, info from,
2152
+ source_location where = source_location::current()) noexcept;
2153
+
2154
+ exception(const exception&) = default;
2155
+ exception(exception&&) = default;
2156
+
2157
+ exception& operator=(const exception&) = default;
2158
+ exception& operator=(exception&&) = default;
2159
+
2160
+ constexpr const char* what() const noexcept override;
2161
+ consteval u8string_view u8what() const noexcept;
2162
+ consteval info from() const noexcept;
2163
+ consteval source_location where() const noexcept;
2164
+ };
2165
+ }
2166
+ ```
2167
+
2168
+ Reflection functions throw exceptions of type `meta::exception` to
2169
+ signal an error. `meta::exception` is a consteval-only type.
2170
+
2171
+ ``` cpp
2172
+ consteval exception(u8string_view what, info from,
2173
+ source_location where = source_location::current()) noexcept;
2174
+ ```
2175
+
2176
+ *Effects:* Initializes *u8what\_* with `what`, *from\_* with `from`, and
2177
+ *where\_* with `where`. If `what` can be represented in the ordinary
2178
+ literal encoding, initializes *what\_* with `what`, transcoded from
2179
+ UTF-8 to the ordinary literal encoding. Otherwise, *what\_* is
2180
+ value-initialized.
2181
+
2182
+ ``` cpp
2183
+ consteval exception(string_view what, info from,
2184
+ source_location where = source_location::current()) noexcept;
2185
+ ```
2186
+
2187
+ `what` designates a sequence of characters that can be encoded in UTF-8.
2188
+
2189
+ *Effects:* Initializes *what\_* with `what`, *u8what\_* with `what`
2190
+ transcoded from the ordinary literal encoding to UTF-8, *from\_* with
2191
+ `from` and *where\_* with `where`.
2192
+
2193
+ ``` cpp
2194
+ constexpr const char* what() const noexcept override;
2195
+ ```
2196
+
2197
+ *`what_`*`.has_value()` is `true`.
2198
+
2199
+ *Returns:* *`what_`*`->c_str()`.
2200
+
2201
+ ``` cpp
2202
+ consteval u8string_view u8what() const noexcept;
2203
+ ```
2204
+
2205
+ *Returns:* *u8what\_*.
2206
+
2207
+ ``` cpp
2208
+ consteval info from() const noexcept;
2209
+ ```
2210
+
2211
+ *Returns:* *from\_*.
2212
+
2213
+ ``` cpp
2214
+ consteval source_location where() const noexcept;
2215
+ ```
2216
+
2217
+ *Returns:* *where\_*.
2218
+
2219
+ ### Operator representations <a id="meta.reflection.operators">[[meta.reflection.operators]]</a>
2220
+
2221
+ ``` cpp
2222
+ enum class operators {
2223
+ see below;
2224
+ };
2225
+ using enum operators;
2226
+ ```
2227
+
2228
+ The enumeration type `operators` specifies constants used to identify
2229
+ operators that can be overloaded, with the meanings listed
2230
+ in  [[meta.reflection.operators]]. The values of the constants are
2231
+ distinct.
2232
+
2233
+ **Table: Enum class `operators`** <a id="meta.reflection.operators">[meta.reflection.operators]</a>
2234
+
2235
+ | Constant | Corresponding *operator-function-id* | Operator symbol name |
2236
+ | --------------------------- | ------------------------------------ | -------------------- |
2237
+ | `op_new` | `operator new` | `new` |
2238
+ | `op_delete` | `operator delete` | `delete` |
2239
+ | `op_array_new` | `operator new[]` | `new[]` |
2240
+ | `op_array_delete` | `operator delete[]` | `delete[]` |
2241
+ | `op_co_await` | `operator co_await` | `co_await` |
2242
+ | `op_parentheses` | `operator()` | `()` |
2243
+ | `op_square_brackets` | `operator[]` | `[]` |
2244
+ | `op_arrow` | `operator->` | `->` |
2245
+ | `op_arrow_star` | `operator->*` | `->*` |
2246
+ | `op_tilde` | `operator~` | `~` |
2247
+ | `op_exclamation` | `operator!` | `!` |
2248
+ | `op_plus` | `operator+` | `+` |
2249
+ | `op_minus` | `operator-` | `-` |
2250
+ | `op_star` | `operator*` | `*` |
2251
+ | `op_slash` | `operator/` | `/` |
2252
+ | `op_percent` | `operator%` | `%` |
2253
+ | `op_caret` | `operator^` | `^` |
2254
+ | `op_ampersand` | `operator&` | `&` |
2255
+ | `op_equals` | `operator=` | `=` |
2256
+ | `op_pipe` | `operator|` | `|` |
2257
+ | `op_plus_equals` | `operator+=` | `+=` |
2258
+ | `op_minus_equals` | `operator-=` | `-=` |
2259
+ | `op_star_equals` | `operator*=` | `*=` |
2260
+ | `op_slash_equals` | `operator/=` | `/=` |
2261
+ | `op_percent_equals` | `operator%=` | `%=` |
2262
+ | `op_caret_equals` | `operator^=` | `^=` |
2263
+ | `op_ampersand_equals` | `operator&=` | `&=` |
2264
+ | `op_pipe_equals` | `operator|=` | `|=` |
2265
+ | `op_equals_equals` | `operator==` | `==` |
2266
+ | `op_exclamation_equals` | `operator!=` | `!=` |
2267
+ | `op_less` | `operator<` | `<` |
2268
+ | `op_greater` | `operator>` | `>` |
2269
+ | `op_less_equals` | `operator<=` | `<=` |
2270
+ | `op_greater_equals` | `operator>=` | `>=` |
2271
+ | `op_spaceship` | `operator<=>` | `<=>` |
2272
+ | `op_ampersand_ampersand` | `operator&&` | `&&` |
2273
+ | `op_pipe_pipe` | `operator||` | `||` |
2274
+ | `op_less_less` | `operator<<` | `<<` |
2275
+ | `op_greater_greater` | `operator>>` | `>>` |
2276
+ | `op_less_less_equals` | `operator<<=` | `<<=` |
2277
+ | `op_greater_greater_equals` | `operator>>=` | `>>=` |
2278
+ | `op_plus_plus` | `operator++` | `++` |
2279
+ | `op_minus_minus` | `operator--` | `--` |
2280
+ | `op_comma` | `operator,` | `,` |
2281
+
2282
+ ``` cpp
2283
+ consteval operators operator_of(info r);
2284
+ ```
2285
+
2286
+ *Returns:* The value of the enumerator from `operators` whose
2287
+ corresponding *operator-function-id* is the unqualified name of the
2288
+ entity represented by `r`.
2289
+
2290
+ *Throws:* `meta::exception` unless `r` represents an operator function
2291
+ or operator function template.
2292
+
2293
+ ``` cpp
2294
+ consteval string_view symbol_of(operators op);
2295
+ consteval u8string_view u8symbol_of(operators op);
2296
+ ```
2297
+
2298
+ *Returns:* A `string_view` or `u8string_view` containing the characters
2299
+ of the operator symbol name corresponding to `op`, respectively encoded
2300
+ with the ordinary literal encoding or with UTF-8.
2301
+
2302
+ *Throws:* `meta::exception` unless the value of `op` corresponds to one
2303
+ of the enumerators in `operators`.
2304
+
2305
+ ### Reflection names and locations <a id="meta.reflection.names">[[meta.reflection.names]]</a>
2306
+
2307
+ ``` cpp
2308
+ consteval bool has_identifier(info r);
2309
+ ```
2310
+
2311
+ *Returns:*
2312
+
2313
+ - If `r` represents an entity that has a typedef name for linkage
2314
+ purposes [[dcl.typedef]], then `true`.
2315
+ - Otherwise, if `r` represents an unnamed entity, then `false`.
2316
+ - Otherwise, if `r` represents a class type, then
2317
+ `!has_template_arguments(r)`.
2318
+ - Otherwise, if `r` represents a function, then `true` if
2319
+ `has_template_arguments(r)` is `false` and the function is not a
2320
+ constructor, destructor, operator function, or conversion function.
2321
+ Otherwise, `false`.
2322
+ - Otherwise, if `r` represents a template, then `true` if `r` does not
2323
+ represent a constructor template, operator function template, or
2324
+ conversion function template. Otherwise, `false`.
2325
+ - Otherwise, if `r` represents the iᵗʰ parameter of a function F that is
2326
+ an (implicit or explicit) specialization of a templated function T and
2327
+ the iᵗʰ parameter of the instantiated declaration of T whose template
2328
+ arguments are those of F would be instantiated from a pack, then
2329
+ `false`.
2330
+ - Otherwise, if `r` represents the parameter P of a function F, then let
2331
+ S be the set of declarations, ignoring any explicit instantiations,
2332
+ that precede some point in the evaluation context and that declare
2333
+ either F or a templated function of which F is a specialization;
2334
+ `true` if
2335
+ - there is a declaration D in S that introduces a name N for either P
2336
+ or the parameter corresponding to P in the templated function that D
2337
+ declares and
2338
+ - no declaration in S does so using any name other than N.
2339
+
2340
+ Otherwise, `false`.
2341
+ \[*Example 1*:
2342
+ void fun(int);
2343
+ constexpr std::meta::info r = parameters_of(^^fun)[0];
2344
+ static_assert(!has_identifier(r));
2345
+
2346
+ void fun(int x);
2347
+ static_assert(has_identifier(r));
2348
+
2349
+ void fun(int x);
2350
+ static_assert(has_identifier(r));
2351
+
2352
+ void poison() {
2353
+ void fun(int y);
2354
+ }
2355
+ static_assert(!has_identifier(r));
2356
+
2357
+ — *end example*]
2358
+ - Otherwise, if `r` represents a variable, then `false` if the
2359
+ declaration of that variable was instantiated from a function
2360
+ parameter pack. Otherwise, `!has_template_arguments(r)`.
2361
+ - Otherwise, if `r` represents a structured binding, then `false` if the
2362
+ declaration of that structured binding was instantiated from a
2363
+ structured binding pack. Otherwise, `true`.
2364
+ - Otherwise, if `r` represents a type alias, then
2365
+ `!has_template_arguments(r)`.
2366
+ - Otherwise, if `r` represents an enumerator, non-static-data member,
2367
+ namespace, or namespace alias, then `true`.
2368
+ - Otherwise, if `r` represents a direct base class relationship, then
2369
+ `has_identifier(type_of(r))`.
2370
+ - Otherwise, `r` represents a data member description
2371
+ (T, N, A, W, *NUA*)[[class.mem.general]]; `true` if N is not $\bot$.
2372
+ Otherwise, `false`.
2373
+
2374
+ ``` cpp
2375
+ consteval string_view identifier_of(info r);
2376
+ consteval u8string_view u8identifier_of(info r);
2377
+ ```
2378
+
2379
+ Let E be UTF-8 for `u8identifier_of`, and otherwise the ordinary literal
2380
+ encoding.
2381
+
2382
+ *Returns:* An NTMBS, encoded with E, determined as follows:
2383
+
2384
+ - If `r` represents an entity with a typedef name for linkage purposes,
2385
+ then that name.
2386
+ - Otherwise, if `r` represents a literal operator or literal operator
2387
+ template, then the *ud-suffix* of the operator or operator template.
2388
+ - Otherwise, if `r` represents the parameter P of a function F, then let
2389
+ S be the set of declarations, ignoring any explicit instantiations,
2390
+ that precede some point in the evaluation context and that declare
2391
+ either F or a templated function of which F is a specialization; the
2392
+ name that was introduced by a declaration in S for the parameter
2393
+ corresponding to P.
2394
+ - Otherwise, if `r` represents an entity, then the identifier introduced
2395
+ by the declaration of that entity.
2396
+ - Otherwise, if `r` represents a direct base class relationship, then
2397
+ `identifier_of(type_of(r))` or `u8identifier_of(type_of(r))`,
2398
+ respectively.
2399
+ - Otherwise, `r` represents a data member description
2400
+ (T, N, A, W, NUA)[[class.mem.general]]; a `string_view` or
2401
+ `u8string_view`, respectively, containing the identifier N.
2402
+
2403
+ *Throws:* `meta::exception` unless `has_identifier(r)` is `true` and the
2404
+ identifier that would be returned (see above) is representable by E.
2405
+
2406
+ ``` cpp
2407
+ consteval string_view display_string_of(info r);
2408
+ consteval u8string_view u8display_string_of(info r);
2409
+ ```
2410
+
2411
+ *Returns:* An *implementation-defined* `string_view` or `u8string_view`,
2412
+ respectively.
2413
+
2414
+ *Recommended practice:* Where possible, implementations should return a
2415
+ string suitable for identifying the represented construct.
2416
+
2417
+ ``` cpp
2418
+ consteval source_location source_location_of(info r);
2419
+ ```
2420
+
2421
+ *Returns:* If `r` represents a value, a type other than a class type or
2422
+ an enumeration type, the global namespace, or a data member description,
2423
+ then `source_location{}`. Otherwise, an *implementation-defined*
2424
+ `source_location` value.
2425
+
2426
+ *Recommended practice:* If `r` represents an entity with a definition
2427
+ that is reachable from the evaluation context, a value corresponding to
2428
+ a definition should be returned.
2429
+
2430
+ ### Reflection queries <a id="meta.reflection.queries">[[meta.reflection.queries]]</a>
2431
+
2432
+ ``` cpp
2433
+ consteval bool has-type(info r); // exposition only
2434
+ ```
2435
+
2436
+ *Returns:* `true` if `r` represents a value, annotation, object,
2437
+ variable, function whose type does not contain an undeduced placeholder
2438
+ type and that is not a constructor or destructor, enumerator, non-static
2439
+ data member, unnamed bit-field, direct base class relationship, data
2440
+ member description, or function parameter. Otherwise, `false`.
2441
+
2442
+ ``` cpp
2443
+ consteval info type_of(info r);
2444
+ ```
2445
+
2446
+ *Returns:*
2447
+
2448
+ - If `r` represents the iᵗʰ parameter of a function F, then the iᵗʰ type
2449
+ in the parameter-type-list of F[[dcl.fct]].
2450
+ - Otherwise, if `r` represents a value, object, variable, function,
2451
+ non-static data member, or unnamed bit-field, then the type of what is
2452
+ represented by `r`.
2453
+ - Otherwise, if `r` represents an annotation, then
2454
+ `type_of(constant_of(r))`.
2455
+ - Otherwise, if `r` represents an enumerator N of an enumeration E,
2456
+ then:
2457
+ - If E is defined by a declaration D that precedes a point P in the
2458
+ evaluation context and P does not occur within an *enum-specifier*
2459
+ of D, then a reflection of E.
2460
+ - Otherwise, a reflection of the type of N prior to the closing brace
2461
+ of the *enum-specifier* as specified in  [[dcl.enum]].
2462
+ - Otherwise, if `r` represents a direct base class relationship (D, B),
2463
+ then a reflection of B.
2464
+ - Otherwise, for a data member description
2465
+ (T, N, A, W, *NUA*)[[class.mem.general]], a reflection of the type T.
2466
+
2467
+ *Throws:* `meta::exception` unless *`has-type`*`(r)` is `true`.
2468
+
2469
+ ``` cpp
2470
+ consteval info object_of(info r);
2471
+ ```
2472
+
2473
+ *Returns:*
2474
+
2475
+ - If `r` represents an object, then `r`.
2476
+ - Otherwise, if `r` represents a reference, then a reflection of the
2477
+ object referred to by that reference.
2478
+ - Otherwise, `r` represents a variable; a reflection of the object
2479
+ declared by that variable.
2480
+
2481
+ *Throws:* `meta::exception` unless `r` is a reflection representing
2482
+ either
2483
+
2484
+ - an object with static storage duration [[basic.stc.general]], or
2485
+ - a variable that either declares or refers to such an object, and if
2486
+ that variable is a reference R, then either
2487
+ - R is usable in constant expressions [[expr.const]], or
2488
+ - the lifetime of R began within the core constant expression
2489
+ currently under evaluation.
2490
+
2491
+ [*Example 1*:
2492
+
2493
+ ``` cpp
2494
+ int x;
2495
+ int& y = x;
2496
+
2497
+ static_assert(^^x != ^^y); // OK, r and y are different variables so their
2498
+ // reflections compare different
2499
+ static_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference
2500
+ // to x, their underlying objects are the same
2501
+ ```
2502
+
2503
+ — *end example*]
2504
+
2505
+ ``` cpp
2506
+ consteval info constant_of(info r);
2507
+ ```
2508
+
2509
+ Let R be a constant expression of type `info` such that R` == r` is
2510
+ `true`. If `r` represents an annotation, then let C be its underlying
2511
+ constant.
2512
+
2513
+ *Effects:* Equivalent to:
2514
+
2515
+ ``` cpp
2516
+ if constexpr (is_annotation(R)) {
2517
+ return C;
2518
+ } else {
2519
+ return reflect_constant([: R :]);
2520
+ }
2521
+ ```
2522
+
2523
+ *Throws:* `meta::exception` unless either `r` represents an annotation
2524
+ or `[: `R` :]` is a valid *splice-expression*[[expr.prim.splice]].
2525
+
2526
+ [*Example 2*:
2527
+
2528
+ ``` cpp
2529
+ constexpr int x = 0;
2530
+ constexpr int y = 0;
2531
+
2532
+ static_assert(^^x != ^^y); // OK, x and y are different variables,
2533
+ // so their reflections compare different
2534
+ static_assert(constant_of(^^x) ==
2535
+ constant_of(^^y)); // OK, both constant_of(\reflexpr{x)} and
2536
+ // constant_of(\reflexpr{y)} represent the value 0
2537
+ static_assert(constant_of(^^x) ==
2538
+ reflect_constant(0)); // OK, likewise
2539
+
2540
+ struct S { int m; };
2541
+ constexpr S s {42};
2542
+ static_assert(is_object(constant_of(^^s)) &&
2543
+ is_object(reflect_object(s)));
2544
+ static_assert(constant_of(^^s) != // OK, template parameter object that is template-argument-
2545
+ reflect_object(s)); // equivalent to s is a different object than s
2546
+ static_assert(constant_of(^^s) ==
2547
+ constant_of(reflect_object(s))); // OK
2548
+
2549
+ consteval info fn() {
2550
+ constexpr int x = 42;
2551
+ return ^^x;
2552
+ }
2553
+ constexpr info r = constant_of(fn()); // error: x is outside its lifetime
2554
+ ```
2555
+
2556
+ — *end example*]
2557
+
2558
+ ``` cpp
2559
+ consteval bool is_public(info r);
2560
+ consteval bool is_protected(info r);
2561
+ consteval bool is_private(info r);
2562
+ ```
2563
+
2564
+ *Returns:* `true` if `r` represents either
2565
+
2566
+ - a class member or unnamed bit-field that is public, protected, or
2567
+ private, respectively, or
2568
+ - a direct base class relationship (D, B) for which B is, respectively,
2569
+ a public, protected, or private base class of D.
2570
+
2571
+ Otherwise, `false`.
2572
+
2573
+ ``` cpp
2574
+ consteval bool is_virtual(info r);
2575
+ ```
2576
+
2577
+ *Returns:* `true` if `r` represents either a virtual member function or
2578
+ a direct base class relationship (D, B) for which B is a virtual base
2579
+ class of D. Otherwise, `false`.
2580
+
2581
+ ``` cpp
2582
+ consteval bool is_pure_virtual(info r);
2583
+ consteval bool is_override(info r);
2584
+ ```
2585
+
2586
+ *Returns:* `true` if `r` represents a member function that is pure
2587
+ virtual or overrides another member function, respectively. Otherwise,
2588
+ `false`.
2589
+
2590
+ ``` cpp
2591
+ consteval bool is_final(info r);
2592
+ ```
2593
+
2594
+ *Returns:* `true` if `r` represents a final class or a final member
2595
+ function. Otherwise, `false`.
2596
+
2597
+ ``` cpp
2598
+ consteval bool is_deleted(info r);
2599
+ consteval bool is_defaulted(info r);
2600
+ ```
2601
+
2602
+ *Returns:* `true` if `r` represents a function that is a deleted
2603
+ function [[dcl.fct.def.delete]] or defaulted
2604
+ function [[dcl.fct.def.default]], respectively. Otherwise, `false`.
2605
+
2606
+ ``` cpp
2607
+ consteval bool is_user_provided(info r);
2608
+ consteval bool is_user_declared(info r);
2609
+ ```
2610
+
2611
+ *Returns:* `true` if `r` represents a function that is user-provided or
2612
+ user-declared [[dcl.fct.def.default]], respectively. Otherwise, `false`.
2613
+
2614
+ ``` cpp
2615
+ consteval bool is_explicit(info r);
2616
+ ```
2617
+
2618
+ *Returns:* `true` if `r` represents a member function that is declared
2619
+ explicit. Otherwise, `false`.
2620
+
2621
+ [*Note 1*: If `r` represents a member function template that is
2622
+ declared explicit, `is_explicit(r)` is still `false` because in general,
2623
+ such queries for templates cannot be answered. — *end note*]
2624
+
2625
+ ``` cpp
2626
+ consteval bool is_noexcept(info r);
2627
+ ```
2628
+
2629
+ *Returns:* `true` if `r` represents a `noexcept` function type or a
2630
+ function with a non-throwing exception specification [[except.spec]].
2631
+ Otherwise, `false`.
2632
+
2633
+ [*Note 2*: If `r` represents a function template that is declared
2634
+ `noexcept`, `is_noexcept(r)` is still `false` because in general, such
2635
+ queries for templates cannot be answered. — *end note*]
2636
+
2637
+ ``` cpp
2638
+ consteval bool is_bit_field(info r);
2639
+ ```
2640
+
2641
+ *Returns:* `true` if `r` represents a bit-field, or if `r` represents a
2642
+ data member description (T, N, A, W, *NUA*)[[class.mem.general]] for
2643
+ which W is not $\bot$. Otherwise, `false`.
2644
+
2645
+ ``` cpp
2646
+ consteval bool is_enumerator(info r);
2647
+ consteval bool is_annotation(info r);
2648
+ ```
2649
+
2650
+ *Returns:* `true` if `r` represents an enumerator or annotation,
2651
+ respectively. Otherwise, `false`.
2652
+
2653
+ ``` cpp
2654
+ consteval bool is_const(info r);
2655
+ consteval bool is_volatile(info r);
2656
+ ```
2657
+
2658
+ Let T be `type_of(r)` if *`has-type`*`(r)` is `true`. Otherwise, let T
2659
+ be `dealias(r)`.
2660
+
2661
+ *Returns:* `true` if `T` represents a const or volatile type,
2662
+ respectively, or a const- or volatile-qualified function type,
2663
+ respectively. Otherwise, `false`.
2664
+
2665
+ ``` cpp
2666
+ consteval bool is_mutable_member(info r);
2667
+ ```
2668
+
2669
+ *Returns:* `true` if `r` represents a `mutable` non-static data member.
2670
+ Otherwise, `false`.
2671
+
2672
+ ``` cpp
2673
+ consteval bool is_lvalue_reference_qualified(info r);
2674
+ consteval bool is_rvalue_reference_qualified(info r);
2675
+ ```
2676
+
2677
+ Let T be `type_of(r)` if *`has-type`*`(r)` is `true`. Otherwise, let T
2678
+ be `dealias(r)`.
2679
+
2680
+ *Returns:* `true` if T represents an lvalue- or rvalue-qualified
2681
+ function type, respectively. Otherwise, `false`.
2682
+
2683
+ ``` cpp
2684
+ consteval bool has_static_storage_duration(info r);
2685
+ consteval bool has_thread_storage_duration(info r);
2686
+ consteval bool has_automatic_storage_duration(info r);
2687
+ ```
2688
+
2689
+ *Returns:* `true` if `r` represents an object or variable that has
2690
+ static, thread, or automatic storage duration,
2691
+ respectively [[basic.stc]]. Otherwise, `false`.
2692
+
2693
+ [*Note 3*: It is not possible to have a reflection representing an
2694
+ object or variable having dynamic storage duration. — *end note*]
2695
+
2696
+ ``` cpp
2697
+ consteval bool has_internal_linkage(info r);
2698
+ consteval bool has_module_linkage(info r);
2699
+ consteval bool has_external_linkage(info r);
2700
+ consteval bool has_c_language_linkage(info r);
2701
+ consteval bool has_linkage(info r);
2702
+ ```
2703
+
2704
+ *Returns:* `true` if `r` represents a variable, function, type,
2705
+ template, or namespace whose name has internal linkage, module linkage,
2706
+ C language linkage, or any linkage, respectively [[basic.link]].
2707
+ Otherwise, `false`.
2708
+
2709
+ ``` cpp
2710
+ consteval bool is_complete_type(info r);
2711
+ ```
2712
+
2713
+ *Returns:* `true` if `is_type(r)` is `true` and there is some point in
2714
+ the evaluation context from which the type represented by `dealias(r)`
2715
+ is not an incomplete type [[basic.types]]. Otherwise, `false`.
2716
+
2717
+ ``` cpp
2718
+ consteval bool is_enumerable_type(info r);
2719
+ ```
2720
+
2721
+ A type T is *enumerable* from a point P if either
2722
+
2723
+ - T is a class type complete at point P or
2724
+ - T is an enumeration type defined by a declaration D such that D is
2725
+ reachable from P but P does not occur within an *enum-specifier* of
2726
+ D[[dcl.enum]].
2727
+
2728
+ *Returns:* `true` if `dealias(r)` represents a type that is enumerable
2729
+ from some point in the evaluation context. Otherwise, `false`.
2730
+
2731
+ [*Example 3*:
2732
+
2733
+ ``` cpp
2734
+ class S;
2735
+ enum class E;
2736
+ static_assert(!is_enumerable_type(^^S));
2737
+ static_assert(!is_enumerable_type(^^E));
2738
+
2739
+ class S {
2740
+ void mfn() {
2741
+ static_assert(is_enumerable_type(^^S));
2742
+ }
2743
+ static_assert(!is_enumerable_type(^^S));
2744
+ };
2745
+ static_assert(is_enumerable_type(^^S));
2746
+
2747
+ enum class E {
2748
+ A = is_enumerable_type(^^E) ? 1 : 2
2749
+ };
2750
+ static_assert(is_enumerable_type(^^E));
2751
+ static_assert(static_cast<int>(E::A) == 2);
2752
+ ```
2753
+
2754
+ — *end example*]
2755
+
2756
+ ``` cpp
2757
+ consteval bool is_variable(info r);
2758
+ ```
2759
+
2760
+ *Returns:* `true` if `r` represents a variable. Otherwise, `false`.
2761
+
2762
+ ``` cpp
2763
+ consteval bool is_type(info r);
2764
+ consteval bool is_namespace(info r);
2765
+ ```
2766
+
2767
+ *Returns:* `true` if `r` represents an entity whose underlying entity is
2768
+ a type or namespace, respectively. Otherwise, `false`.
2769
+
2770
+ ``` cpp
2771
+ consteval bool is_type_alias(info r);
2772
+ consteval bool is_namespace_alias(info r);
2773
+ ```
2774
+
2775
+ *Returns:* `true` if `r` represents a type alias or namespace alias,
2776
+ respectively. Otherwise, `false`.
2777
+
2778
+ [*Note 4*: A specialization of an alias template is a type
2779
+ alias. — *end note*]
2780
+
2781
+ ``` cpp
2782
+ consteval bool is_function(info r);
2783
+ ```
2784
+
2785
+ *Returns:* `true` if `r` represents a function. Otherwise, `false`.
2786
+
2787
+ ``` cpp
2788
+ consteval bool is_conversion_function(info r);
2789
+ consteval bool is_operator_function(info r);
2790
+ consteval bool is_literal_operator(info r);
2791
+ ```
2792
+
2793
+ *Returns:* `true` if `r` represents a function that is a conversion
2794
+ function [[class.conv.fct]], operator function [[over.oper]], or literal
2795
+ operator [[over.literal]], respectively. Otherwise, `false`.
2796
+
2797
+ ``` cpp
2798
+ consteval bool is_special_member_function(info r);
2799
+ consteval bool is_constructor(info r);
2800
+ consteval bool is_default_constructor(info r);
2801
+ consteval bool is_copy_constructor(info r);
2802
+ consteval bool is_move_constructor(info r);
2803
+ consteval bool is_assignment(info r);
2804
+ consteval bool is_copy_assignment(info r);
2805
+ consteval bool is_move_assignment(info r);
2806
+ consteval bool is_destructor(info r);
2807
+ ```
2808
+
2809
+ *Returns:* `true` if `r` represents a function that is a special member
2810
+ function [[special]], a constructor, a default constructor, a copy
2811
+ constructor, a move constructor, an assignment operator, a copy
2812
+ assignment operator, a move assignment operator, or a destructor,
2813
+ respectively. Otherwise, `false`.
2814
+
2815
+ ``` cpp
2816
+ consteval bool is_function_parameter(info r);
2817
+ ```
2818
+
2819
+ *Returns:* `true` if `r` represents a function parameter. Otherwise,
2820
+ `false`.
2821
+
2822
+ ``` cpp
2823
+ consteval bool is_explicit_object_parameter(info r);
2824
+ ```
2825
+
2826
+ *Returns:* `true` if `r` represents a function parameter that is an
2827
+ explicit object parameter [[dcl.fct]]. Otherwise, `false`.
2828
+
2829
+ ``` cpp
2830
+ consteval bool has_default_argument(info r);
2831
+ ```
2832
+
2833
+ *Returns:* If `r` represents a parameter P of a function F, then:
2834
+
2835
+ - If F is a specialization of a templated function T, then `true` if
2836
+ there exists a declaration D of T that precedes some point in the
2837
+ evaluation context and D specifies a default argument for the
2838
+ parameter of T corresponding to P. Otherwise, `false`.
2839
+ - Otherwise, if there exists a declaration D of F that precedes some
2840
+ point in the evaluation context and D specifies a default argument for
2841
+ P, then `true`.
2842
+
2843
+ Otherwise, `false`.
2844
+
2845
+ ``` cpp
2846
+ consteval bool has_ellipsis_parameter(info r);
2847
+ ```
2848
+
2849
+ *Returns:* `true` if `r` represents a function or function type that has
2850
+ an ellipsis in its parameter-type-list [[dcl.fct]]. Otherwise, `false`.
2851
+
2852
+ ``` cpp
2853
+ consteval bool is_template(info r);
2854
+ ```
2855
+
2856
+ *Returns:* `true` if `r` represents a function template, class template,
2857
+ variable template, alias template, or concept. Otherwise, `false`.
2858
+
2859
+ [*Note 5*: A template specialization is not a template. For example,
2860
+ `is_template(``)` is `true` but `is_template(``)` is
2861
+ `false`. — *end note*]
2862
+
2863
+ ``` cpp
2864
+ consteval bool is_function_template(info r);
2865
+ consteval bool is_variable_template(info r);
2866
+ consteval bool is_class_template(info r);
2867
+ consteval bool is_alias_template(info r);
2868
+ consteval bool is_conversion_function_template(info r);
2869
+ consteval bool is_operator_function_template(info r);
2870
+ consteval bool is_literal_operator_template(info r);
2871
+ consteval bool is_constructor_template(info r);
2872
+ consteval bool is_concept(info r);
2873
+ ```
2874
+
2875
+ *Returns:* `true` if `r` represents a function template, variable
2876
+ template, class template, alias template, conversion function template,
2877
+ operator function template, literal operator template, constructor
2878
+ template, or concept, respectively. Otherwise, `false`.
2879
+
2880
+ ``` cpp
2881
+ consteval bool is_value(info r);
2882
+ consteval bool is_object(info r);
2883
+ ```
2884
+
2885
+ *Returns:* `true` if `r` represents a value or object, respectively.
2886
+ Otherwise, `false`.
2887
+
2888
+ ``` cpp
2889
+ consteval bool is_structured_binding(info r);
2890
+ ```
2891
+
2892
+ *Returns:* `true` if `r` represents a structured binding. Otherwise,
2893
+ `false`.
2894
+
2895
+ ``` cpp
2896
+ consteval bool is_class_member(info r);
2897
+ consteval bool is_namespace_member(info r);
2898
+ consteval bool is_nonstatic_data_member(info r);
2899
+ consteval bool is_static_member(info r);
2900
+ consteval bool is_base(info r);
2901
+ ```
2902
+
2903
+ *Returns:* `true` if `r` represents a class member, namespace member,
2904
+ non-static data member, static member, or direct base class
2905
+ relationship, respectively. Otherwise, `false`.
2906
+
2907
+ ``` cpp
2908
+ consteval bool has_default_member_initializer(info r);
2909
+ ```
2910
+
2911
+ *Returns:* `true` if `r` represents a non-static data member that has a
2912
+ default member initializer. Otherwise, `false`.
2913
+
2914
+ ``` cpp
2915
+ consteval bool has_parent(info r);
2916
+ ```
2917
+
2918
+ *Returns:*
2919
+
2920
+ - If `r` represents the global namespace, then `false`.
2921
+ - Otherwise, if `r` represents an entity that has C language
2922
+ linkage [[dcl.link]], then `false`.
2923
+ - Otherwise, if `r` represents an entity that has a language linkage
2924
+ other than C++ language linkage, then an *implementation-defined*
2925
+ value.
2926
+ - Otherwise, if `r` represents a type that is neither a class nor
2927
+ enumeration type, then `false`.
2928
+ - Otherwise, if `r` represents an entity or direct base class
2929
+ relationship, then `true`.
2930
+ - Otherwise, `false`.
2931
+
2932
+ ``` cpp
2933
+ consteval info parent_of(info r);
2934
+ ```
2935
+
2936
+ *Returns:*
2937
+
2938
+ - If `r` represents a non-static data member that is a direct member of
2939
+ an anonymous union, or an unnamed bit-field declared within the
2940
+ *member-specification* of such a union, then a reflection representing
2941
+ the innermost enclosing anonymous union.
2942
+ - Otherwise, if `r` represents an enumerator, then a reflection
2943
+ representing the corresponding enumeration type.
2944
+ - Otherwise, if `r` represents a direct base class relationship (D, B),
2945
+ then a reflection representing D.
2946
+ - Otherwise, let E be a class, function, or namespace whose class scope,
2947
+ function parameter scope, or namespace scope, respectively, is the
2948
+ innermost such scope that either is, or encloses, the target scope of
2949
+ a declaration of what is represented by `r`.
2950
+ - If E is the function call operator of a closure type for a
2951
+ *consteval-block-declaration*[[dcl.pre]], then
2952
+ `parent_of(parent_of(``))`. \[*Note 1*: In this case, the first
2953
+ `parent_of` will be the closure type, so the second `parent_of` is
2954
+ necessary to give the parent of that closure type. — *end note*]
2955
+ - Otherwise, .
2956
+
2957
+ *Throws:* `meta::exception` unless `has_parent(r)` is `true`.
2958
+
2959
+ [*Example 4*:
2960
+
2961
+ ``` cpp
2962
+ struct I { };
2963
+
2964
+ struct F : I {
2965
+ union {
2966
+ int o;
2967
+ };
2968
+
2969
+ enum N {
2970
+ A
2971
+ };
2972
+ };
2973
+
2974
+ constexpr auto ctx = std::meta::access_context::current();
2975
+
2976
+ static_assert(parent_of(^^F) == ^^::);
2977
+ static_assert(parent_of(bases_of(^^F, ctx)[0]) == ^^F);
2978
+ static_assert(is_union_type(parent_of(^^F::o)));
2979
+ static_assert(parent_of(^^F::N) == ^^F);
2980
+ static_assert(parent_of(^^F::A) == ^^F::N);
2981
+ ```
2982
+
2983
+ — *end example*]
2984
+
2985
+ ``` cpp
2986
+ consteval info dealias(info r);
2987
+ ```
2988
+
2989
+ *Returns:* A reflection representing the underlying entity of what `r`
2990
+ represents.
2991
+
2992
+ *Throws:* `meta::exception` unless `r` represents an entity.
2993
+
2994
+ [*Example 5*:
2995
+
2996
+ ``` cpp
2997
+ using X = int;
2998
+ using Y = X;
2999
+ static_assert(dealias(^^int) == ^^int);
3000
+ static_assert(dealias(^^X) == ^^int);
3001
+ static_assert(dealias(^^Y) == ^^int);
3002
+ ```
3003
+
3004
+ — *end example*]
3005
+
3006
+ ``` cpp
3007
+ consteval bool has_template_arguments(info r);
3008
+ ```
3009
+
3010
+ *Returns:* `true` if `r` represents a specialization of a function
3011
+ template, variable template, class template, or an alias template.
3012
+ Otherwise, `false`.
3013
+
3014
+ ``` cpp
3015
+ consteval info template_of(info r);
3016
+ ```
3017
+
3018
+ *Returns:* A reflection of the template of the specialization
3019
+ represented by `r`.
3020
+
3021
+ *Throws:* `meta::exception` unless `has_template_arguments(r)` is
3022
+ `true`.
3023
+
3024
+ ``` cpp
3025
+ consteval vector<info> template_arguments_of(info r);
3026
+ ```
3027
+
3028
+ *Returns:* A `vector` containing reflections of the template arguments
3029
+ of the template specialization represented by `r`, in the order in which
3030
+ they appear in the corresponding template argument list. For a given
3031
+ template argument A, its corresponding reflection R is determined as
3032
+ follows:
3033
+
3034
+ - If A denotes a type or type alias, then R is a reflection representing
3035
+ the underlying entity of A. \[*Note 2*: R always represents a type,
3036
+ never a type alias. — *end note*]
3037
+ - Otherwise, if A denotes a class template, variable template, concept,
3038
+ or alias template, then R is a reflection representing A.
3039
+ - Otherwise, A is a constant template argument [[temp.arg.nontype]]. Let
3040
+ P be the corresponding template parameter.
3041
+ - If P has reference type, then R is a reflection representing the
3042
+ object or function referred to by A.
3043
+ - Otherwise, if P has class type, then R represents the corresponding
3044
+ template parameter object.
3045
+ - Otherwise, R is a reflection representing the value of A.
3046
+
3047
+ *Throws:* `meta::exception` unless `has_template_arguments(r)` is
3048
+ `true`.
3049
+
3050
+ [*Example 6*:
3051
+
3052
+ ``` cpp
3053
+ template<class T, class U = T> struct Pair { };
3054
+ template<class T> struct Pair<char, T> { };
3055
+ template<class T> using PairPtr = Pair<T*>;
3056
+
3057
+ static_assert(template_of(^^Pair<int>) == ^^Pair);
3058
+ static_assert(template_of(^^Pair<char, char>) == ^^Pair);
3059
+ static_assert(template_arguments_of(^^Pair<int>).size() == 2);
3060
+ static_assert(template_arguments_of(^^Pair<int>)[0] == ^^int);
3061
+
3062
+ static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);
3063
+ static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);
3064
+
3065
+ struct S { };
3066
+ int i;
3067
+ template<int, int&, S, template<class> class>
3068
+ struct X { };
3069
+ constexpr auto T = ^^X<1, i, S{}, PairPtr>;
3070
+ static_assert(is_value(template_arguments_of(T)[0]));
3071
+ static_assert(is_object(template_arguments_of(T)[1]));
3072
+ static_assert(is_object(template_arguments_of(T)[2]));
3073
+ static_assert(template_arguments_of(T)[3] == ^^PairPtr);
3074
+ ```
3075
+
3076
+ — *end example*]
3077
+
3078
+ ``` cpp
3079
+ consteval vector<info> parameters_of(info r);
3080
+ ```
3081
+
3082
+ *Returns:*
3083
+
3084
+ - If `r` represents a function F, then a `vector` containing reflections
3085
+ of the parameters of F, in the order in which they appear in a
3086
+ declaration of F.
3087
+ - Otherwise, `r` represents a function type T; a `vector` containing
3088
+ reflections of the types in parameter-type-list [[dcl.fct]] of T, in
3089
+ the order in which they appear in the parameter-type-list.
3090
+
3091
+ *Throws:* `meta::exception` unless `r` represents a function or a
3092
+ function type.
3093
+
3094
+ ``` cpp
3095
+ consteval info variable_of(info r);
3096
+ ```
3097
+
3098
+ *Returns:* The reflection of the parameter variable corresponding to
3099
+ `r`.
3100
+
3101
+ *Throws:* `meta::exception` unless
3102
+
3103
+ - `r` represents a parameter of a function F and
3104
+ - there is a point P in the evaluation context for which the innermost
3105
+ non-block scope enclosing P is the function parameter
3106
+ scope [[basic.scope.param]] associated with F.
3107
+
3108
+ ``` cpp
3109
+ consteval info return_type_of(info r);
3110
+ ```
3111
+
3112
+ *Returns:* The reflection of the return type of the function or function
3113
+ type represented by `r`.
3114
+
3115
+ *Throws:* `meta::exception` unless either `r` represents a function and
3116
+ *`has-type`*`(r)` is `true` or `r` represents a function type.
3117
+
3118
+ ### Access control context <a id="meta.reflection.access.context">[[meta.reflection.access.context]]</a>
3119
+
3120
+ The `access_context` class is a non-aggregate type that represents a
3121
+ namespace, class, or function from which queries pertaining to access
3122
+ rules may be performed, as well as the designating class
3123
+ [[class.access.base]], if any.
3124
+
3125
+ An `access_context` has an associated scope and designating class.
3126
+
3127
+ ``` cpp
3128
+ namespace std::meta {
3129
+ struct access_context {
3130
+ access_context() = delete;
3131
+
3132
+ consteval info scope() const;
3133
+ consteval info designating_class() const;
3134
+
3135
+ static consteval access_context current() noexcept;
3136
+ static consteval access_context unprivileged() noexcept;
3137
+ static consteval access_context unchecked() noexcept;
3138
+ consteval access_context via(info cls) const;
3139
+ };
3140
+ }
3141
+ ```
3142
+
3143
+ `access_context` is a structural type. Two values `ac1` and `ac2` of
3144
+ type `access_context` are template-argument-equivalent [[temp.type]] if
3145
+ `ac1.scope()` and `ac2.scope()` are template-argument-equivalent and
3146
+ `ac1.designating_class()` and `ac2.designating_class()` are
3147
+ template-argument-equivalent.
3148
+
3149
+ ``` cpp
3150
+ consteval info scope() const;
3151
+ consteval info designating_class() const;
3152
+ ```
3153
+
3154
+ *Returns:* The `access_context`’s associated scope and designating
3155
+ class, respectively.
3156
+
3157
+ ``` cpp
3158
+ static consteval access_context current() noexcept;
3159
+ ```
3160
+
3161
+ Given a program point P, let *`eval-point`*`(`P`)` be the following
3162
+ program point:
3163
+
3164
+ - If a potentially-evaluated subexpression [[intro.execution]] of a
3165
+ default member initializer I for a member of class
3166
+ C[[class.mem.general]] appears at P, then a point determined as
3167
+ follows:
3168
+ - If an aggregate initialization is using I, *`eval-point`*`(`Q`)`,
3169
+ where Q is the point at which that aggregate initialization appears.
3170
+ - Otherwise, if an initialization by an inherited
3171
+ constructor [[class.inhctor.init]] is using I, a point whose
3172
+ immediate scope is the class scope corresponding to C.
3173
+ - Otherwise, a point whose immediate scope is the function parameter
3174
+ scope corresponding to the constructor definition that is using I.
3175
+ - Otherwise, if a potentially-evaluated subexpression of a default
3176
+ argument [[dcl.fct.default]] appears at P, *`eval-point`*`(`Q`)`,
3177
+ where Q is the point at which the invocation of the
3178
+ function [[expr.call]] using that default argument appears.
3179
+ - Otherwise, if the immediate scope of P is a function parameter scope
3180
+ introduced by a declaration D, and P appears either before the locus
3181
+ of D or within the trailing *requires-clause* of D, a point whose
3182
+ immediate scope is the innermost scope enclosing the locus of D that
3183
+ is not a template parameter scope.
3184
+ - Otherwise, if the immediate scope of P is a function parameter scope
3185
+ introduced by a *lambda-expression* L whose *lambda-introducer*
3186
+ appears at point Q, and P appears either within the
3187
+ *trailing-return-type* or the trailing *requires-clause* of L,
3188
+ *`eval-point`*`(`Q`)`.
3189
+ - Otherwise, if the innermost non-block scope enclosing P is the
3190
+ function parameter scope introduced by a
3191
+ *consteval-block-declaration*[[dcl.pre]], a point whose immediate
3192
+ scope is that inhabited by the outermost *consteval-block-declaration*
3193
+ D containing P such that each scope (if any) that intervenes between P
3194
+ and the function parameter scope introduced by D is either
3195
+ - a block scope or
3196
+ - a function parameter scope or lambda scope introduced by a
3197
+ *consteval-block-declaration*.
3198
+ - Otherwise, P.
3199
+
3200
+ Given a scope S, let *`ctx-scope`*`(`S`)` be the following scope:
3201
+
3202
+ - If S is a class scope or namespace scope, S.
3203
+ - Otherwise, if S is a function parameter scope introduced by the
3204
+ declaration of a function, S.
3205
+ - Otherwise, if S is a lambda scope introduced by a *lambda-expression*
3206
+ L, the function parameter scope corresponding to the call operator of
3207
+ the closure type of L.
3208
+ - Otherwise, *`ctx-scope`*`(`S'`)`, where S' is the parent scope of S.
3209
+
3210
+ *Returns:* An `access_context` whose designating class is the null
3211
+ reflection and whose scope represents the function, class, or namespace
3212
+ whose corresponding function parameter scope, class scope, or namespace
3213
+ scope, respectively, is *`ctx-scope`*`(`S`)`, where S is the immediate
3214
+ scope of *`eval-point`*`(`P`)` and P is the point at which the
3215
+ invocation of `current` lexically appears.
3216
+
3217
+ *Remarks:* `current` is not an addressable function [[namespace.std]].
3218
+ An invocation of `current` that appears at a program point P is
3219
+ value-dependent [[temp.dep.constexpr]] if *`eval-point`*`(`P`)` is
3220
+ enclosed by a scope corresponding to a templated entity.
3221
+
3222
+ [*Example 1*:
3223
+
3224
+ ``` cpp
3225
+ struct A {
3226
+ int a = 0;
3227
+ consteval A(int p) : a(p) {}
3228
+ };
3229
+ struct B : A {
3230
+ using A::A;
3231
+ consteval B(int p, int q) : A(p * q) {}
3232
+ info s = access_context::current().scope();
3233
+ };
3234
+ struct C : B { using B::B; };
3235
+
3236
+ struct Agg {
3237
+ consteval bool eq(info rhs = access_context::current().scope()) {
3238
+ return s == rhs;
3239
+ }
3240
+ info s = access_context::current().scope();
3241
+ };
3242
+
3243
+ namespace NS {
3244
+ static_assert(Agg{}.s == access_context::current().scope()); // OK
3245
+ static_assert(Agg{}.eq()); // OK
3246
+ static_assert(B(1).s == ^^B); // OK
3247
+ static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OK
3248
+ static_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OK
3249
+
3250
+ auto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:];
3251
+ static_assert(type_of(^^fn) == ^^auto()->int); // OK
3252
+
3253
+ template<auto R>
3254
+ struct TCls {
3255
+ consteval bool fn()
3256
+ requires (is_type(access_context::current().scope())) {
3257
+ return true; // OK, scope is TCls<R>.
3258
+ }
3259
+ };
3260
+ static_assert(TCls<0>{}.fn()); // OK
3261
+ }
3262
+ ```
3263
+
3264
+ — *end example*]
3265
+
3266
+ ``` cpp
3267
+ static consteval access_context unprivileged() noexcept;
3268
+ ```
3269
+
3270
+ *Returns:* An `access_context` whose designating class is the null
3271
+ reflection and whose scope is the global namespace.
3272
+
3273
+ ``` cpp
3274
+ static consteval access_context unchecked() noexcept;
3275
+ ```
3276
+
3277
+ *Returns:* An `access_context` whose designating class and scope are
3278
+ both the null reflection.
3279
+
3280
+ ``` cpp
3281
+ consteval access_context via(info cls) const;
3282
+ ```
3283
+
3284
+ *Returns:* An `access_context` whose scope is `this->scope()` and whose
3285
+ designating class is `cls`.
3286
+
3287
+ *Throws:* `meta::exception` unless `cls` is either the null reflection
3288
+ or a reflection of a complete class type.
3289
+
3290
+ ### Member accessibility queries <a id="meta.reflection.access.queries">[[meta.reflection.access.queries]]</a>
3291
+
3292
+ ``` cpp
3293
+ consteval bool is_accessible(info r, access_context ctx);
3294
+ ```
3295
+
3296
+ Let *`PARENT-CLS`*`(r)` be:
3297
+
3298
+ - If `parent_of(r)` represents a class C, then C.
3299
+ - Otherwise, *`PARENT-CLS`*`(parent_of(r))`.
3300
+
3301
+ Let *`DESIGNATING-CLS`*`(r, ctx)` be:
3302
+
3303
+ - If `ctx.designating_class()` represents a class C, then C.
3304
+ - Otherwise, *`PARENT-CLS`*`(r)`.
3305
+
3306
+ *Returns:*
3307
+
3308
+ - If `r` represents an unnamed bit-field F, then
3309
+ `is_accessible(``r_H``, ctx)`, where `r_H` represents a hypothetical
3310
+ non-static data member of the class represented by *`PARENT-CLS`*`(r)`
3311
+ with the same access as F. \[*Note 1*: Unnamed bit-fields are treated
3312
+ as class members for the purpose of `is_accessible`. — *end note*]
3313
+ - Otherwise, if `r` does not represent a class member or a direct base
3314
+ class relationship, then `true`.
3315
+ - Otherwise, if `r` represents
3316
+ - a class member that is not a (possibly indirect or variant) member
3317
+ of *`DESIGNATING-CLS`*`(r, ctx)` or
3318
+ - a direct base class relationship such that `parent_of(r)` does not
3319
+ represent *`DESIGNATING-CLS`*`(r, ctx)` or a (direct or indirect)
3320
+ base class thereof,
3321
+
3322
+ then `false`.
3323
+ - Otherwise, if `ctx.scope()` is the null reflection, then `true`.
3324
+ - Otherwise, letting P be a program point whose immediate scope is the
3325
+ function parameter scope, class scope, or namespace scope
3326
+ corresponding to the function, class, or namespace represented by
3327
+ `ctx.scope()`:
3328
+ - If `r` represents a direct base class relationship (D, B), then
3329
+ `true` if base class B of *`DESIGNATING-CLS`*`(r, ctx)` is
3330
+ accessible at P[[class.access.base]]; otherwise `false`.
3331
+ - Otherwise, `r` represents a class member M; `true` if M would be
3332
+ accessible at P with the designating class [[class.access.base]] as
3333
+ *`DESIGNATING-CLS`*`(r, ctx)` if the effect of any
3334
+ *using-declaration*s [[namespace.udecl]] were ignored. Otherwise,
3335
+ `false`.
3336
+
3337
+ [*Note 1*: The definitions of when a class member or base class is
3338
+ accessible from a point P do not consider whether a declaration of that
3339
+ entity is reachable from P. — *end note*]
3340
+
3341
+ *Throws:* `meta::exception` if
3342
+
3343
+ - `r` represents a class member for which *`PARENT-CLS`*`(r)` is an
3344
+ incomplete class or
3345
+ - `r` represents a direct base class relationship (D, B) for which D is
3346
+ incomplete.
3347
+
3348
+ [*Example 1*:
3349
+
3350
+ ``` cpp
3351
+ consteval access_context fn() {
3352
+ return access_context::current();
3353
+ }
3354
+
3355
+ class Cls {
3356
+ int mem;
3357
+ friend consteval access_context fn();
3358
+ public:
3359
+ static constexpr auto r = ^^mem;
3360
+ };
3361
+
3362
+ static_assert(is_accessible(Cls::r, fn())); // OK
3363
+ static_assert(!is_accessible(Cls::r, access_context::current())); // OK
3364
+ static_assert(is_accessible(Cls::r, access_context::unchecked())); // OK
3365
+ ```
3366
+
3367
+ — *end example*]
3368
+
3369
+ ``` cpp
3370
+ consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
3371
+ ```
3372
+
3373
+ *Returns:* `true` if `is_accessible(`R`, ctx)` is `false` for any R in
3374
+ `nonstatic_data_members_of(r, access_context::unchecked())`. Otherwise,
3375
+ `false`.
3376
+
3377
+ *Throws:* `meta::exception` unless
3378
+
3379
+ - `nonstatic_data_members_of(r, access_context::unchecked())` is a
3380
+ constant subexpression and
3381
+ - `r` does not represent a closure type.
3382
+
3383
+ ``` cpp
3384
+ consteval bool has_inaccessible_bases(info r, access_context ctx);
3385
+ ```
3386
+
3387
+ *Returns:* `true` if `is_accessible(`R`, ctx)` is `false` for any R in
3388
+ `bases_of(r, access_context::unchecked())`. Otherwise, `false`.
3389
+
3390
+ *Throws:* `meta::exception` unless
3391
+ `bases_of(r, access_context::unchecked())` is a constant subexpression.
3392
+
3393
+ ``` cpp
3394
+ consteval bool has_inaccessible_subobjects(info r, access_context ctx);
3395
+ ```
3396
+
3397
+ *Effects:* Equivalent to:
3398
+
3399
+ ``` cpp
3400
+ return has_inaccessible_bases(r, ctx) || has_inaccessible_nonstatic_data_members(r, ctx);
3401
+ ```
3402
+
3403
+ ### Reflection member queries <a id="meta.reflection.member.queries">[[meta.reflection.member.queries]]</a>
3404
+
3405
+ ``` cpp
3406
+ consteval vector<info> members_of(info r, access_context ctx);
3407
+ ```
3408
+
3409
+ A declaration D *members-of-precedes* a point P if D precedes either P
3410
+ or the point immediately following the *class-specifier* of the
3411
+ outermost class for which P is in a complete-class context.
3412
+
3413
+ A declaration D of a member M of a class or namespace Q is
3414
+ *Q-members-of-eligible* if
3415
+
3416
+ - the host scope of D[[basic.scope.scope]] is the class scope or
3417
+ namespace scope associated with Q,
3418
+ - D is not a friend declaration,
3419
+ - M is not a closure type [[expr.prim.lambda.closure]],
3420
+ - M is not a specialization of a template [[temp.pre]],
3421
+ - if Q is a class that is not a closure type, then M is a direct member
3422
+ of Q[[class.mem.general]] that is not a variant member of a nested
3423
+ anonymous union of Q[[class.union.anon]], and
3424
+ - if Q is a closure type, then M is a function call operator or function
3425
+ call operator template.
3426
+
3427
+ It is *implementation-defined* whether declarations of other members of
3428
+ a closure type Q are Q-members-of-eligible.
3429
+
3430
+ A member M of a class or namespace Q is *Q-members-of-representable*
3431
+ from a point P if a Q-members-of-eligible declaration of M
3432
+ members-of-precedes P, and M is
3433
+
3434
+ - a class or enumeration type,
3435
+ - a type alias,
3436
+ - a class template, function template, variable template, alias
3437
+ template, or concept,
3438
+ - a variable or reference V for which the type of V does not contain an
3439
+ undeduced placeholder type,
3440
+ - a function F for which
3441
+ - the type of F does not contain an undeduced placeholder type,
3442
+ - the constraints (if any) of F are satisfied, and
3443
+ - if F is a prospective destructor, F is the selected
3444
+ destructor [[class.dtor]],
3445
+ - a non-static data member,
3446
+ - a namespace, or
3447
+ - a namespace alias.
3448
+
3449
+ [*Note 1*: Examples of direct members that are not
3450
+ Q-members-of-representable for any entity Q include: unscoped
3451
+ enumerators [[enum]], partial specializations of
3452
+ templates [[temp.spec.partial]], and closure
3453
+ types [[expr.prim.lambda.closure]]. — *end note*]
3454
+
3455
+ *Returns:* A `vector` containing reflections of all members M of the
3456
+ entity Q represented by `dealias(r)` for which
3457
+
3458
+ - M is Q-members-of-representable from some point in the evaluation
3459
+ context and
3460
+ - `is_accessible(``, ctx)` is `true`.
3461
+
3462
+ If `dealias(r)` represents a class C, then the `vector` also contains
3463
+ reflections representing all unnamed bit-fields B whose declarations
3464
+ inhabit the class scope corresponding to C for which
3465
+ `is_accessible(``, ctx)` is `true`. Reflections of class members and
3466
+ unnamed bit-fields that are declared appear in the order in which they
3467
+ are declared.
3468
+
3469
+ [*Note 2*: Base classes are not members. Implicitly-declared special
3470
+ members appear after any user-declared
3471
+ members [[special]]. — *end note*]
3472
+
3473
+ *Throws:* `meta::exception` unless `dealias(r)` is a reflection
3474
+ representing either a class type that is complete from some point in the
3475
+ evaluation context or a namespace.
3476
+
3477
+ [*Example 1*:
3478
+
3479
+ ``` cpp
3480
+ // TU1
3481
+ export module M;
3482
+ namespace NS {
3483
+ export int m;
3484
+ static int l;
3485
+ }
3486
+ static_assert(members_of(^^NS, access_context::current()).size() == 2);
3487
+
3488
+ // TU2
3489
+ import M;
3490
+
3491
+ static_assert( // NS::l does not precede
3492
+ members_of(^^NS, access_context::current()).size() == 1); // the constant-expression [basic.lookup]
3493
+
3494
+ class B {};
3495
+
3496
+ struct S : B {
3497
+ private:
3498
+ class I;
3499
+ public:
3500
+ int m;
3501
+ };
3502
+
3503
+ static_assert( // 6 special members,
3504
+ members_of(^^S, access_context::current()).size() == 7); // 1 public member,
3505
+ // does not include base
3506
+
3507
+ static_assert( // all of the above,
3508
+ members_of(^^S, access_context::unchecked()).size() == 8); // as well as a reflection
3509
+ // representing S::I
3510
+ ```
3511
+
3512
+ — *end example*]
3513
+
3514
+ ``` cpp
3515
+ consteval vector<info> bases_of(info type, access_context ctx);
3516
+ ```
3517
+
3518
+ *Returns:* Let C be the class represented by `dealias(type)`. A `vector`
3519
+ containing the reflections of all the direct base class relationships B,
3520
+ if any, of C such that `is_accessible(``, ctx)` is `true`. The direct
3521
+ base class relationships appear in the order in which the corresponding
3522
+ base classes appear in the *base-specifier-list* of C.
3523
+
3524
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
3525
+ type that is complete from some point in the evaluation context.
3526
+
3527
+ ``` cpp
3528
+ consteval vector<info> static_data_members_of(info type, access_context ctx);
3529
+ ```
3530
+
3531
+ *Returns:* A `vector` containing each element `e` of
3532
+ `members_of(type, ctx)` such that `is_variable(e)` is `true`, preserving
3533
+ their order.
3534
+
3535
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
3536
+ type that is complete from some point in the evaluation context.
3537
+
3538
+ ``` cpp
3539
+ consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
3540
+ ```
3541
+
3542
+ *Returns:* A `vector` containing each element `e` of
3543
+ `members_of(type, ctx)` such that `is_nonstatic_data_member(e)` is
3544
+ `true`, preserving their order.
3545
+
3546
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
3547
+ type that is complete from some point in the evaluation context.
3548
+
3549
+ ``` cpp
3550
+ consteval vector<info> subobjects_of(info type, access_context ctx);
3551
+ ```
3552
+
3553
+ *Returns:* A `vector` containing each element of `bases_of(type, ctx)`
3554
+ followed by each element of `nonstatic_data_members_of(type, ctx)`,
3555
+ preserving their order.
3556
+
3557
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
3558
+ type that is complete from some point in the evaluation context.
3559
+
3560
+ ``` cpp
3561
+ consteval vector<info> enumerators_of(info type_enum);
3562
+ ```
3563
+
3564
+ *Returns:* A `vector` containing the reflections of each enumerator of
3565
+ the enumeration represented by `dealias(type_enum)`, in the order in
3566
+ which they are declared.
3567
+
3568
+ *Throws:* `meta::exception` unless `dealias(type_enum)` represents an
3569
+ enumeration type, and `is_enumerable_type(type_enum)` is `true`.
3570
+
3571
+ ### Reflection layout queries <a id="meta.reflection.layout">[[meta.reflection.layout]]</a>
3572
+
3573
+ ``` cpp
3574
+ struct member_offset {
3575
+ ptrdiff_t bytes;
3576
+ ptrdiff_t bits;
3577
+ constexpr ptrdiff_t total_bits() const;
3578
+ auto operator<=>(const member_offset&) const = default;
3579
+ };
3580
+
3581
+ constexpr ptrdiff_t member_offset::total_bits() const;
3582
+ ```
3583
+
3584
+ *Returns:* `bytes * CHAR_BIT + bits`.
3585
+
3586
+ ``` cpp
3587
+ consteval member_offset offset_of(info r);
3588
+ ```
3589
+
3590
+ Let V be the offset in bits from the beginning of a complete object of
3591
+ the type represented by `parent_of(r)` to the subobject associated with
3592
+ the construct represented by `r`.
3593
+
3594
+ *Returns:* `{`V` / CHAR_BIT, `V` % CHAR_BIT}`.
3595
+
3596
+ *Throws:* `meta::exception` unless `r` represents a non-static data
3597
+ member, unnamed bit-field, or direct base class relationship (D, B) for
3598
+ which either B is not a virtual base class or D is not an abstract
3599
+ class.
3600
+
3601
+ ``` cpp
3602
+ consteval size_t size_of(info r);
3603
+ ```
3604
+
3605
+ *Returns:* If
3606
+
3607
+ - `r` represents a non-static data member of type T or a data member
3608
+ description (T, N, A, W, *NUA*) or
3609
+ - `dealias(r)` represents a type T,
3610
+
3611
+ then `sizeof(`T`)` if T is not a reference type and
3612
+ `size_of(add_pointer(``))` otherwise. Otherwise, `size_of(type_of(r))`.
3613
+
3614
+ [*Note 1*: It is possible that while `sizeof(char) == size_of(``)` is
3615
+ `true`, that `sizeof(char&) == size_of(``&)` is `false`. If `b`
3616
+ represents a direct base class relationship of an empty base class, then
3617
+ `size_of(b) > 0` is `true`. — *end note*]
3618
+
3619
+ *Throws:* `meta::exception` unless all of the following conditions are
3620
+ met:
3621
+
3622
+ - `dealias(r)` is a reflection of a type, object, value, variable of
3623
+ non-reference type, non-static data member that is not a bit-field,
3624
+ direct base class relationship, or data member description
3625
+ (T, N, A, W, *NUA*)[[class.mem.general]] where W is $\bot$.
3626
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
3627
+ `true`.
3628
+
3629
+ ``` cpp
3630
+ consteval size_t alignment_of(info r);
3631
+ ```
3632
+
3633
+ *Returns:*
3634
+
3635
+ - If `dealias(r)` represents a type T, then
3636
+ `alignment_of(add_pointer(r))` if T is a reference type and the
3637
+ alignment requirement of T otherwise.
3638
+ - Otherwise, if `dealias(r)` represents a variable or object, then the
3639
+ alignment requirement of the variable or object.
3640
+ - Otherwise, if `r` represents a direct base class relationship, then
3641
+ `alignment_of(type_of(r))`.
3642
+ - Otherwise, if `r` represents a non-static data member M of a class C,
3643
+ then the alignment of the direct member subobject corresponding to M
3644
+ of a complete object of type C.
3645
+ - Otherwise, `r` represents a data member description
3646
+ (T, N, A, W, *NUA*)[[class.mem.general]]. If A is not $\bot$, then the
3647
+ value A. Otherwise, `alignment_of(``)`.
3648
+
3649
+ *Throws:* `meta::exception` unless all of the following conditions are
3650
+ met:
3651
+
3652
+ - `dealias(r)` is a reflection of a type, object, variable of
3653
+ non-reference type, non-static data member that is not a bit-field,
3654
+ direct base class relationship, or data member description.
3655
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
3656
+ `true`.
3657
+
3658
+ ``` cpp
3659
+ consteval size_t bit_size_of(info r);
3660
+ ```
3661
+
3662
+ *Returns:*
3663
+
3664
+ - If `r` represents an unnamed bit-field or a non-static data member
3665
+ that is a bit-field with width W, then W.
3666
+ - Otherwise, if `r` represents a data member description
3667
+ (T, N, A, W, *NUA*)[[class.mem.general]] and W is not $\bot$, then W.
3668
+ - Otherwise, `CHAR_BIT * size_of(r)`.
3669
+
3670
+ *Throws:* `meta::exception` unless all of the following conditions are
3671
+ met:
3672
+
3673
+ - `dealias(r)` is a reflection of a type, object, value, variable of
3674
+ non-reference type, non-static data member, unnamed bit-field, direct
3675
+ base class relationship, or data member description.
3676
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
3677
+ `true`.
3678
+
3679
+ ### Annotation reflection <a id="meta.reflection.annotation">[[meta.reflection.annotation]]</a>
3680
+
3681
+ ``` cpp
3682
+ consteval vector<info> annotations_of(info item);
3683
+ ```
3684
+
3685
+ Let E be
3686
+
3687
+ - the corresponding *base-specifier* if `item` represents a direct base
3688
+ class relationship,
3689
+ - otherwise, the entity represented by `item`.
3690
+
3691
+ *Returns:* A `vector` containing all of the reflections R representing
3692
+ each annotation applying to each declaration of E that precedes either
3693
+ some point in the evaluation context [[expr.const]] or a point
3694
+ immediately following the *class-specifier* of the outermost class for
3695
+ which such a point is in a complete-class context. For any two
3696
+ reflections R₁ and R₂ in the returned `vector`, if the annotation
3697
+ represented by R₁ precedes the annotation represented by R₂, then R₁
3698
+ appears before R₂. If R₁ and R₂ represent annotations from the same
3699
+ translation unit T, any element in the returned `vector` between R₁ and
3700
+ R₂ represents an annotation from T.
3701
+
3702
+ [*Note 1*: The order in which two annotations appear is otherwise
3703
+ unspecified. — *end note*]
3704
+
3705
+ *Throws:* `meta::exception` unless `item` represents a type, type alias,
3706
+ variable, function, namespace, enumerator, direct base class
3707
+ relationship, or non-static data member.
3708
+
3709
+ [*Example 1*:
3710
+
3711
+ ``` cpp
3712
+ [[=1]] void f();
3713
+ [[=2, =3]] void g();
3714
+ void g [[=4]] ();
3715
+
3716
+ static_assert(annotations_of(^^f).size() == 1);
3717
+ static_assert(annotations_of(^^g).size() == 3);
3718
+ static_assert([: constant_of(annotations_of(^^g)[0]) :] == 2);
3719
+ static_assert(extract<int>(annotations_of(^^g)[1]) == 3);
3720
+ static_assert(extract<int>(annotations_of(^^g)[2]) == 4);
3721
+
3722
+ struct Option { bool value; };
3723
+
3724
+ struct C {
3725
+ [[=Option{true}]] int a;
3726
+ [[=Option{false}]] int b;
3727
+ };
3728
+
3729
+ static_assert(extract<Option>(annotations_of(^^C::a)[0]).value);
3730
+ static_assert(!extract<Option>(annotations_of(^^C::b)[0]).value);
3731
+
3732
+ template<class T>
3733
+ struct [[=42]] D { };
3734
+
3735
+ constexpr std::meta::info a1 = annotations_of(^^D<int>)[0];
3736
+ constexpr std::meta::info a2 = annotations_of(^^D<char>)[0];
3737
+ static_assert(a1 != a2);
3738
+ static_assert(constant_of(a1) == constant_of(a2));
3739
+
3740
+ [[=1]] int x, y;
3741
+ static_assert(annotations_of(^^x)[0] == annotations_of(^^y)[0]);
3742
+ ```
3743
+
3744
+ — *end example*]
3745
+
3746
+ ``` cpp
3747
+ consteval vector<info> annotations_of_with_type(info item, info type);
3748
+ ```
3749
+
3750
+ *Returns:* A `vector` containing each element `e` of
3751
+ `annotations_of(item)` where
3752
+
3753
+ ``` cpp
3754
+ remove_const(type_of(e)) == remove_const(type)
3755
+ ```
3756
+
3757
+ is `true`, preserving their order.
3758
+
3759
+ *Throws:* `meta::exception` unless
3760
+
3761
+ - `annotations_of(item)` is a constant expression and
3762
+ - `dealias(type)` represents a type and `is_complete_type(type)` is
3763
+ `true`.
3764
+
3765
+ ### Value extraction <a id="meta.reflection.extract">[[meta.reflection.extract]]</a>
3766
+
3767
+ The `extract` function template may be used to extract a value out of a
3768
+ reflection when its type is known.
3769
+
3770
+ The following are defined for exposition only to aid in the
3771
+ specification of `extract`.
3772
+
3773
+ ``` cpp
3774
+ template<class T>
3775
+ consteval T extract-ref(info r); // exposition only
3776
+ ```
3777
+
3778
+ [*Note 1*: `T` is a reference type. — *end note*]
3779
+
3780
+ *Returns:* If `r` represents an object O, then a reference to O.
3781
+ Otherwise, a reference to the object declared, or referred to, by the
3782
+ variable represented by `r`.
3783
+
3784
+ *Throws:* `meta::exception` unless
3785
+
3786
+ - `r` represents a variable or object of type `U`,
3787
+ - `is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]>`
3788
+ is `true`, and \[*Note 1*: The intent is to allow only qualification
3789
+ conversion from `U` to `T`. — *end note*]
3790
+ - If `r` represents a variable, then either that variable is usable in
3791
+ constant expressions or its lifetime began within the core constant
3792
+ expression currently under evaluation.
3793
+
3794
+ ``` cpp
3795
+ template<class T>
3796
+ consteval T extract-member-or-function(info r); // exposition only
3797
+ ```
3798
+
3799
+ *Returns:*
3800
+
3801
+ - If `T` is a pointer type, then a pointer value pointing to the
3802
+ function represented by `r`.
3803
+ - Otherwise, a pointer-to-member value designating the non-static data
3804
+ member or function represented by `r`.
3805
+
3806
+ *Throws:* `meta::exception` unless
3807
+
3808
+ - `r` represents a non-static data member with type `X`, that is not a
3809
+ bit-field, that is a direct member of class `C`, `T` and `X C::*` are
3810
+ similar types [[conv.qual]], and `is_convertible_v<X C::*, T>` is
3811
+ `true`;
3812
+ - `r` represents an implicit object member function with type `F` or
3813
+ `F noexcept` that is a direct member of a class `C`, and `T` is
3814
+ `F C::*`; or
3815
+ - `r` represents a non-member function, static member function, or
3816
+ explicit object member function of function type `F` or `F noexcept`,
3817
+ and `T` is `F*`.
3818
+
3819
+ ``` cpp
3820
+ template<class T>
3821
+ consteval T extract-value(info r); // exposition only
3822
+ ```
3823
+
3824
+ Let `U` be the type of the value or object that `r` represents.
3825
+
3826
+ *Returns:* `static_cast<T>([:`R`:])`, where R is a constant expression
3827
+ of type `info` such that R` == r` is `true`.
3828
+
3829
+ *Throws:* `meta::exception` unless
3830
+
3831
+ - `U` is a pointer type, `T` and `U` are either similar [[conv.qual]] or
3832
+ both function pointer types, and `is_convertible_v<U, T>` is `true`,
3833
+ - `U` is not a pointer type and the cv-unqualified types of `T` and `U`
3834
+ are the same,
3835
+ - `U` is an array type, `T` is a pointer type, and the value `r`
3836
+ represents is convertible to `T`, or
3837
+ - `U` is a closure type, `T` is a function pointer type, and the value
3838
+ that `r` represents is convertible to `T`.
3839
+
3840
+ ``` cpp
3841
+ template<class T>
3842
+ consteval T extract(info r);
3843
+ ```
3844
+
3845
+ Let `U` be `remove_cv_t<T>`.
3846
+
3847
+ *Effects:* Equivalent to:
3848
+
3849
+ ``` cpp
3850
+ if constexpr (is_reference_type(^^T)) {
3851
+ return extract-ref<T>(r);
3852
+ } else if (is_nonstatic_data_member(r) || is_function(r)) {
3853
+ return extract-member-or-function<U>(r);
3854
+ } else {
3855
+ return extract-value<U>(constant_of(r));
3856
+ }
3857
+ ```
3858
+
3859
+ ### Reflection substitution <a id="meta.reflection.substitute">[[meta.reflection.substitute]]</a>
3860
+
3861
+ ``` cpp
3862
+ template<class R>
3863
+ concept reflection_range =
3864
+ ranges::input_range<R> &&
3865
+ same_as<ranges::range_value_t<R>, info> &&
3866
+ same_as<remove_cvref_t<ranges::range_reference_t<R>>, info>;
3867
+
3868
+ template<reflection_range R = initializer_list<info>>
3869
+ consteval bool can_substitute(info templ, R&& arguments);
3870
+ ```
3871
+
3872
+ Let `Z` be the template represented by `templ` and let `Args...` be a
3873
+ sequence of prvalue constant expressions that compute the reflections
3874
+ held by the elements of `arguments`, in order.
3875
+
3876
+ *Returns:* `true` if `Z<[:Args:]...>` is a valid
3877
+ *template-id*[[temp.names]] that does not name a function whose type
3878
+ contains an undeduced placeholder type. Otherwise, `false`.
3879
+
3880
+ *Throws:* `meta::exception` unless `templ` represents a template, and
3881
+ every reflection in `arguments` represents a construct usable as a
3882
+ template argument [[temp.arg]].
3883
+
3884
+ [*Note 1*: If forming `Z<[:Args:]...>` leads to a failure outside of
3885
+ the immediate context, the program is ill-formed. — *end note*]
3886
+
3887
+ ``` cpp
3888
+ template<reflection_range R = initializer_list<info>>
3889
+ consteval info substitute(info templ, R&& arguments);
3890
+ ```
3891
+
3892
+ Let `Z` be the template represented by `templ` and let `Args...` be a
3893
+ sequence of prvalue constant expressions that compute the reflections
3894
+ held by the elements of `arguments`, in order.
3895
+
3896
+ *Returns:* .
3897
+
3898
+ *Throws:* `meta::exception` unless `can_substitute(templ, arguments)` is
3899
+ `true`.
3900
+
3901
+ [*Note 2*: If forming `Z<[:Args:]...>` leads to a failure outside of
3902
+ the immediate context, the program is ill-formed. — *end note*]
3903
+
3904
+ [*Example 1*:
3905
+
3906
+ ``` cpp
3907
+ template<class T>
3908
+ auto fn1();
3909
+
3910
+ static_assert(!can_substitute(^^fn1, {^^int})); // OK
3911
+ constexpr info r1 = substitute(^^fn1, {^^int}); // error: fn1<int> contains an undeduced
3912
+ // placeholder type for its return type
3913
+
3914
+ template<class T>
3915
+ auto fn2() {
3916
+ static_assert(^^T != ^^int); // static assertion failed during instantiation of fn2<int>
3917
+ return 0;
3918
+ }
3919
+
3920
+ constexpr bool r2 = can_substitute(^^fn2, {^^int}); // error: instantiation of body of fn2<int>
3921
+ // is needed to deduce return type
3922
+ ```
3923
+
3924
+ — *end example*]
3925
+
3926
+ [*Example 2*:
3927
+
3928
+ ``` cpp
3929
+ consteval info to_integral_constant(unsigned i) {
3930
+ return substitute(^^integral_constant, {^^unsigned, reflect_constant(i)});
3931
+ }
3932
+ constexpr info r = to_integral_constant(2); // OK, r represents the type
3933
+ // integral_constant<unsigned, 2>
3934
+ ```
3935
+
3936
+ — *end example*]
3937
+
3938
+ ### Expression result reflection <a id="meta.reflection.result">[[meta.reflection.result]]</a>
3939
+
3940
+ ``` cpp
3941
+ template<class T>
3942
+ consteval info reflect_constant(T expr);
3943
+ ```
3944
+
3945
+ *Mandates:* `is_copy_constructible_v<T>` is `true` and `T` is a
3946
+ cv-unqualified structural type [[temp.param]] that is not a reference
3947
+ type.
3948
+
3949
+ Let V be:
3950
+
3951
+ - if `T` is a class type, then an object that is
3952
+ template-argument-equivalent to the value of `expr`;
3953
+ - otherwise, the value of `expr`.
3954
+
3955
+ Let `TCls` be the invented template:
3956
+
3957
+ ``` cpp
3958
+ template<T P> struct TCls;
3959
+ ```
3960
+
3961
+ *Returns:* `template_arguments_of(``)[0]`.
3962
+
3963
+ [*Note 1*: This is a reflection of an object for class types, and a
3964
+ reflection of a value otherwise. — *end note*]
3965
+
3966
+ *Throws:* `meta::exception` unless the *template-id* `TCls<`V`>` would
3967
+ be valid.
3968
+
3969
+ [*Example 1*:
3970
+
3971
+ ``` cpp
3972
+ template<auto D>
3973
+ struct A { };
3974
+
3975
+ struct N { int x; };
3976
+ struct K { char const* p; };
3977
+
3978
+ constexpr info r1 = reflect_constant(42);
3979
+ static_assert(is_value(r1));
3980
+ static_assert(r1 == template_arguments_of(^^A<42>)[0]);
3981
+
3982
+ constexpr info r2 = reflect_constant(N{42});
3983
+ static_assert(is_object(r2));
3984
+ static_assert(r2 == template_arguments_of(^^A<N{42}>)[0]);
3985
+
3986
+ constexpr info r3 = reflect_constant(K{nullptr}); // OK
3987
+ constexpr info r4 = reflect_constant(K{"ebab"}); // error: constituent pointer
3988
+ // points to string literal
3989
+ ```
3990
+
3991
+ — *end example*]
3992
+
3993
+ ``` cpp
3994
+ template<class T>
3995
+ consteval info reflect_object(T& expr);
3996
+ ```
3997
+
3998
+ *Mandates:* `T` is an object type.
3999
+
4000
+ *Returns:* A reflection of the object designated by `expr`.
4001
+
4002
+ *Throws:* `meta::exception` unless `expr` is suitable for use as a
4003
+ constant template argument for a constant template parameter of type
4004
+ `T&` [[temp.arg.nontype]].
4005
+
4006
+ ``` cpp
4007
+ template<class T>
4008
+ consteval info reflect_function(T& fn);
4009
+ ```
4010
+
4011
+ *Mandates:* `T` is a function type.
4012
+
4013
+ *Returns:* A reflection of the function designated by `fn`.
4014
+
4015
+ *Throws:* `meta::exception` unless `fn` is suitable for use as a
4016
+ constant template argument for a constant template parameter of type
4017
+ `T&` [[temp.arg.nontype]].
4018
+
4019
+ ### Reflection class definition generation <a id="meta.reflection.define.aggregate">[[meta.reflection.define.aggregate]]</a>
4020
+
4021
+ ``` cpp
4022
+ namespace std::meta {
4023
+ struct data_member_options {
4024
+ struct name-type { // exposition only
4025
+ template<class T>
4026
+ requires constructible_from<u8string, T>
4027
+ consteval name-type(T&&);
4028
+
4029
+ template<class T>
4030
+ requires constructible_from<string, T>
4031
+ consteval name-type(T&&);
4032
+
4033
+ private:
4034
+ variant<u8string, string> contents; // exposition only
4035
+ };
4036
+
4037
+ optional<name-type> name;
4038
+ optional<int> alignment;
4039
+ optional<int> bit_width;
4040
+ bool no_unique_address = false;
4041
+ };
4042
+ }
4043
+ ```
4044
+
4045
+ The classes `data_member_options` and `data_member_options::name-type`
4046
+ are consteval-only types [[basic.types.general]], and are not structural
4047
+ types [[temp.param]].
4048
+
4049
+ ``` cpp
4050
+ template<class T>
4051
+ requires constructible_from<u8string, T>
4052
+ consteval name-type(T&& value);
4053
+ ```
4054
+
4055
+ *Effects:* Initializes *contents* with
4056
+ `u8string(std::forward<T>(value))`.
4057
+
4058
+ ``` cpp
4059
+ template<class T>
4060
+ requires constructible_from<string, T>
4061
+ consteval name-type(T&& value);
4062
+ ```
4063
+
4064
+ *Effects:* Initializes *contents* with `string(std::forward<T>(value))`.
4065
+
4066
+ [*Note 1*:
4067
+
4068
+ The class *name-type* allows the function `data_member_spec` to accept
4069
+ an ordinary string literal (or `string_view`, `string`, etc.) or a UTF-8
4070
+ string literal (or `u8string_view`, `u8string`, etc.) equally well.
4071
+
4072
+ [*Example 1*:
4073
+
4074
+ consteval void fn() {
4075
+ data_member_options o1 = {.name = "ordinary_literal_encoding"};
4076
+ data_member_options o2 = {.name = u8"utf8_encoding"};
4077
+ }
4078
+
4079
+ — *end example*]
4080
+
4081
+ — *end note*]
4082
+
4083
+ ``` cpp
4084
+ consteval info data_member_spec(info type, data_member_options options);
4085
+ ```
4086
+
4087
+ *Returns:* A reflection of a data member description
4088
+ (T, N, A, W, *NUA*)[[class.mem.general]] where
4089
+
4090
+ - T is the type represented by `dealias(type)`,
4091
+ - N is either the identifier encoded by `options.name` or $\bot$ if
4092
+ `options.name` does not contain a value,
4093
+ - A is either the alignment value held by `options.alignment` or $\bot$
4094
+ if `options.alignment` does not contain a value,
4095
+ - W is either the value held by `options.bit_width` or $\bot$ if
4096
+ `options.bit_width` does not contain a value, and
4097
+ - *NUA* is the value held by `options.no_unique_address`.
4098
+
4099
+ [*Note 2*: The returned reflection value is primarily useful in
4100
+ conjunction with `define_aggregate`; it can also be queried by certain
4101
+ other functions in `std::meta` (e.g., `type_of`,
4102
+ `identifier_of`). — *end note*]
4103
+
4104
+ *Throws:* `meta::exception` unless the following conditions are met:
4105
+
4106
+ - `dealias(type)` represents either an object type or a reference type;
4107
+ - if `options.name` contains a value, then:
4108
+ - `holds_alternative<u8string>(options.name->`*`contents`*`)` is
4109
+ `true` and `get<u8string>(options.name->`*`contents`*`)` contains a
4110
+ valid identifier [[lex.name]] that is not a keyword [[lex.key]] when
4111
+ interpreted with UTF-8, or
4112
+ - `holds_alternative<string>(options.name->`*`contents`*`)` is `true`
4113
+ and `get<string>(options.name->`*`contents`*`)` contains a valid
4114
+ identifier [[lex.name]] that is not a keyword [[lex.key]] when
4115
+ interpreted with the ordinary literal encoding;
4116
+
4117
+ \[*Note 1*: The name corresponds to the spelling of an
4118
+ identifier token after phase 6 of translation [[lex.phases]].
4119
+ Lexical constructs like
4120
+ *universal-character-name*s [[lex.universal.char]] are not
4121
+ processed and will cause evaluation to fail. For example,
4122
+ `R"(\u03B1)"` is an invalid identifier and is not interpreted as
4123
+ `"`α`"`. — *end note*]
4124
+ - if `options.name` does not contain a value, then `options.bit_width`
4125
+ contains a value;
4126
+ - if `options.bit_width` contains a value V, then
4127
+ - `is_integral_type(type) || is_enum_type(type)` is `true`,
4128
+ - `options.alignment` does not contain a value,
4129
+ - `options.no_unique_address` is `false`, and
4130
+ - if V equals `0`, then `options.name` does not contain a value; and
4131
+ - if `options.alignment` contains a value, it is an alignment
4132
+ value [[basic.align]] not less than `alignment_of(type)`.
4133
+
4134
+ ``` cpp
4135
+ consteval bool is_data_member_spec(info r);
4136
+ ```
4137
+
4138
+ *Returns:* `true` if `r` represents a data member description.
4139
+ Otherwise, `false`.
4140
+
4141
+ ``` cpp
4142
+ template<reflection_range R = initializer_list<info>>
4143
+ consteval info define_aggregate(info class_type, R&& mdescrs);
4144
+ ```
4145
+
4146
+ Let C be the class represented by `class_type` and $r_K$ be the Kᵗʰ
4147
+ reflection value in `mdescrs`. For every $r_K$ in `mdescrs`, let
4148
+ $(T_K, N_K, A_K, W_K, *NUA*_K)$ be the corresponding data member
4149
+ description represented by $r_K$.
4150
+
4151
+ - C is incomplete from every point in the evaluation context;
4152
+ \[*Note 2*: C can be a class template specialization for which there
4153
+ is a reachable definition of the class template. In this case, the
4154
+ injected declaration is an explicit specialization. — *end note*]
4155
+ - `is_data_member_spec(`$r_K$`)` is `true` for every $r_K$;
4156
+ - `is_complete_type(`$T_K$`)` is `true` for every $r_K$; and
4157
+ - for every pair $(r_K, r_L)$ where K < L, if $N_K$ is not $\bot$ and
4158
+ $N_L$ is not $\bot$, then either:
4159
+ - $N_K$` != `$N_L$ is `true` or
4160
+ - $N_K$` == u8"_"` is `true`. \[*Note 3*: Every provided identifier is
4161
+ unique or `"_"`. — *end note*]
4162
+
4163
+ *Effects:* Produces an injected declaration D[[expr.const]] that defines
4164
+ C and has properties as follows:
4165
+
4166
+ - The target scope of D is the scope to which C
4167
+ belongs [[basic.scope.scope]].
4168
+ - The locus of D follows immediately after the core constant expression
4169
+ currently under evaluation.
4170
+ - The characteristic sequence of D[[expr.const]] is the sequence of
4171
+ reflection values $r_K$.
4172
+ - If C is a specialization of a templated class T, and C is not a local
4173
+ class, then D is an explicit specialization of T.
4174
+ - For each $r_K$, there is a corresponding entity $M_K$ belonging to the
4175
+ class scope of D with the following properties:
4176
+ - If $N_K$ is $\bot$, $M_K$ is an unnamed bit-field. Otherwise, $M_K$
4177
+ is a non-static data member whose name is the identifier determined
4178
+ by the character sequence encoded by $N_K$ in UTF-8.
4179
+ - The type of $M_K$ is $T_K$.
4180
+ - $M_K$ is declared with the attribute `[[no_unique_address]]` if and
4181
+ only if *NUA*_K is `true`.
4182
+ - If $W_K$ is not $\bot$, $M_K$ is a bit-field whose width is that
4183
+ value. Otherwise, $M_K$ is not a bit-field.
4184
+ - If $A_K$ is not $\bot$, $M_K$ has the *alignment-specifier*
4185
+ `alignas(`$A_K$`)`. Otherwise, $M_K$ has no *alignment-specifier*.
4186
+ - For every $r_L$ in `mdescrs` such that K < L, the declaration
4187
+ corresponding to $r_K$ precedes the declaration corresponding to
4188
+ $r_L$.
4189
+
4190
+ *Returns:* `class_type`.
4191
+
4192
+ ### Reflection type traits <a id="meta.reflection.traits">[[meta.reflection.traits]]</a>
4193
+
4194
+ This subclause specifies `consteval` functions to query the properties
4195
+ of types [[meta.unary]], query the relationships between types
4196
+ [[meta.rel]], or transform types [[meta.trans]], during program
4197
+ translation. Each `consteval` function declared in this class has an
4198
+ associated class template declared elsewhere in this document.
4199
+
4200
+ Every function and function template declared in this subclause throws
4201
+ an exception of type `meta::exception` unless the following conditions
4202
+ are met:
4203
+
4204
+ - For every parameter `p` of type `info`, `is_type(p)` is `true`.
4205
+ - For every parameter `r` whose type is constrained on
4206
+ `reflection_range`, `ranges::{}all_of({}r, is_type)` is `true`.
4207
+
4208
+ ``` cpp
4209
+ // associated with [meta.unary.cat], primary type categories
4210
+ consteval bool is_void_type(info type);
4211
+ consteval bool is_null_pointer_type(info type);
4212
+ consteval bool is_integral_type(info type);
4213
+ consteval bool is_floating_point_type(info type);
4214
+ consteval bool is_array_type(info type);
4215
+ consteval bool is_pointer_type(info type);
4216
+ consteval bool is_lvalue_reference_type(info type);
4217
+ consteval bool is_rvalue_reference_type(info type);
4218
+ consteval bool is_member_object_pointer_type(info type);
4219
+ consteval bool is_member_function_pointer_type(info type);
4220
+ consteval bool is_enum_type(info type);
4221
+ consteval bool is_union_type(info type);
4222
+ consteval bool is_class_type(info type);
4223
+ consteval bool is_function_type(info type);
4224
+ consteval bool is_reflection_type(info type);
4225
+
4226
+ // associated with [meta.unary.comp], composite type categories
4227
+ consteval bool is_reference_type(info type);
4228
+ consteval bool is_arithmetic_type(info type);
4229
+ consteval bool is_fundamental_type(info type);
4230
+ consteval bool is_object_type(info type);
4231
+ consteval bool is_scalar_type(info type);
4232
+ consteval bool is_compound_type(info type);
4233
+ consteval bool is_member_pointer_type(info type);
4234
+
4235
+ // associated with [meta.unary.prop], type properties
4236
+ consteval bool is_const_type(info type);
4237
+ consteval bool is_volatile_type(info type);
4238
+ consteval bool is_trivially_copyable_type(info type);
4239
+ consteval bool is_trivially_relocatable_type(info type);
4240
+ consteval bool is_replaceable_type(info type);
4241
+ consteval bool is_standard_layout_type(info type);
4242
+ consteval bool is_empty_type(info type);
4243
+ consteval bool is_polymorphic_type(info type);
4244
+ consteval bool is_abstract_type(info type);
4245
+ consteval bool is_final_type(info type);
4246
+ consteval bool is_aggregate_type(info type);
4247
+ consteval bool is_consteval_only_type(info type);
4248
+ consteval bool is_signed_type(info type);
4249
+ consteval bool is_unsigned_type(info type);
4250
+ consteval bool is_bounded_array_type(info type);
4251
+ consteval bool is_unbounded_array_type(info type);
4252
+ consteval bool is_scoped_enum_type(info type);
4253
+
4254
+ template<reflection_range R = initializer_list<info>>
4255
+ consteval bool is_constructible_type(info type, R&& type_args);
4256
+ consteval bool is_default_constructible_type(info type);
4257
+ consteval bool is_copy_constructible_type(info type);
4258
+ consteval bool is_move_constructible_type(info type);
4259
+
4260
+ consteval bool is_assignable_type(info type_dst, info type_src);
4261
+ consteval bool is_copy_assignable_type(info type);
4262
+ consteval bool is_move_assignable_type(info type);
4263
+
4264
+ consteval bool is_swappable_with_type(info type1, info type2);
4265
+ consteval bool is_swappable_type(info type);
4266
+
4267
+ consteval bool is_destructible_type(info type);
4268
+
4269
+ template<reflection_range R = initializer_list<info>>
4270
+ consteval bool is_trivially_constructible_type(info type, R&& type_args);
4271
+ consteval bool is_trivially_default_constructible_type(info type);
4272
+ consteval bool is_trivially_copy_constructible_type(info type);
4273
+ consteval bool is_trivially_move_constructible_type(info type);
4274
+
4275
+ consteval bool is_trivially_assignable_type(info type_dst, info type_src);
4276
+ consteval bool is_trivially_copy_assignable_type(info type);
4277
+ consteval bool is_trivially_move_assignable_type(info type);
4278
+ consteval bool is_trivially_destructible_type(info type);
4279
+
4280
+ template<reflection_range R = initializer_list<info>>
4281
+ consteval bool is_nothrow_constructible_type(info type, R&& type_args);
4282
+ consteval bool is_nothrow_default_constructible_type(info type);
4283
+ consteval bool is_nothrow_copy_constructible_type(info type);
4284
+ consteval bool is_nothrow_move_constructible_type(info type);
4285
+
4286
+ consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
4287
+ consteval bool is_nothrow_copy_assignable_type(info type);
4288
+ consteval bool is_nothrow_move_assignable_type(info type);
4289
+
4290
+ consteval bool is_nothrow_swappable_with_type(info type1, info type2);
4291
+ consteval bool is_nothrow_swappable_type(info type);
4292
+
4293
+ consteval bool is_nothrow_destructible_type(info type);
4294
+ consteval bool is_nothrow_relocatable_type(info type);
4295
+
4296
+ consteval bool is_implicit_lifetime_type(info type);
4297
+
4298
+ consteval bool has_virtual_destructor(info type);
4299
+
4300
+ consteval bool has_unique_object_representations(info type);
4301
+
4302
+ consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
4303
+ consteval bool reference_converts_from_temporary(info type_dst, info type_src);
4304
+
4305
+ // associated with [meta.rel], type relations
4306
+ consteval bool is_same_type(info type1, info type2);
4307
+ consteval bool is_base_of_type(info type_base, info type_derived);
4308
+ consteval bool is_virtual_base_of_type(info type_base, info type_derived);
4309
+ consteval bool is_convertible_type(info type_src, info type_dst);
4310
+ consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
4311
+ consteval bool is_layout_compatible_type(info type1, info type2);
4312
+ consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
4313
+
4314
+ template<reflection_range R = initializer_list<info>>
4315
+ consteval bool is_invocable_type(info type, R&& type_args);
4316
+ template<reflection_range R = initializer_list<info>>
4317
+ consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
4318
+
4319
+ template<reflection_range R = initializer_list<info>>
4320
+ consteval bool is_nothrow_invocable_type(info type, R&& type_args);
4321
+ template<reflection_range R = initializer_list<info>>
4322
+ consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
4323
+
4324
+ // associated with [meta.trans.cv], const-volatile modifications
4325
+ consteval info remove_const(info type);
4326
+ consteval info remove_volatile(info type);
4327
+ consteval info remove_cv(info type);
4328
+ consteval info add_const(info type);
4329
+ consteval info add_volatile(info type);
4330
+ consteval info add_cv(info type);
4331
+
4332
+ // associated with [meta.trans.ref], reference modifications
4333
+ consteval info remove_reference(info type);
4334
+ consteval info add_lvalue_reference(info type);
4335
+ consteval info add_rvalue_reference(info type);
4336
+
4337
+ // associated with [meta.trans.sign], sign modifications
4338
+ consteval info make_signed(info type);
4339
+ consteval info make_unsigned(info type);
4340
+
4341
+ // associated with [meta.trans.arr], array modifications
4342
+ consteval info remove_extent(info type);
4343
+ consteval info remove_all_extents(info type);
4344
+
4345
+ // associated with [meta.trans.ptr], pointer modifications
4346
+ consteval info remove_pointer(info type);
4347
+ consteval info add_pointer(info type);
4348
+
4349
+ // associated with [meta.trans.other], other transformations
4350
+ consteval info remove_cvref(info type);
4351
+ consteval info decay(info type);
4352
+ template<reflection_range R = initializer_list<info>>
4353
+ consteval info common_type(R&& type_args);
4354
+ template<reflection_range R = initializer_list<info>>
4355
+ consteval info common_reference(R&& type_args);
4356
+ consteval info underlying_type(info type);
4357
+ template<reflection_range R = initializer_list<info>>
4358
+ consteval info invoke_result(info type, R&& type_args);
4359
+ consteval info unwrap_reference(info type);
4360
+ consteval info unwrap_ref_decay(info type);
4361
+ ```
4362
+
4363
+ Each function or function template declared above has the following
4364
+ behavior based on the signature and return type of that function or
4365
+ function template.
4366
+
4367
+ [*Note 1*: The associated class template need not be
4368
+ instantiated. — *end note*]
4369
+
4370
+ [*Note 2*: For those functions or function templates which return a
4371
+ reflection, that reflection always represents a type and never a type
4372
+ alias. — *end note*]
4373
+
4374
+ [*Note 3*: If `t` is a reflection of the type `int` and `u` is a
4375
+ reflection of an alias to the type `int`, then `t == u` is `false` but
4376
+ `is_same_type(t, u)` is `true`. Also, `t == dealias(u)` is
4377
+ `true`. — *end note*]
4378
+
4379
+ ``` cpp
4380
+ consteval size_t rank(info type);
4381
+ ```
4382
+
4383
+ *Returns:* `rank_v<`T`>`, where T is the type represented by
4384
+ `dealias(type)`.
4385
+
4386
+ ``` cpp
4387
+ consteval size_t extent(info type, unsigned i = 0);
4388
+ ```
4389
+
4390
+ *Returns:* `extent_v<`T`, `I`>`, where T is the type represented by
4391
+ `dealias(type)` and I is a constant equal to `i`.
4392
+
4393
+ ``` cpp
4394
+ consteval size_t tuple_size(info type);
4395
+ ```
4396
+
4397
+ *Returns:* `tuple_size_v<`T`>`, where T is the type represented by
4398
+ `dealias(type)`.
4399
+
4400
+ ``` cpp
4401
+ consteval info tuple_element(size_t index, info type);
4402
+ ```
4403
+
4404
+ *Returns:* A reflection representing the type denoted by
4405
+ `tuple_element_t<`I`, `T`>`, where T is the type represented by
4406
+ `dealias(type)` and I is a constant equal to `index`.
4407
+
4408
+ ``` cpp
4409
+ consteval size_t variant_size(info type);
4410
+ ```
4411
+
4412
+ *Returns:* `variant_size_v<`T`>`, where T is the type represented by
4413
+ `dealias(type)`.
4414
+
4415
+ ``` cpp
4416
+ consteval info variant_alternative(size_t index, info type);
4417
+ ```
4418
+
4419
+ *Returns:* A reflection representing the type denoted by
4420
+ `variant_alternative_t<`I`, `T`>`, where T is the type represented by
4421
+ `dealias(type)` and I is a constant equal to `index`.
4422
+
4423
+ ``` cpp
4424
+ consteval strong_ordering type_order(info t1, info t2);
4425
+ ```
4426
+
4427
+ *Returns:* `type_order_v<`T₁`, `T₂`>`, where T₁ and T₂ are the types
4428
+ represented by `dealias(t1)` and `dealias(t2)`, respectively.
4429
+
4430
  ## Compile-time rational arithmetic <a id="ratio">[[ratio]]</a>
4431
 
4432
+ ### General <a id="ratio.general">[[ratio.general]]</a>
4433
 
4434
  Subclause  [[ratio]] describes the ratio library. It provides a class
4435
  template `ratio` which exactly represents any finite rational number
4436
  with a numerator and denominator representable by compile-time constants
4437
  of type `intmax_t`.
 
4475
  constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
4476
  template<class R1, class R2>
4477
  constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
4478
 
4479
  // [ratio.si], convenience SI typedefs
4480
+ using quecto = ratio<1, 1'000'000'000'000'000'000'000'000'000'000>; // see below
4481
+ using ronto = ratio<1, 1'000'000'000'000'000'000'000'000'000>; // see below
4482
  using yocto = ratio<1, 1'000'000'000'000'000'000'000'000>; // see below
4483
  using zepto = ratio<1, 1'000'000'000'000'000'000'000>; // see below
4484
  using atto = ratio<1, 1'000'000'000'000'000'000>;
4485
  using femto = ratio<1, 1'000'000'000'000'000>;
4486
  using pico = ratio<1, 1'000'000'000'000>;
 
4497
  using tera = ratio< 1'000'000'000'000, 1>;
4498
  using peta = ratio< 1'000'000'000'000'000, 1>;
4499
  using exa = ratio< 1'000'000'000'000'000'000, 1>;
4500
  using zetta = ratio< 1'000'000'000'000'000'000'000, 1>; // see below
4501
  using yotta = ratio< 1'000'000'000'000'000'000'000'000, 1>; // see below
4502
+ using ronna = ratio< 1'000'000'000'000'000'000'000'000'000, 1>; // see below
4503
+ using quetta = ratio<1'000'000'000'000'000'000'000'000'000'000, 1>; // see below
4504
  }
4505
  ```
4506
 
4507
  ### Class template `ratio` <a id="ratio.ratio">[[ratio.ratio]]</a>
4508
 
 
4621
  struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };
4622
  ```
4623
 
4624
  ### SI types for `ratio` <a id="ratio.si">[[ratio.si]]</a>
4625
 
4626
+ For each of the *typedef-name*s `quecto`, `ronto`, `yocto`, `zepto`,
4627
+ `zetta`, `yotta`, `ronna`, and `quetta`, if both of the constants used
4628
+ in its specification are representable by `intmax_t`, the typedef is
4629
+ defined; if either of the constants is not representable by `intmax_t`,
4630
+ the typedef is not defined.
4631
 
4632
  <!-- Link reference definitions -->
4633
  [array]: containers.md#array
4634
+ [basic.align]: basic.md#basic.align
4635
  [basic.compound]: basic.md#basic.compound
4636
  [basic.fundamental]: basic.md#basic.fundamental
4637
+ [basic.life]: basic.md#basic.life
4638
+ [basic.link]: basic.md#basic.link
4639
+ [basic.lookup.argdep]: basic.md#basic.lookup.argdep
4640
+ [basic.scope.param]: basic.md#basic.scope.param
4641
+ [basic.scope.scope]: basic.md#basic.scope.scope
4642
+ [basic.stc]: basic.md#basic.stc
4643
+ [basic.stc.general]: basic.md#basic.stc.general
4644
  [basic.type.qualifier]: basic.md#basic.type.qualifier
4645
  [basic.types]: basic.md#basic.types
4646
  [basic.types.general]: basic.md#basic.types.general
4647
  [class.abstract]: class.md#class.abstract
4648
+ [class.access.base]: class.md#class.access.base
4649
+ [class.conv.fct]: class.md#class.conv.fct
4650
  [class.dtor]: class.md#class.dtor
4651
+ [class.inhctor.init]: class.md#class.inhctor.init
4652
  [class.mem]: class.md#class.mem
4653
+ [class.mem.general]: class.md#class.mem.general
4654
  [class.pre]: class.md#class.pre
4655
  [class.prop]: class.md#class.prop
4656
  [class.temporary]: basic.md#class.temporary
4657
+ [class.union.anon]: class.md#class.union.anon
4658
  [class.virtual]: class.md#class.virtual
4659
+ [const.wrap.class]: #const.wrap.class
4660
+ [conv.qual]: expr.md#conv.qual
4661
  [conv.rank]: basic.md#conv.rank
4662
  [dcl.array]: dcl.md#dcl.array
4663
  [dcl.enum]: dcl.md#dcl.enum
4664
+ [dcl.fct]: dcl.md#dcl.fct
4665
+ [dcl.fct.def.default]: dcl.md#dcl.fct.def.default
4666
+ [dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
4667
+ [dcl.fct.default]: dcl.md#dcl.fct.default
4668
  [dcl.init.aggr]: dcl.md#dcl.init.aggr
4669
+ [dcl.link]: dcl.md#dcl.link
4670
+ [dcl.pre]: dcl.md#dcl.pre
4671
  [dcl.ref]: dcl.md#dcl.ref
4672
+ [dcl.typedef]: dcl.md#dcl.typedef
4673
  [declval]: utilities.md#declval
4674
  [defns.referenceable]: intro.md#defns.referenceable
4675
+ [enum]: dcl.md#enum
4676
+ [except.spec]: except.md#except.spec
4677
  [expr.alignof]: expr.md#expr.alignof
4678
+ [expr.call]: expr.md#expr.call
4679
+ [expr.const]: expr.md#expr.const
4680
+ [expr.prim.lambda.closure]: expr.md#expr.prim.lambda.closure
4681
+ [expr.prim.splice]: expr.md#expr.prim.splice
4682
  [expr.type]: expr.md#expr.type
4683
  [expr.unary.noexcept]: expr.md#expr.unary.noexcept
 
4684
  [functional.syn]: utilities.md#functional.syn
4685
+ [intro.execution]: basic.md#intro.execution
4686
+ [intro.object]: basic.md#intro.object
4687
  [intseq]: #intseq
4688
  [intseq.general]: #intseq.general
4689
  [intseq.intseq]: #intseq.intseq
4690
  [intseq.make]: #intseq.make
4691
+ [lex.key]: lex.md#lex.key
4692
+ [lex.name]: lex.md#lex.name
4693
+ [lex.string]: lex.md#lex.string
4694
  [meta]: #meta
4695
  [meta.const.eval]: #meta.const.eval
4696
+ [meta.define.static]: #meta.define.static
4697
  [meta.general]: #meta.general
4698
  [meta.help]: #meta.help
4699
  [meta.logical]: #meta.logical
4700
  [meta.member]: #meta.member
4701
+ [meta.reflection]: #meta.reflection
4702
+ [meta.reflection.access.context]: #meta.reflection.access.context
4703
+ [meta.reflection.access.queries]: #meta.reflection.access.queries
4704
+ [meta.reflection.annotation]: #meta.reflection.annotation
4705
+ [meta.reflection.define.aggregate]: #meta.reflection.define.aggregate
4706
+ [meta.reflection.exception]: #meta.reflection.exception
4707
+ [meta.reflection.extract]: #meta.reflection.extract
4708
+ [meta.reflection.layout]: #meta.reflection.layout
4709
+ [meta.reflection.member.queries]: #meta.reflection.member.queries
4710
+ [meta.reflection.names]: #meta.reflection.names
4711
+ [meta.reflection.operators]: #meta.reflection.operators
4712
+ [meta.reflection.queries]: #meta.reflection.queries
4713
+ [meta.reflection.result]: #meta.reflection.result
4714
+ [meta.reflection.substitute]: #meta.reflection.substitute
4715
+ [meta.reflection.traits]: #meta.reflection.traits
4716
  [meta.rel]: #meta.rel
4717
  [meta.rqmts]: #meta.rqmts
4718
+ [meta.string.literal]: #meta.string.literal
4719
  [meta.summary]: #meta.summary
4720
+ [meta.syn]: #meta.syn
4721
  [meta.trans]: #meta.trans
4722
  [meta.trans.arr]: #meta.trans.arr
4723
  [meta.trans.cv]: #meta.trans.cv
4724
  [meta.trans.general]: #meta.trans.general
4725
  [meta.trans.other]: #meta.trans.other
 
4732
  [meta.unary.comp]: #meta.unary.comp
4733
  [meta.unary.general]: #meta.unary.general
4734
  [meta.unary.prop]: #meta.unary.prop
4735
  [meta.unary.prop.query]: #meta.unary.prop.query
4736
  [namespace.std]: library.md#namespace.std
4737
+ [namespace.udecl]: dcl.md#namespace.udecl
4738
+ [over.literal]: over.md#over.literal
4739
+ [over.oper]: over.md#over.oper
4740
  [ratio]: #ratio
4741
  [ratio.arithmetic]: #ratio.arithmetic
4742
  [ratio.comparison]: #ratio.comparison
4743
  [ratio.general]: #ratio.general
4744
  [ratio.ratio]: #ratio.ratio
 
4746
  [ratio.syn]: #ratio.syn
4747
  [special]: class.md#special
4748
  [stmt.return]: stmt.md#stmt.return
4749
  [support.signal]: support.md#support.signal
4750
  [swappable.requirements]: library.md#swappable.requirements
4751
+ [temp.arg]: temp.md#temp.arg
4752
+ [temp.arg.nontype]: temp.md#temp.arg.nontype
4753
+ [temp.dep.constexpr]: temp.md#temp.dep.constexpr
4754
+ [temp.inst]: temp.md#temp.inst
4755
+ [temp.names]: temp.md#temp.names
4756
+ [temp.param]: temp.md#temp.param
4757
+ [temp.pre]: temp.md#temp.pre
4758
+ [temp.spec.partial]: temp.md#temp.spec.partial
4759
+ [temp.type]: temp.md#temp.type
4760
+ [term.implicit.lifetime.type]: basic.md#term.implicit.lifetime.type
4761
  [term.object.type]: basic.md#term.object.type
4762
  [term.odr.use]: basic.md#term.odr.use
4763
  [term.scalar.type]: basic.md#term.scalar.type
4764
  [term.standard.layout.type]: basic.md#term.standard.layout.type
4765
+ [term.trivial.type]: future.md#term.trivial.type
4766
  [term.trivially.copyable.type]: basic.md#term.trivially.copyable.type
4767
  [term.unevaluated.operand]: expr.md#term.unevaluated.operand
4768
  [tuple.apply]: utilities.md#tuple.apply
4769
  [type.traits]: #type.traits
4770
  [type.traits.general]: #type.traits.general