From Jason Turner

[meta.reflection]

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

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3_brtuk2/{from.md → to.md} +2857 -0
tmp/tmp3_brtuk2/{from.md → to.md} RENAMED
@@ -0,0 +1,2857 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Reflection <a id="meta.reflection">[[meta.reflection]]</a>
2
+
3
+ ### Header `<meta>` synopsis <a id="meta.syn">[[meta.syn]]</a>
4
+
5
+ ``` cpp
6
+ #include <initializer_list> // see [initializer.list.syn]
7
+
8
+ namespace std {
9
+ // [meta.string.literal], checking string literals
10
+ consteval bool is_string_literal(const char* p);
11
+ consteval bool is_string_literal(const wchar_t* p);
12
+ consteval bool is_string_literal(const char8_t* p);
13
+ consteval bool is_string_literal(const char16_t* p);
14
+ consteval bool is_string_literal(const char32_t* p);
15
+
16
+ // [meta.define.static], promoting to static storage
17
+ namespace meta {
18
+ template<ranges::input_range R>
19
+ consteval info reflect_constant_string(R&& r);
20
+ template<ranges::input_range R>
21
+ consteval info reflect_constant_array(R&& r);
22
+ }
23
+ template<ranges::input_range R>
24
+ consteval const ranges::range_value_t<R>* define_static_string(R&& r);
25
+ template<ranges::input_range R>
26
+ consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
27
+ template<class T>
28
+ consteval const remove_cvref_t<T>* define_static_object(T&& r);
29
+ }
30
+
31
+ namespace std::meta {
32
+ using info = decltype(^^::);
33
+
34
+ // [meta.reflection.exception], class exception
35
+ class exception;
36
+
37
+ // [meta.reflection.operators], operator representations
38
+ enum class operators {
39
+ see below;
40
+ };
41
+ using enum operators;
42
+ consteval operators operator_of(info r);
43
+ consteval string_view symbol_of(operators op);
44
+ consteval u8string_view u8symbol_of(operators op);
45
+
46
+ // [meta.reflection.names], reflection names and locations
47
+ consteval bool has_identifier(info r);
48
+
49
+ consteval string_view identifier_of(info r);
50
+ consteval u8string_view u8identifier_of(info r);
51
+
52
+ consteval string_view display_string_of(info r);
53
+ consteval u8string_view u8display_string_of(info r);
54
+
55
+ consteval source_location source_location_of(info r);
56
+
57
+ // [meta.reflection.queries], reflection queries
58
+ consteval info type_of(info r);
59
+ consteval info object_of(info r);
60
+ consteval info constant_of(info r);
61
+
62
+ consteval bool is_public(info r);
63
+ consteval bool is_protected(info r);
64
+ consteval bool is_private(info r);
65
+
66
+ consteval bool is_virtual(info r);
67
+ consteval bool is_pure_virtual(info r);
68
+ consteval bool is_override(info r);
69
+ consteval bool is_final(info r);
70
+
71
+ consteval bool is_deleted(info r);
72
+ consteval bool is_defaulted(info r);
73
+ consteval bool is_user_provided(info r);
74
+ consteval bool is_user_declared(info r);
75
+ consteval bool is_explicit(info r);
76
+ consteval bool is_noexcept(info r);
77
+
78
+ consteval bool is_bit_field(info r);
79
+ consteval bool is_enumerator(info r);
80
+ consteval bool is_annotation(info r);
81
+
82
+ consteval bool is_const(info r);
83
+ consteval bool is_volatile(info r);
84
+ consteval bool is_mutable_member(info r);
85
+ consteval bool is_lvalue_reference_qualified(info r);
86
+ consteval bool is_rvalue_reference_qualified(info r);
87
+
88
+ consteval bool has_static_storage_duration(info r);
89
+ consteval bool has_thread_storage_duration(info r);
90
+ consteval bool has_automatic_storage_duration(info r);
91
+
92
+ consteval bool has_internal_linkage(info r);
93
+ consteval bool has_module_linkage(info r);
94
+ consteval bool has_external_linkage(info r);
95
+ consteval bool has_c_language_linkage(info r);
96
+ consteval bool has_linkage(info r);
97
+
98
+ consteval bool is_complete_type(info r);
99
+ consteval bool is_enumerable_type(info r);
100
+
101
+ consteval bool is_variable(info r);
102
+ consteval bool is_type(info r);
103
+ consteval bool is_namespace(info r);
104
+ consteval bool is_type_alias(info r);
105
+ consteval bool is_namespace_alias(info r);
106
+
107
+ consteval bool is_function(info r);
108
+ consteval bool is_conversion_function(info r);
109
+ consteval bool is_operator_function(info r);
110
+ consteval bool is_literal_operator(info r);
111
+ consteval bool is_special_member_function(info r);
112
+ consteval bool is_constructor(info r);
113
+ consteval bool is_default_constructor(info r);
114
+ consteval bool is_copy_constructor(info r);
115
+ consteval bool is_move_constructor(info r);
116
+ consteval bool is_assignment(info r);
117
+ consteval bool is_copy_assignment(info r);
118
+ consteval bool is_move_assignment(info r);
119
+ consteval bool is_destructor(info r);
120
+
121
+ consteval bool is_function_parameter(info r);
122
+ consteval bool is_explicit_object_parameter(info r);
123
+ consteval bool has_default_argument(info r);
124
+ consteval bool has_ellipsis_parameter(info r);
125
+
126
+ consteval bool is_template(info r);
127
+ consteval bool is_function_template(info r);
128
+ consteval bool is_variable_template(info r);
129
+ consteval bool is_class_template(info r);
130
+ consteval bool is_alias_template(info r);
131
+ consteval bool is_conversion_function_template(info r);
132
+ consteval bool is_operator_function_template(info r);
133
+ consteval bool is_literal_operator_template(info r);
134
+ consteval bool is_constructor_template(info r);
135
+ consteval bool is_concept(info r);
136
+
137
+ consteval bool is_value(info r);
138
+ consteval bool is_object(info r);
139
+
140
+ consteval bool is_structured_binding(info r);
141
+
142
+ consteval bool is_class_member(info r);
143
+ consteval bool is_namespace_member(info r);
144
+ consteval bool is_nonstatic_data_member(info r);
145
+ consteval bool is_static_member(info r);
146
+ consteval bool is_base(info r);
147
+
148
+ consteval bool has_default_member_initializer(info r);
149
+
150
+ consteval bool has_parent(info r);
151
+ consteval info parent_of(info r);
152
+
153
+ consteval info dealias(info r);
154
+
155
+ consteval bool has_template_arguments(info r);
156
+ consteval info template_of(info r);
157
+ consteval vector<info> template_arguments_of(info r);
158
+ consteval vector<info> parameters_of(info r);
159
+ consteval info variable_of(info r);
160
+ consteval info return_type_of(info r);
161
+
162
+ // [meta.reflection.access.context], access control context
163
+ struct access_context;
164
+
165
+ // [meta.reflection.access.queries], member accessibility queries
166
+ consteval bool is_accessible(info r, access_context ctx);
167
+ consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
168
+ consteval bool has_inaccessible_bases(info r, access_context ctx);
169
+ consteval bool has_inaccessible_subobjects(info r, access_context ctx);
170
+
171
+ // [meta.reflection.member.queries], reflection member queries
172
+ consteval vector<info> members_of(info r, access_context ctx);
173
+ consteval vector<info> bases_of(info type, access_context ctx);
174
+ consteval vector<info> static_data_members_of(info type, access_context ctx);
175
+ consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
176
+ consteval vector<info> subobjects_of(info type, access_context ctx);
177
+ consteval vector<info> enumerators_of(info type_enum);
178
+
179
+ // [meta.reflection.layout], reflection layout queries
180
+ struct member_offset;
181
+ consteval member_offset offset_of(info r);
182
+ consteval size_t size_of(info r);
183
+ consteval size_t alignment_of(info r);
184
+ consteval size_t bit_size_of(info r);
185
+
186
+ // [meta.reflection.annotation], annotation reflection
187
+ consteval vector<info> annotations_of(info item);
188
+ consteval vector<info> annotations_of_with_type(info item, info type);
189
+
190
+ // [meta.reflection.extract], value extraction
191
+ template<class T>
192
+ consteval T extract(info);
193
+
194
+ // [meta.reflection.substitute], reflection substitution
195
+ template<class R>
196
+ concept reflection_range = see below;
197
+
198
+ template<reflection_range R = initializer_list<info>>
199
+ consteval bool can_substitute(info templ, R&& arguments);
200
+ template<reflection_range R = initializer_list<info>>
201
+ consteval info substitute(info templ, R&& arguments);
202
+
203
+ // [meta.reflection.result], expression result reflection
204
+ template<class T>
205
+ consteval info reflect_constant(T expr);
206
+ template<class T>
207
+ consteval info reflect_object(T& expr);
208
+ template<class T>
209
+ consteval info reflect_function(T& fn);
210
+
211
+ // [meta.reflection.define.aggregate], class definition generation
212
+ struct data_member_options;
213
+ consteval info data_member_spec(info type, data_member_options options);
214
+ consteval bool is_data_member_spec(info r);
215
+ template<reflection_range R = initializer_list<info>>
216
+ consteval info define_aggregate(info type_class, R&&);
217
+
218
+ // associated with [meta.unary.cat], primary type categories
219
+ consteval bool is_void_type(info type);
220
+ consteval bool is_null_pointer_type(info type);
221
+ consteval bool is_integral_type(info type);
222
+ consteval bool is_floating_point_type(info type);
223
+ consteval bool is_array_type(info type);
224
+ consteval bool is_pointer_type(info type);
225
+ consteval bool is_lvalue_reference_type(info type);
226
+ consteval bool is_rvalue_reference_type(info type);
227
+ consteval bool is_member_object_pointer_type(info type);
228
+ consteval bool is_member_function_pointer_type(info type);
229
+ consteval bool is_enum_type(info type);
230
+ consteval bool is_union_type(info type);
231
+ consteval bool is_class_type(info type);
232
+ consteval bool is_function_type(info type);
233
+ consteval bool is_reflection_type(info type);
234
+
235
+ // associated with [meta.unary.comp], composite type categories
236
+ consteval bool is_reference_type(info type);
237
+ consteval bool is_arithmetic_type(info type);
238
+ consteval bool is_fundamental_type(info type);
239
+ consteval bool is_object_type(info type);
240
+ consteval bool is_scalar_type(info type);
241
+ consteval bool is_compound_type(info type);
242
+ consteval bool is_member_pointer_type(info type);
243
+
244
+ // associated with [meta.unary.prop], type properties
245
+ consteval bool is_const_type(info type);
246
+ consteval bool is_volatile_type(info type);
247
+ consteval bool is_trivially_copyable_type(info type);
248
+ consteval bool is_trivially_relocatable_type(info type);
249
+ consteval bool is_replaceable_type(info type);
250
+ consteval bool is_standard_layout_type(info type);
251
+ consteval bool is_empty_type(info type);
252
+ consteval bool is_polymorphic_type(info type);
253
+ consteval bool is_abstract_type(info type);
254
+ consteval bool is_final_type(info type);
255
+ consteval bool is_aggregate_type(info type);
256
+ consteval bool is_consteval_only_type(info type);
257
+ consteval bool is_signed_type(info type);
258
+ consteval bool is_unsigned_type(info type);
259
+ consteval bool is_bounded_array_type(info type);
260
+ consteval bool is_unbounded_array_type(info type);
261
+ consteval bool is_scoped_enum_type(info type);
262
+
263
+ template<reflection_range R = initializer_list<info>>
264
+ consteval bool is_constructible_type(info type, R&& type_args);
265
+ consteval bool is_default_constructible_type(info type);
266
+ consteval bool is_copy_constructible_type(info type);
267
+ consteval bool is_move_constructible_type(info type);
268
+
269
+ consteval bool is_assignable_type(info type_dst, info type_src);
270
+ consteval bool is_copy_assignable_type(info type);
271
+ consteval bool is_move_assignable_type(info type);
272
+
273
+ consteval bool is_swappable_with_type(info type1, info type2);
274
+ consteval bool is_swappable_type(info type);
275
+
276
+ consteval bool is_destructible_type(info type);
277
+
278
+ template<reflection_range R = initializer_list<info>>
279
+ consteval bool is_trivially_constructible_type(info type, R&& type_args);
280
+ consteval bool is_trivially_default_constructible_type(info type);
281
+ consteval bool is_trivially_copy_constructible_type(info type);
282
+ consteval bool is_trivially_move_constructible_type(info type);
283
+
284
+ consteval bool is_trivially_assignable_type(info type_dst, info type_src);
285
+ consteval bool is_trivially_copy_assignable_type(info type);
286
+ consteval bool is_trivially_move_assignable_type(info type);
287
+ consteval bool is_trivially_destructible_type(info type);
288
+
289
+ template<reflection_range R = initializer_list<info>>
290
+ consteval bool is_nothrow_constructible_type(info type, R&& type_args);
291
+ consteval bool is_nothrow_default_constructible_type(info type);
292
+ consteval bool is_nothrow_copy_constructible_type(info type);
293
+ consteval bool is_nothrow_move_constructible_type(info type);
294
+
295
+ consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
296
+ consteval bool is_nothrow_copy_assignable_type(info type);
297
+ consteval bool is_nothrow_move_assignable_type(info type);
298
+
299
+ consteval bool is_nothrow_swappable_with_type(info type1, info type2);
300
+ consteval bool is_nothrow_swappable_type(info type);
301
+
302
+ consteval bool is_nothrow_destructible_type(info type);
303
+ consteval bool is_nothrow_relocatable_type(info type);
304
+
305
+ consteval bool is_implicit_lifetime_type(info type);
306
+
307
+ consteval bool has_virtual_destructor(info type);
308
+
309
+ consteval bool has_unique_object_representations(info type);
310
+
311
+ consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
312
+ consteval bool reference_converts_from_temporary(info type_dst, info type_src);
313
+
314
+ // associated with [meta.unary.prop.query], type property queries
315
+ consteval size_t rank(info type);
316
+ consteval size_t extent(info type, unsigned i = 0);
317
+
318
+ // associated with [meta.rel], type relations
319
+ consteval bool is_same_type(info type1, info type2);
320
+ consteval bool is_base_of_type(info type_base, info type_derived);
321
+ consteval bool is_virtual_base_of_type(info type_base, info type_derived);
322
+ consteval bool is_convertible_type(info type_src, info type_dst);
323
+ consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
324
+ consteval bool is_layout_compatible_type(info type1, info type2);
325
+ consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
326
+
327
+ template<reflection_range R = initializer_list<info>>
328
+ consteval bool is_invocable_type(info type, R&& type_args);
329
+ template<reflection_range R = initializer_list<info>>
330
+ consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
331
+
332
+ template<reflection_range R = initializer_list<info>>
333
+ consteval bool is_nothrow_invocable_type(info type, R&& type_args);
334
+ template<reflection_range R = initializer_list<info>>
335
+ consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
336
+
337
+ // associated with [meta.trans.cv], const-volatile modifications
338
+ consteval info remove_const(info type);
339
+ consteval info remove_volatile(info type);
340
+ consteval info remove_cv(info type);
341
+ consteval info add_const(info type);
342
+ consteval info add_volatile(info type);
343
+ consteval info add_cv(info type);
344
+
345
+ // associated with [meta.trans.ref], reference modifications
346
+ consteval info remove_reference(info type);
347
+ consteval info add_lvalue_reference(info type);
348
+ consteval info add_rvalue_reference(info type);
349
+
350
+ // associated with [meta.trans.sign], sign modifications
351
+ consteval info make_signed(info type);
352
+ consteval info make_unsigned(info type);
353
+
354
+ // associated with [meta.trans.arr], array modifications
355
+ consteval info remove_extent(info type);
356
+ consteval info remove_all_extents(info type);
357
+
358
+ // associated with [meta.trans.ptr], pointer modifications
359
+ consteval info remove_pointer(info type);
360
+ consteval info add_pointer(info type);
361
+
362
+ // associated with [meta.trans.other], other transformations
363
+ consteval info remove_cvref(info type);
364
+ consteval info decay(info type);
365
+ template<reflection_range R = initializer_list<info>>
366
+ consteval info common_type(R&& type_args);
367
+ template<reflection_range R = initializer_list<info>>
368
+ consteval info common_reference(R&& type_args);
369
+ consteval info underlying_type(info type);
370
+ template<reflection_range R = initializer_list<info>>
371
+ consteval info invoke_result(info type, R&& type_args);
372
+ consteval info unwrap_reference(info type);
373
+ consteval info unwrap_ref_decay(info type);
374
+
375
+ consteval size_t tuple_size(info type);
376
+ consteval info tuple_element(size_t index, info type);
377
+
378
+ consteval size_t variant_size(info type);
379
+ consteval info variant_alternative(size_t index, info type);
380
+
381
+ consteval strong_ordering type_order(info type_a, info type_b);
382
+ }
383
+ ```
384
+
385
+ Unless otherwise specified, each function, and each specialization of
386
+ any function template, specified in this header is a designated
387
+ addressable function [[namespace.std]].
388
+
389
+ The behavior of any function specified in namespace `std::meta` is
390
+ *implementation-defined* when a reflection of a construct not otherwise
391
+ specified by this document is provided as an argument.
392
+
393
+ [*Note 1*: Values of type `std::meta::info` can represent
394
+ implementation-specific constructs [[basic.fundamental]]. — *end note*]
395
+
396
+ [*Note 2*:
397
+
398
+ Many of the functions specified in namespace `std::meta` have semantics
399
+ that can be affected by the completeness of class types represented by
400
+ reflection values. For such functions, for any reflection `r` such that
401
+ `dealias(r)` represents a specialization of a templated class with a
402
+ reachable definition, the specialization is implicitly instantiated
403
+ [[temp.inst]].
404
+
405
+ [*Example 1*:
406
+
407
+ ``` cpp
408
+ template<class T>
409
+ struct X {
410
+ T mem;
411
+ };
412
+
413
+ static_assert(size_of(^^X<int>) == sizeof(int)); // instantiates X<int>
414
+ ```
415
+
416
+ — *end example*]
417
+
418
+ — *end note*]
419
+
420
+ Any function in namespace `std::meta` whose return type is `string_view`
421
+ or `u8string_view` returns an object *`V`* such that
422
+ `V.data()[V.size()]` equals `'\0'`.
423
+
424
+ [*Example 2*:
425
+
426
+ ``` cpp
427
+ struct C { };
428
+
429
+ constexpr string_view sv = identifier_of(^^C);
430
+ static_assert(sv == "C");
431
+ static_assert(sv.data()[0] == 'C');
432
+ static_assert(sv.data()[1] == '{}0');
433
+ ```
434
+
435
+ — *end example*]
436
+
437
+ For the purpose of exposition, throughout this clause `^^E` is used to
438
+ indicate a reflection representing source construct `E`.
439
+
440
+ ### Checking string literals <a id="meta.string.literal">[[meta.string.literal]]</a>
441
+
442
+ ``` cpp
443
+ consteval bool is_string_literal(const char* p);
444
+ consteval bool is_string_literal(const wchar_t* p);
445
+ consteval bool is_string_literal(const char8_t* p);
446
+ consteval bool is_string_literal(const char16_t* p);
447
+ consteval bool is_string_literal(const char32_t* p);
448
+ ```
449
+
450
+ *Returns:*
451
+
452
+ - If `p` points to an unspecified object [[expr.const]], `false`.
453
+ - Otherwise, if `p` points to a subobject of a string literal
454
+ object [[lex.string]], `true`.
455
+ - Otherwise, `false`.
456
+
457
+ ### Promoting to static storage <a id="meta.define.static">[[meta.define.static]]</a>
458
+
459
+ The functions in this subclause promote compile-time storage into static
460
+ storage.
461
+
462
+ ``` cpp
463
+ template<ranges::input_range R>
464
+ consteval info reflect_constant_string(R&& r);
465
+ ```
466
+
467
+ Let `CharT` be `ranges::range_value_t<R>`.
468
+
469
+ *Mandates:* `CharT` is one of `char`, `wchar_t`, `char8_t`, `char16_t`,
470
+ `char32_t`.
471
+
472
+ Let V be the pack of values of type `CharT` whose elements are the
473
+ corresponding elements of `r`, except that if `r` refers to a string
474
+ literal object, then V does not include the trailing null terminator of
475
+ `r`.
476
+
477
+ Let P be the template parameter object [[temp.param]] of type
478
+ `const CharT[sizeof...(V) + 1]` initialized with `{`V`..., CharT()}`.
479
+
480
+ *Returns:* .
481
+
482
+ [*Note 1*: P is a potentially non-unique
483
+ object [[intro.object]]. — *end note*]
484
+
485
+ ``` cpp
486
+ template<ranges::input_range R>
487
+ consteval info reflect_constant_array(R&& r);
488
+ ```
489
+
490
+ Let `T` be `ranges::range_value_t<R>`.
491
+
492
+ *Mandates:* `T` is a structural type [[temp.param]],
493
+ `is_constructible_v<T, ranges::range_reference_t<R>>` is `true`, and
494
+ `is_copy_constructible_v<T>` is `true`.
495
+
496
+ Let V be the pack of values of type `info` of the same size as `r`,
497
+ where the iᵗʰ element is `reflect_constant(``eᵢ``)`, where `eᵢ` is the
498
+ iᵗʰ element of `r`.
499
+
500
+ Let P be
501
+
502
+ - If `sizeof...(`V`) > 0` is `true`, then the template parameter
503
+ object [[temp.param]] of type `const T[sizeof...(`V`)]` initialized
504
+ with `{[:`V`:]...}`.
505
+ - Otherwise, the template parameter object of type `const array<T, 0>`
506
+ initialized with `{}`.
507
+
508
+ *Returns:* .
509
+
510
+ *Throws:* `meta::exception` unless `reflect_constant(e)` is a constant
511
+ subexpression for every element `e` of `r`.
512
+
513
+ [*Note 2*: P is a potentially non-unique
514
+ object [[intro.object]]. — *end note*]
515
+
516
+ ``` cpp
517
+ template<ranges::input_range R>
518
+ consteval const ranges::range_value_t<R>* define_static_string(R&& r);
519
+ ```
520
+
521
+ *Effects:* Equivalent to:
522
+
523
+ ``` cpp
524
+ return meta::extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r));
525
+ ```
526
+
527
+ ``` cpp
528
+ template<ranges::input_range R>
529
+ consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
530
+ ```
531
+
532
+ *Effects:* Equivalent to:
533
+
534
+ ``` cpp
535
+ using T = ranges::range_value_t<R>;
536
+ meta::info array = meta::reflect_constant_array(r);
537
+ if (meta::is_array_type(meta::type_of(array))) {
538
+ return span<const T>(meta::extract<const T*>(array), meta::extent(meta::type_of(array)));
539
+ } else {
540
+ return span<const T>();
541
+ }
542
+ ```
543
+
544
+ ``` cpp
545
+ template<class T>
546
+ consteval const remove_cvref_t<T>* define_static_object(T&& t);
547
+ ```
548
+
549
+ *Effects:* Equivalent to:
550
+
551
+ ``` cpp
552
+ using U = remove_cvref_t<T>;
553
+ if constexpr (meta::is_class_type(^^U)) {
554
+ return addressof(meta::extract<const U&>(meta::reflect_constant(std::forward<T>(t))));
555
+ } else {
556
+ return define_static_array(span(addressof(t), 1)).data();
557
+ }
558
+ ```
559
+
560
+ [*Note 3*: For class types, `define_static_object` provides the address
561
+ of the template parameter object [[temp.param]] that is
562
+ template-argument equivalent to `t`. — *end note*]
563
+
564
+ ### Class `exception` <a id="meta.reflection.exception">[[meta.reflection.exception]]</a>
565
+
566
+ ``` cpp
567
+ namespace std::meta {
568
+ class exception : public std::exception {
569
+ private:
570
+ optional<string> what_; // exposition only
571
+ u8string u8what_; // exposition only
572
+ info from_; // exposition only
573
+ source_location where_; // exposition only
574
+
575
+ public:
576
+ consteval exception(u8string_view what, info from,
577
+ source_location where = source_location::current()) noexcept;
578
+
579
+ consteval exception(string_view what, info from,
580
+ source_location where = source_location::current()) noexcept;
581
+
582
+ exception(const exception&) = default;
583
+ exception(exception&&) = default;
584
+
585
+ exception& operator=(const exception&) = default;
586
+ exception& operator=(exception&&) = default;
587
+
588
+ constexpr const char* what() const noexcept override;
589
+ consteval u8string_view u8what() const noexcept;
590
+ consteval info from() const noexcept;
591
+ consteval source_location where() const noexcept;
592
+ };
593
+ }
594
+ ```
595
+
596
+ Reflection functions throw exceptions of type `meta::exception` to
597
+ signal an error. `meta::exception` is a consteval-only type.
598
+
599
+ ``` cpp
600
+ consteval exception(u8string_view what, info from,
601
+ source_location where = source_location::current()) noexcept;
602
+ ```
603
+
604
+ *Effects:* Initializes *u8what\_* with `what`, *from\_* with `from`, and
605
+ *where\_* with `where`. If `what` can be represented in the ordinary
606
+ literal encoding, initializes *what\_* with `what`, transcoded from
607
+ UTF-8 to the ordinary literal encoding. Otherwise, *what\_* is
608
+ value-initialized.
609
+
610
+ ``` cpp
611
+ consteval exception(string_view what, info from,
612
+ source_location where = source_location::current()) noexcept;
613
+ ```
614
+
615
+ `what` designates a sequence of characters that can be encoded in UTF-8.
616
+
617
+ *Effects:* Initializes *what\_* with `what`, *u8what\_* with `what`
618
+ transcoded from the ordinary literal encoding to UTF-8, *from\_* with
619
+ `from` and *where\_* with `where`.
620
+
621
+ ``` cpp
622
+ constexpr const char* what() const noexcept override;
623
+ ```
624
+
625
+ *`what_`*`.has_value()` is `true`.
626
+
627
+ *Returns:* *`what_`*`->c_str()`.
628
+
629
+ ``` cpp
630
+ consteval u8string_view u8what() const noexcept;
631
+ ```
632
+
633
+ *Returns:* *u8what\_*.
634
+
635
+ ``` cpp
636
+ consteval info from() const noexcept;
637
+ ```
638
+
639
+ *Returns:* *from\_*.
640
+
641
+ ``` cpp
642
+ consteval source_location where() const noexcept;
643
+ ```
644
+
645
+ *Returns:* *where\_*.
646
+
647
+ ### Operator representations <a id="meta.reflection.operators">[[meta.reflection.operators]]</a>
648
+
649
+ ``` cpp
650
+ enum class operators {
651
+ see below;
652
+ };
653
+ using enum operators;
654
+ ```
655
+
656
+ The enumeration type `operators` specifies constants used to identify
657
+ operators that can be overloaded, with the meanings listed
658
+ in  [[meta.reflection.operators]]. The values of the constants are
659
+ distinct.
660
+
661
+ **Table: Enum class `operators`** <a id="meta.reflection.operators">[meta.reflection.operators]</a>
662
+
663
+ | Constant | Corresponding *operator-function-id* | Operator symbol name |
664
+ | --------------------------- | ------------------------------------ | -------------------- |
665
+ | `op_new` | `operator new` | `new` |
666
+ | `op_delete` | `operator delete` | `delete` |
667
+ | `op_array_new` | `operator new[]` | `new[]` |
668
+ | `op_array_delete` | `operator delete[]` | `delete[]` |
669
+ | `op_co_await` | `operator co_await` | `co_await` |
670
+ | `op_parentheses` | `operator()` | `()` |
671
+ | `op_square_brackets` | `operator[]` | `[]` |
672
+ | `op_arrow` | `operator->` | `->` |
673
+ | `op_arrow_star` | `operator->*` | `->*` |
674
+ | `op_tilde` | `operator~` | `~` |
675
+ | `op_exclamation` | `operator!` | `!` |
676
+ | `op_plus` | `operator+` | `+` |
677
+ | `op_minus` | `operator-` | `-` |
678
+ | `op_star` | `operator*` | `*` |
679
+ | `op_slash` | `operator/` | `/` |
680
+ | `op_percent` | `operator%` | `%` |
681
+ | `op_caret` | `operator^` | `^` |
682
+ | `op_ampersand` | `operator&` | `&` |
683
+ | `op_equals` | `operator=` | `=` |
684
+ | `op_pipe` | `operator|` | `|` |
685
+ | `op_plus_equals` | `operator+=` | `+=` |
686
+ | `op_minus_equals` | `operator-=` | `-=` |
687
+ | `op_star_equals` | `operator*=` | `*=` |
688
+ | `op_slash_equals` | `operator/=` | `/=` |
689
+ | `op_percent_equals` | `operator%=` | `%=` |
690
+ | `op_caret_equals` | `operator^=` | `^=` |
691
+ | `op_ampersand_equals` | `operator&=` | `&=` |
692
+ | `op_pipe_equals` | `operator|=` | `|=` |
693
+ | `op_equals_equals` | `operator==` | `==` |
694
+ | `op_exclamation_equals` | `operator!=` | `!=` |
695
+ | `op_less` | `operator<` | `<` |
696
+ | `op_greater` | `operator>` | `>` |
697
+ | `op_less_equals` | `operator<=` | `<=` |
698
+ | `op_greater_equals` | `operator>=` | `>=` |
699
+ | `op_spaceship` | `operator<=>` | `<=>` |
700
+ | `op_ampersand_ampersand` | `operator&&` | `&&` |
701
+ | `op_pipe_pipe` | `operator||` | `||` |
702
+ | `op_less_less` | `operator<<` | `<<` |
703
+ | `op_greater_greater` | `operator>>` | `>>` |
704
+ | `op_less_less_equals` | `operator<<=` | `<<=` |
705
+ | `op_greater_greater_equals` | `operator>>=` | `>>=` |
706
+ | `op_plus_plus` | `operator++` | `++` |
707
+ | `op_minus_minus` | `operator--` | `--` |
708
+ | `op_comma` | `operator,` | `,` |
709
+
710
+ ``` cpp
711
+ consteval operators operator_of(info r);
712
+ ```
713
+
714
+ *Returns:* The value of the enumerator from `operators` whose
715
+ corresponding *operator-function-id* is the unqualified name of the
716
+ entity represented by `r`.
717
+
718
+ *Throws:* `meta::exception` unless `r` represents an operator function
719
+ or operator function template.
720
+
721
+ ``` cpp
722
+ consteval string_view symbol_of(operators op);
723
+ consteval u8string_view u8symbol_of(operators op);
724
+ ```
725
+
726
+ *Returns:* A `string_view` or `u8string_view` containing the characters
727
+ of the operator symbol name corresponding to `op`, respectively encoded
728
+ with the ordinary literal encoding or with UTF-8.
729
+
730
+ *Throws:* `meta::exception` unless the value of `op` corresponds to one
731
+ of the enumerators in `operators`.
732
+
733
+ ### Reflection names and locations <a id="meta.reflection.names">[[meta.reflection.names]]</a>
734
+
735
+ ``` cpp
736
+ consteval bool has_identifier(info r);
737
+ ```
738
+
739
+ *Returns:*
740
+
741
+ - If `r` represents an entity that has a typedef name for linkage
742
+ purposes [[dcl.typedef]], then `true`.
743
+ - Otherwise, if `r` represents an unnamed entity, then `false`.
744
+ - Otherwise, if `r` represents a class type, then
745
+ `!has_template_arguments(r)`.
746
+ - Otherwise, if `r` represents a function, then `true` if
747
+ `has_template_arguments(r)` is `false` and the function is not a
748
+ constructor, destructor, operator function, or conversion function.
749
+ Otherwise, `false`.
750
+ - Otherwise, if `r` represents a template, then `true` if `r` does not
751
+ represent a constructor template, operator function template, or
752
+ conversion function template. Otherwise, `false`.
753
+ - Otherwise, if `r` represents the iᵗʰ parameter of a function F that is
754
+ an (implicit or explicit) specialization of a templated function T and
755
+ the iᵗʰ parameter of the instantiated declaration of T whose template
756
+ arguments are those of F would be instantiated from a pack, then
757
+ `false`.
758
+ - Otherwise, if `r` represents the parameter P of a function F, then let
759
+ S be the set of declarations, ignoring any explicit instantiations,
760
+ that precede some point in the evaluation context and that declare
761
+ either F or a templated function of which F is a specialization;
762
+ `true` if
763
+ - there is a declaration D in S that introduces a name N for either P
764
+ or the parameter corresponding to P in the templated function that D
765
+ declares and
766
+ - no declaration in S does so using any name other than N.
767
+
768
+ Otherwise, `false`.
769
+ \[*Example 1*:
770
+ void fun(int);
771
+ constexpr std::meta::info r = parameters_of(^^fun)[0];
772
+ static_assert(!has_identifier(r));
773
+
774
+ void fun(int x);
775
+ static_assert(has_identifier(r));
776
+
777
+ void fun(int x);
778
+ static_assert(has_identifier(r));
779
+
780
+ void poison() {
781
+ void fun(int y);
782
+ }
783
+ static_assert(!has_identifier(r));
784
+
785
+ — *end example*]
786
+ - Otherwise, if `r` represents a variable, then `false` if the
787
+ declaration of that variable was instantiated from a function
788
+ parameter pack. Otherwise, `!has_template_arguments(r)`.
789
+ - Otherwise, if `r` represents a structured binding, then `false` if the
790
+ declaration of that structured binding was instantiated from a
791
+ structured binding pack. Otherwise, `true`.
792
+ - Otherwise, if `r` represents a type alias, then
793
+ `!has_template_arguments(r)`.
794
+ - Otherwise, if `r` represents an enumerator, non-static-data member,
795
+ namespace, or namespace alias, then `true`.
796
+ - Otherwise, if `r` represents a direct base class relationship, then
797
+ `has_identifier(type_of(r))`.
798
+ - Otherwise, `r` represents a data member description
799
+ (T, N, A, W, *NUA*)[[class.mem.general]]; `true` if N is not $\bot$.
800
+ Otherwise, `false`.
801
+
802
+ ``` cpp
803
+ consteval string_view identifier_of(info r);
804
+ consteval u8string_view u8identifier_of(info r);
805
+ ```
806
+
807
+ Let E be UTF-8 for `u8identifier_of`, and otherwise the ordinary literal
808
+ encoding.
809
+
810
+ *Returns:* An NTMBS, encoded with E, determined as follows:
811
+
812
+ - If `r` represents an entity with a typedef name for linkage purposes,
813
+ then that name.
814
+ - Otherwise, if `r` represents a literal operator or literal operator
815
+ template, then the *ud-suffix* of the operator or operator template.
816
+ - Otherwise, if `r` represents the parameter P of a function F, then let
817
+ S be the set of declarations, ignoring any explicit instantiations,
818
+ that precede some point in the evaluation context and that declare
819
+ either F or a templated function of which F is a specialization; the
820
+ name that was introduced by a declaration in S for the parameter
821
+ corresponding to P.
822
+ - Otherwise, if `r` represents an entity, then the identifier introduced
823
+ by the declaration of that entity.
824
+ - Otherwise, if `r` represents a direct base class relationship, then
825
+ `identifier_of(type_of(r))` or `u8identifier_of(type_of(r))`,
826
+ respectively.
827
+ - Otherwise, `r` represents a data member description
828
+ (T, N, A, W, NUA)[[class.mem.general]]; a `string_view` or
829
+ `u8string_view`, respectively, containing the identifier N.
830
+
831
+ *Throws:* `meta::exception` unless `has_identifier(r)` is `true` and the
832
+ identifier that would be returned (see above) is representable by E.
833
+
834
+ ``` cpp
835
+ consteval string_view display_string_of(info r);
836
+ consteval u8string_view u8display_string_of(info r);
837
+ ```
838
+
839
+ *Returns:* An *implementation-defined* `string_view` or `u8string_view`,
840
+ respectively.
841
+
842
+ *Recommended practice:* Where possible, implementations should return a
843
+ string suitable for identifying the represented construct.
844
+
845
+ ``` cpp
846
+ consteval source_location source_location_of(info r);
847
+ ```
848
+
849
+ *Returns:* If `r` represents a value, a type other than a class type or
850
+ an enumeration type, the global namespace, or a data member description,
851
+ then `source_location{}`. Otherwise, an *implementation-defined*
852
+ `source_location` value.
853
+
854
+ *Recommended practice:* If `r` represents an entity with a definition
855
+ that is reachable from the evaluation context, a value corresponding to
856
+ a definition should be returned.
857
+
858
+ ### Reflection queries <a id="meta.reflection.queries">[[meta.reflection.queries]]</a>
859
+
860
+ ``` cpp
861
+ consteval bool has-type(info r); // exposition only
862
+ ```
863
+
864
+ *Returns:* `true` if `r` represents a value, annotation, object,
865
+ variable, function whose type does not contain an undeduced placeholder
866
+ type and that is not a constructor or destructor, enumerator, non-static
867
+ data member, unnamed bit-field, direct base class relationship, data
868
+ member description, or function parameter. Otherwise, `false`.
869
+
870
+ ``` cpp
871
+ consteval info type_of(info r);
872
+ ```
873
+
874
+ *Returns:*
875
+
876
+ - If `r` represents the iᵗʰ parameter of a function F, then the iᵗʰ type
877
+ in the parameter-type-list of F[[dcl.fct]].
878
+ - Otherwise, if `r` represents a value, object, variable, function,
879
+ non-static data member, or unnamed bit-field, then the type of what is
880
+ represented by `r`.
881
+ - Otherwise, if `r` represents an annotation, then
882
+ `type_of(constant_of(r))`.
883
+ - Otherwise, if `r` represents an enumerator N of an enumeration E,
884
+ then:
885
+ - If E is defined by a declaration D that precedes a point P in the
886
+ evaluation context and P does not occur within an *enum-specifier*
887
+ of D, then a reflection of E.
888
+ - Otherwise, a reflection of the type of N prior to the closing brace
889
+ of the *enum-specifier* as specified in  [[dcl.enum]].
890
+ - Otherwise, if `r` represents a direct base class relationship (D, B),
891
+ then a reflection of B.
892
+ - Otherwise, for a data member description
893
+ (T, N, A, W, *NUA*)[[class.mem.general]], a reflection of the type T.
894
+
895
+ *Throws:* `meta::exception` unless *`has-type`*`(r)` is `true`.
896
+
897
+ ``` cpp
898
+ consteval info object_of(info r);
899
+ ```
900
+
901
+ *Returns:*
902
+
903
+ - If `r` represents an object, then `r`.
904
+ - Otherwise, if `r` represents a reference, then a reflection of the
905
+ object referred to by that reference.
906
+ - Otherwise, `r` represents a variable; a reflection of the object
907
+ declared by that variable.
908
+
909
+ *Throws:* `meta::exception` unless `r` is a reflection representing
910
+ either
911
+
912
+ - an object with static storage duration [[basic.stc.general]], or
913
+ - a variable that either declares or refers to such an object, and if
914
+ that variable is a reference R, then either
915
+ - R is usable in constant expressions [[expr.const]], or
916
+ - the lifetime of R began within the core constant expression
917
+ currently under evaluation.
918
+
919
+ [*Example 1*:
920
+
921
+ ``` cpp
922
+ int x;
923
+ int& y = x;
924
+
925
+ static_assert(^^x != ^^y); // OK, r and y are different variables so their
926
+ // reflections compare different
927
+ static_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference
928
+ // to x, their underlying objects are the same
929
+ ```
930
+
931
+ — *end example*]
932
+
933
+ ``` cpp
934
+ consteval info constant_of(info r);
935
+ ```
936
+
937
+ Let R be a constant expression of type `info` such that R` == r` is
938
+ `true`. If `r` represents an annotation, then let C be its underlying
939
+ constant.
940
+
941
+ *Effects:* Equivalent to:
942
+
943
+ ``` cpp
944
+ if constexpr (is_annotation(R)) {
945
+ return C;
946
+ } else {
947
+ return reflect_constant([: R :]);
948
+ }
949
+ ```
950
+
951
+ *Throws:* `meta::exception` unless either `r` represents an annotation
952
+ or `[: `R` :]` is a valid *splice-expression*[[expr.prim.splice]].
953
+
954
+ [*Example 2*:
955
+
956
+ ``` cpp
957
+ constexpr int x = 0;
958
+ constexpr int y = 0;
959
+
960
+ static_assert(^^x != ^^y); // OK, x and y are different variables,
961
+ // so their reflections compare different
962
+ static_assert(constant_of(^^x) ==
963
+ constant_of(^^y)); // OK, both constant_of(\reflexpr{x)} and
964
+ // constant_of(\reflexpr{y)} represent the value 0
965
+ static_assert(constant_of(^^x) ==
966
+ reflect_constant(0)); // OK, likewise
967
+
968
+ struct S { int m; };
969
+ constexpr S s {42};
970
+ static_assert(is_object(constant_of(^^s)) &&
971
+ is_object(reflect_object(s)));
972
+ static_assert(constant_of(^^s) != // OK, template parameter object that is template-argument-
973
+ reflect_object(s)); // equivalent to s is a different object than s
974
+ static_assert(constant_of(^^s) ==
975
+ constant_of(reflect_object(s))); // OK
976
+
977
+ consteval info fn() {
978
+ constexpr int x = 42;
979
+ return ^^x;
980
+ }
981
+ constexpr info r = constant_of(fn()); // error: x is outside its lifetime
982
+ ```
983
+
984
+ — *end example*]
985
+
986
+ ``` cpp
987
+ consteval bool is_public(info r);
988
+ consteval bool is_protected(info r);
989
+ consteval bool is_private(info r);
990
+ ```
991
+
992
+ *Returns:* `true` if `r` represents either
993
+
994
+ - a class member or unnamed bit-field that is public, protected, or
995
+ private, respectively, or
996
+ - a direct base class relationship (D, B) for which B is, respectively,
997
+ a public, protected, or private base class of D.
998
+
999
+ Otherwise, `false`.
1000
+
1001
+ ``` cpp
1002
+ consteval bool is_virtual(info r);
1003
+ ```
1004
+
1005
+ *Returns:* `true` if `r` represents either a virtual member function or
1006
+ a direct base class relationship (D, B) for which B is a virtual base
1007
+ class of D. Otherwise, `false`.
1008
+
1009
+ ``` cpp
1010
+ consteval bool is_pure_virtual(info r);
1011
+ consteval bool is_override(info r);
1012
+ ```
1013
+
1014
+ *Returns:* `true` if `r` represents a member function that is pure
1015
+ virtual or overrides another member function, respectively. Otherwise,
1016
+ `false`.
1017
+
1018
+ ``` cpp
1019
+ consteval bool is_final(info r);
1020
+ ```
1021
+
1022
+ *Returns:* `true` if `r` represents a final class or a final member
1023
+ function. Otherwise, `false`.
1024
+
1025
+ ``` cpp
1026
+ consteval bool is_deleted(info r);
1027
+ consteval bool is_defaulted(info r);
1028
+ ```
1029
+
1030
+ *Returns:* `true` if `r` represents a function that is a deleted
1031
+ function [[dcl.fct.def.delete]] or defaulted
1032
+ function [[dcl.fct.def.default]], respectively. Otherwise, `false`.
1033
+
1034
+ ``` cpp
1035
+ consteval bool is_user_provided(info r);
1036
+ consteval bool is_user_declared(info r);
1037
+ ```
1038
+
1039
+ *Returns:* `true` if `r` represents a function that is user-provided or
1040
+ user-declared [[dcl.fct.def.default]], respectively. Otherwise, `false`.
1041
+
1042
+ ``` cpp
1043
+ consteval bool is_explicit(info r);
1044
+ ```
1045
+
1046
+ *Returns:* `true` if `r` represents a member function that is declared
1047
+ explicit. Otherwise, `false`.
1048
+
1049
+ [*Note 1*: If `r` represents a member function template that is
1050
+ declared explicit, `is_explicit(r)` is still `false` because in general,
1051
+ such queries for templates cannot be answered. — *end note*]
1052
+
1053
+ ``` cpp
1054
+ consteval bool is_noexcept(info r);
1055
+ ```
1056
+
1057
+ *Returns:* `true` if `r` represents a `noexcept` function type or a
1058
+ function with a non-throwing exception specification [[except.spec]].
1059
+ Otherwise, `false`.
1060
+
1061
+ [*Note 2*: If `r` represents a function template that is declared
1062
+ `noexcept`, `is_noexcept(r)` is still `false` because in general, such
1063
+ queries for templates cannot be answered. — *end note*]
1064
+
1065
+ ``` cpp
1066
+ consteval bool is_bit_field(info r);
1067
+ ```
1068
+
1069
+ *Returns:* `true` if `r` represents a bit-field, or if `r` represents a
1070
+ data member description (T, N, A, W, *NUA*)[[class.mem.general]] for
1071
+ which W is not $\bot$. Otherwise, `false`.
1072
+
1073
+ ``` cpp
1074
+ consteval bool is_enumerator(info r);
1075
+ consteval bool is_annotation(info r);
1076
+ ```
1077
+
1078
+ *Returns:* `true` if `r` represents an enumerator or annotation,
1079
+ respectively. Otherwise, `false`.
1080
+
1081
+ ``` cpp
1082
+ consteval bool is_const(info r);
1083
+ consteval bool is_volatile(info r);
1084
+ ```
1085
+
1086
+ Let T be `type_of(r)` if *`has-type`*`(r)` is `true`. Otherwise, let T
1087
+ be `dealias(r)`.
1088
+
1089
+ *Returns:* `true` if `T` represents a const or volatile type,
1090
+ respectively, or a const- or volatile-qualified function type,
1091
+ respectively. Otherwise, `false`.
1092
+
1093
+ ``` cpp
1094
+ consteval bool is_mutable_member(info r);
1095
+ ```
1096
+
1097
+ *Returns:* `true` if `r` represents a `mutable` non-static data member.
1098
+ Otherwise, `false`.
1099
+
1100
+ ``` cpp
1101
+ consteval bool is_lvalue_reference_qualified(info r);
1102
+ consteval bool is_rvalue_reference_qualified(info r);
1103
+ ```
1104
+
1105
+ Let T be `type_of(r)` if *`has-type`*`(r)` is `true`. Otherwise, let T
1106
+ be `dealias(r)`.
1107
+
1108
+ *Returns:* `true` if T represents an lvalue- or rvalue-qualified
1109
+ function type, respectively. Otherwise, `false`.
1110
+
1111
+ ``` cpp
1112
+ consteval bool has_static_storage_duration(info r);
1113
+ consteval bool has_thread_storage_duration(info r);
1114
+ consteval bool has_automatic_storage_duration(info r);
1115
+ ```
1116
+
1117
+ *Returns:* `true` if `r` represents an object or variable that has
1118
+ static, thread, or automatic storage duration,
1119
+ respectively [[basic.stc]]. Otherwise, `false`.
1120
+
1121
+ [*Note 3*: It is not possible to have a reflection representing an
1122
+ object or variable having dynamic storage duration. — *end note*]
1123
+
1124
+ ``` cpp
1125
+ consteval bool has_internal_linkage(info r);
1126
+ consteval bool has_module_linkage(info r);
1127
+ consteval bool has_external_linkage(info r);
1128
+ consteval bool has_c_language_linkage(info r);
1129
+ consteval bool has_linkage(info r);
1130
+ ```
1131
+
1132
+ *Returns:* `true` if `r` represents a variable, function, type,
1133
+ template, or namespace whose name has internal linkage, module linkage,
1134
+ C language linkage, or any linkage, respectively [[basic.link]].
1135
+ Otherwise, `false`.
1136
+
1137
+ ``` cpp
1138
+ consteval bool is_complete_type(info r);
1139
+ ```
1140
+
1141
+ *Returns:* `true` if `is_type(r)` is `true` and there is some point in
1142
+ the evaluation context from which the type represented by `dealias(r)`
1143
+ is not an incomplete type [[basic.types]]. Otherwise, `false`.
1144
+
1145
+ ``` cpp
1146
+ consteval bool is_enumerable_type(info r);
1147
+ ```
1148
+
1149
+ A type T is *enumerable* from a point P if either
1150
+
1151
+ - T is a class type complete at point P or
1152
+ - T is an enumeration type defined by a declaration D such that D is
1153
+ reachable from P but P does not occur within an *enum-specifier* of
1154
+ D[[dcl.enum]].
1155
+
1156
+ *Returns:* `true` if `dealias(r)` represents a type that is enumerable
1157
+ from some point in the evaluation context. Otherwise, `false`.
1158
+
1159
+ [*Example 3*:
1160
+
1161
+ ``` cpp
1162
+ class S;
1163
+ enum class E;
1164
+ static_assert(!is_enumerable_type(^^S));
1165
+ static_assert(!is_enumerable_type(^^E));
1166
+
1167
+ class S {
1168
+ void mfn() {
1169
+ static_assert(is_enumerable_type(^^S));
1170
+ }
1171
+ static_assert(!is_enumerable_type(^^S));
1172
+ };
1173
+ static_assert(is_enumerable_type(^^S));
1174
+
1175
+ enum class E {
1176
+ A = is_enumerable_type(^^E) ? 1 : 2
1177
+ };
1178
+ static_assert(is_enumerable_type(^^E));
1179
+ static_assert(static_cast<int>(E::A) == 2);
1180
+ ```
1181
+
1182
+ — *end example*]
1183
+
1184
+ ``` cpp
1185
+ consteval bool is_variable(info r);
1186
+ ```
1187
+
1188
+ *Returns:* `true` if `r` represents a variable. Otherwise, `false`.
1189
+
1190
+ ``` cpp
1191
+ consteval bool is_type(info r);
1192
+ consteval bool is_namespace(info r);
1193
+ ```
1194
+
1195
+ *Returns:* `true` if `r` represents an entity whose underlying entity is
1196
+ a type or namespace, respectively. Otherwise, `false`.
1197
+
1198
+ ``` cpp
1199
+ consteval bool is_type_alias(info r);
1200
+ consteval bool is_namespace_alias(info r);
1201
+ ```
1202
+
1203
+ *Returns:* `true` if `r` represents a type alias or namespace alias,
1204
+ respectively. Otherwise, `false`.
1205
+
1206
+ [*Note 4*: A specialization of an alias template is a type
1207
+ alias. — *end note*]
1208
+
1209
+ ``` cpp
1210
+ consteval bool is_function(info r);
1211
+ ```
1212
+
1213
+ *Returns:* `true` if `r` represents a function. Otherwise, `false`.
1214
+
1215
+ ``` cpp
1216
+ consteval bool is_conversion_function(info r);
1217
+ consteval bool is_operator_function(info r);
1218
+ consteval bool is_literal_operator(info r);
1219
+ ```
1220
+
1221
+ *Returns:* `true` if `r` represents a function that is a conversion
1222
+ function [[class.conv.fct]], operator function [[over.oper]], or literal
1223
+ operator [[over.literal]], respectively. Otherwise, `false`.
1224
+
1225
+ ``` cpp
1226
+ consteval bool is_special_member_function(info r);
1227
+ consteval bool is_constructor(info r);
1228
+ consteval bool is_default_constructor(info r);
1229
+ consteval bool is_copy_constructor(info r);
1230
+ consteval bool is_move_constructor(info r);
1231
+ consteval bool is_assignment(info r);
1232
+ consteval bool is_copy_assignment(info r);
1233
+ consteval bool is_move_assignment(info r);
1234
+ consteval bool is_destructor(info r);
1235
+ ```
1236
+
1237
+ *Returns:* `true` if `r` represents a function that is a special member
1238
+ function [[special]], a constructor, a default constructor, a copy
1239
+ constructor, a move constructor, an assignment operator, a copy
1240
+ assignment operator, a move assignment operator, or a destructor,
1241
+ respectively. Otherwise, `false`.
1242
+
1243
+ ``` cpp
1244
+ consteval bool is_function_parameter(info r);
1245
+ ```
1246
+
1247
+ *Returns:* `true` if `r` represents a function parameter. Otherwise,
1248
+ `false`.
1249
+
1250
+ ``` cpp
1251
+ consteval bool is_explicit_object_parameter(info r);
1252
+ ```
1253
+
1254
+ *Returns:* `true` if `r` represents a function parameter that is an
1255
+ explicit object parameter [[dcl.fct]]. Otherwise, `false`.
1256
+
1257
+ ``` cpp
1258
+ consteval bool has_default_argument(info r);
1259
+ ```
1260
+
1261
+ *Returns:* If `r` represents a parameter P of a function F, then:
1262
+
1263
+ - If F is a specialization of a templated function T, then `true` if
1264
+ there exists a declaration D of T that precedes some point in the
1265
+ evaluation context and D specifies a default argument for the
1266
+ parameter of T corresponding to P. Otherwise, `false`.
1267
+ - Otherwise, if there exists a declaration D of F that precedes some
1268
+ point in the evaluation context and D specifies a default argument for
1269
+ P, then `true`.
1270
+
1271
+ Otherwise, `false`.
1272
+
1273
+ ``` cpp
1274
+ consteval bool has_ellipsis_parameter(info r);
1275
+ ```
1276
+
1277
+ *Returns:* `true` if `r` represents a function or function type that has
1278
+ an ellipsis in its parameter-type-list [[dcl.fct]]. Otherwise, `false`.
1279
+
1280
+ ``` cpp
1281
+ consteval bool is_template(info r);
1282
+ ```
1283
+
1284
+ *Returns:* `true` if `r` represents a function template, class template,
1285
+ variable template, alias template, or concept. Otherwise, `false`.
1286
+
1287
+ [*Note 5*: A template specialization is not a template. For example,
1288
+ `is_template(``)` is `true` but `is_template(``)` is
1289
+ `false`. — *end note*]
1290
+
1291
+ ``` cpp
1292
+ consteval bool is_function_template(info r);
1293
+ consteval bool is_variable_template(info r);
1294
+ consteval bool is_class_template(info r);
1295
+ consteval bool is_alias_template(info r);
1296
+ consteval bool is_conversion_function_template(info r);
1297
+ consteval bool is_operator_function_template(info r);
1298
+ consteval bool is_literal_operator_template(info r);
1299
+ consteval bool is_constructor_template(info r);
1300
+ consteval bool is_concept(info r);
1301
+ ```
1302
+
1303
+ *Returns:* `true` if `r` represents a function template, variable
1304
+ template, class template, alias template, conversion function template,
1305
+ operator function template, literal operator template, constructor
1306
+ template, or concept, respectively. Otherwise, `false`.
1307
+
1308
+ ``` cpp
1309
+ consteval bool is_value(info r);
1310
+ consteval bool is_object(info r);
1311
+ ```
1312
+
1313
+ *Returns:* `true` if `r` represents a value or object, respectively.
1314
+ Otherwise, `false`.
1315
+
1316
+ ``` cpp
1317
+ consteval bool is_structured_binding(info r);
1318
+ ```
1319
+
1320
+ *Returns:* `true` if `r` represents a structured binding. Otherwise,
1321
+ `false`.
1322
+
1323
+ ``` cpp
1324
+ consteval bool is_class_member(info r);
1325
+ consteval bool is_namespace_member(info r);
1326
+ consteval bool is_nonstatic_data_member(info r);
1327
+ consteval bool is_static_member(info r);
1328
+ consteval bool is_base(info r);
1329
+ ```
1330
+
1331
+ *Returns:* `true` if `r` represents a class member, namespace member,
1332
+ non-static data member, static member, or direct base class
1333
+ relationship, respectively. Otherwise, `false`.
1334
+
1335
+ ``` cpp
1336
+ consteval bool has_default_member_initializer(info r);
1337
+ ```
1338
+
1339
+ *Returns:* `true` if `r` represents a non-static data member that has a
1340
+ default member initializer. Otherwise, `false`.
1341
+
1342
+ ``` cpp
1343
+ consteval bool has_parent(info r);
1344
+ ```
1345
+
1346
+ *Returns:*
1347
+
1348
+ - If `r` represents the global namespace, then `false`.
1349
+ - Otherwise, if `r` represents an entity that has C language
1350
+ linkage [[dcl.link]], then `false`.
1351
+ - Otherwise, if `r` represents an entity that has a language linkage
1352
+ other than C++ language linkage, then an *implementation-defined*
1353
+ value.
1354
+ - Otherwise, if `r` represents a type that is neither a class nor
1355
+ enumeration type, then `false`.
1356
+ - Otherwise, if `r` represents an entity or direct base class
1357
+ relationship, then `true`.
1358
+ - Otherwise, `false`.
1359
+
1360
+ ``` cpp
1361
+ consteval info parent_of(info r);
1362
+ ```
1363
+
1364
+ *Returns:*
1365
+
1366
+ - If `r` represents a non-static data member that is a direct member of
1367
+ an anonymous union, or an unnamed bit-field declared within the
1368
+ *member-specification* of such a union, then a reflection representing
1369
+ the innermost enclosing anonymous union.
1370
+ - Otherwise, if `r` represents an enumerator, then a reflection
1371
+ representing the corresponding enumeration type.
1372
+ - Otherwise, if `r` represents a direct base class relationship (D, B),
1373
+ then a reflection representing D.
1374
+ - Otherwise, let E be a class, function, or namespace whose class scope,
1375
+ function parameter scope, or namespace scope, respectively, is the
1376
+ innermost such scope that either is, or encloses, the target scope of
1377
+ a declaration of what is represented by `r`.
1378
+ - If E is the function call operator of a closure type for a
1379
+ *consteval-block-declaration*[[dcl.pre]], then
1380
+ `parent_of(parent_of(``))`. \[*Note 1*: In this case, the first
1381
+ `parent_of` will be the closure type, so the second `parent_of` is
1382
+ necessary to give the parent of that closure type. — *end note*]
1383
+ - Otherwise, .
1384
+
1385
+ *Throws:* `meta::exception` unless `has_parent(r)` is `true`.
1386
+
1387
+ [*Example 4*:
1388
+
1389
+ ``` cpp
1390
+ struct I { };
1391
+
1392
+ struct F : I {
1393
+ union {
1394
+ int o;
1395
+ };
1396
+
1397
+ enum N {
1398
+ A
1399
+ };
1400
+ };
1401
+
1402
+ constexpr auto ctx = std::meta::access_context::current();
1403
+
1404
+ static_assert(parent_of(^^F) == ^^::);
1405
+ static_assert(parent_of(bases_of(^^F, ctx)[0]) == ^^F);
1406
+ static_assert(is_union_type(parent_of(^^F::o)));
1407
+ static_assert(parent_of(^^F::N) == ^^F);
1408
+ static_assert(parent_of(^^F::A) == ^^F::N);
1409
+ ```
1410
+
1411
+ — *end example*]
1412
+
1413
+ ``` cpp
1414
+ consteval info dealias(info r);
1415
+ ```
1416
+
1417
+ *Returns:* A reflection representing the underlying entity of what `r`
1418
+ represents.
1419
+
1420
+ *Throws:* `meta::exception` unless `r` represents an entity.
1421
+
1422
+ [*Example 5*:
1423
+
1424
+ ``` cpp
1425
+ using X = int;
1426
+ using Y = X;
1427
+ static_assert(dealias(^^int) == ^^int);
1428
+ static_assert(dealias(^^X) == ^^int);
1429
+ static_assert(dealias(^^Y) == ^^int);
1430
+ ```
1431
+
1432
+ — *end example*]
1433
+
1434
+ ``` cpp
1435
+ consteval bool has_template_arguments(info r);
1436
+ ```
1437
+
1438
+ *Returns:* `true` if `r` represents a specialization of a function
1439
+ template, variable template, class template, or an alias template.
1440
+ Otherwise, `false`.
1441
+
1442
+ ``` cpp
1443
+ consteval info template_of(info r);
1444
+ ```
1445
+
1446
+ *Returns:* A reflection of the template of the specialization
1447
+ represented by `r`.
1448
+
1449
+ *Throws:* `meta::exception` unless `has_template_arguments(r)` is
1450
+ `true`.
1451
+
1452
+ ``` cpp
1453
+ consteval vector<info> template_arguments_of(info r);
1454
+ ```
1455
+
1456
+ *Returns:* A `vector` containing reflections of the template arguments
1457
+ of the template specialization represented by `r`, in the order in which
1458
+ they appear in the corresponding template argument list. For a given
1459
+ template argument A, its corresponding reflection R is determined as
1460
+ follows:
1461
+
1462
+ - If A denotes a type or type alias, then R is a reflection representing
1463
+ the underlying entity of A. \[*Note 2*: R always represents a type,
1464
+ never a type alias. — *end note*]
1465
+ - Otherwise, if A denotes a class template, variable template, concept,
1466
+ or alias template, then R is a reflection representing A.
1467
+ - Otherwise, A is a constant template argument [[temp.arg.nontype]]. Let
1468
+ P be the corresponding template parameter.
1469
+ - If P has reference type, then R is a reflection representing the
1470
+ object or function referred to by A.
1471
+ - Otherwise, if P has class type, then R represents the corresponding
1472
+ template parameter object.
1473
+ - Otherwise, R is a reflection representing the value of A.
1474
+
1475
+ *Throws:* `meta::exception` unless `has_template_arguments(r)` is
1476
+ `true`.
1477
+
1478
+ [*Example 6*:
1479
+
1480
+ ``` cpp
1481
+ template<class T, class U = T> struct Pair { };
1482
+ template<class T> struct Pair<char, T> { };
1483
+ template<class T> using PairPtr = Pair<T*>;
1484
+
1485
+ static_assert(template_of(^^Pair<int>) == ^^Pair);
1486
+ static_assert(template_of(^^Pair<char, char>) == ^^Pair);
1487
+ static_assert(template_arguments_of(^^Pair<int>).size() == 2);
1488
+ static_assert(template_arguments_of(^^Pair<int>)[0] == ^^int);
1489
+
1490
+ static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);
1491
+ static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);
1492
+
1493
+ struct S { };
1494
+ int i;
1495
+ template<int, int&, S, template<class> class>
1496
+ struct X { };
1497
+ constexpr auto T = ^^X<1, i, S{}, PairPtr>;
1498
+ static_assert(is_value(template_arguments_of(T)[0]));
1499
+ static_assert(is_object(template_arguments_of(T)[1]));
1500
+ static_assert(is_object(template_arguments_of(T)[2]));
1501
+ static_assert(template_arguments_of(T)[3] == ^^PairPtr);
1502
+ ```
1503
+
1504
+ — *end example*]
1505
+
1506
+ ``` cpp
1507
+ consteval vector<info> parameters_of(info r);
1508
+ ```
1509
+
1510
+ *Returns:*
1511
+
1512
+ - If `r` represents a function F, then a `vector` containing reflections
1513
+ of the parameters of F, in the order in which they appear in a
1514
+ declaration of F.
1515
+ - Otherwise, `r` represents a function type T; a `vector` containing
1516
+ reflections of the types in parameter-type-list [[dcl.fct]] of T, in
1517
+ the order in which they appear in the parameter-type-list.
1518
+
1519
+ *Throws:* `meta::exception` unless `r` represents a function or a
1520
+ function type.
1521
+
1522
+ ``` cpp
1523
+ consteval info variable_of(info r);
1524
+ ```
1525
+
1526
+ *Returns:* The reflection of the parameter variable corresponding to
1527
+ `r`.
1528
+
1529
+ *Throws:* `meta::exception` unless
1530
+
1531
+ - `r` represents a parameter of a function F and
1532
+ - there is a point P in the evaluation context for which the innermost
1533
+ non-block scope enclosing P is the function parameter
1534
+ scope [[basic.scope.param]] associated with F.
1535
+
1536
+ ``` cpp
1537
+ consteval info return_type_of(info r);
1538
+ ```
1539
+
1540
+ *Returns:* The reflection of the return type of the function or function
1541
+ type represented by `r`.
1542
+
1543
+ *Throws:* `meta::exception` unless either `r` represents a function and
1544
+ *`has-type`*`(r)` is `true` or `r` represents a function type.
1545
+
1546
+ ### Access control context <a id="meta.reflection.access.context">[[meta.reflection.access.context]]</a>
1547
+
1548
+ The `access_context` class is a non-aggregate type that represents a
1549
+ namespace, class, or function from which queries pertaining to access
1550
+ rules may be performed, as well as the designating class
1551
+ [[class.access.base]], if any.
1552
+
1553
+ An `access_context` has an associated scope and designating class.
1554
+
1555
+ ``` cpp
1556
+ namespace std::meta {
1557
+ struct access_context {
1558
+ access_context() = delete;
1559
+
1560
+ consteval info scope() const;
1561
+ consteval info designating_class() const;
1562
+
1563
+ static consteval access_context current() noexcept;
1564
+ static consteval access_context unprivileged() noexcept;
1565
+ static consteval access_context unchecked() noexcept;
1566
+ consteval access_context via(info cls) const;
1567
+ };
1568
+ }
1569
+ ```
1570
+
1571
+ `access_context` is a structural type. Two values `ac1` and `ac2` of
1572
+ type `access_context` are template-argument-equivalent [[temp.type]] if
1573
+ `ac1.scope()` and `ac2.scope()` are template-argument-equivalent and
1574
+ `ac1.designating_class()` and `ac2.designating_class()` are
1575
+ template-argument-equivalent.
1576
+
1577
+ ``` cpp
1578
+ consteval info scope() const;
1579
+ consteval info designating_class() const;
1580
+ ```
1581
+
1582
+ *Returns:* The `access_context`’s associated scope and designating
1583
+ class, respectively.
1584
+
1585
+ ``` cpp
1586
+ static consteval access_context current() noexcept;
1587
+ ```
1588
+
1589
+ Given a program point P, let *`eval-point`*`(`P`)` be the following
1590
+ program point:
1591
+
1592
+ - If a potentially-evaluated subexpression [[intro.execution]] of a
1593
+ default member initializer I for a member of class
1594
+ C[[class.mem.general]] appears at P, then a point determined as
1595
+ follows:
1596
+ - If an aggregate initialization is using I, *`eval-point`*`(`Q`)`,
1597
+ where Q is the point at which that aggregate initialization appears.
1598
+ - Otherwise, if an initialization by an inherited
1599
+ constructor [[class.inhctor.init]] is using I, a point whose
1600
+ immediate scope is the class scope corresponding to C.
1601
+ - Otherwise, a point whose immediate scope is the function parameter
1602
+ scope corresponding to the constructor definition that is using I.
1603
+ - Otherwise, if a potentially-evaluated subexpression of a default
1604
+ argument [[dcl.fct.default]] appears at P, *`eval-point`*`(`Q`)`,
1605
+ where Q is the point at which the invocation of the
1606
+ function [[expr.call]] using that default argument appears.
1607
+ - Otherwise, if the immediate scope of P is a function parameter scope
1608
+ introduced by a declaration D, and P appears either before the locus
1609
+ of D or within the trailing *requires-clause* of D, a point whose
1610
+ immediate scope is the innermost scope enclosing the locus of D that
1611
+ is not a template parameter scope.
1612
+ - Otherwise, if the immediate scope of P is a function parameter scope
1613
+ introduced by a *lambda-expression* L whose *lambda-introducer*
1614
+ appears at point Q, and P appears either within the
1615
+ *trailing-return-type* or the trailing *requires-clause* of L,
1616
+ *`eval-point`*`(`Q`)`.
1617
+ - Otherwise, if the innermost non-block scope enclosing P is the
1618
+ function parameter scope introduced by a
1619
+ *consteval-block-declaration*[[dcl.pre]], a point whose immediate
1620
+ scope is that inhabited by the outermost *consteval-block-declaration*
1621
+ D containing P such that each scope (if any) that intervenes between P
1622
+ and the function parameter scope introduced by D is either
1623
+ - a block scope or
1624
+ - a function parameter scope or lambda scope introduced by a
1625
+ *consteval-block-declaration*.
1626
+ - Otherwise, P.
1627
+
1628
+ Given a scope S, let *`ctx-scope`*`(`S`)` be the following scope:
1629
+
1630
+ - If S is a class scope or namespace scope, S.
1631
+ - Otherwise, if S is a function parameter scope introduced by the
1632
+ declaration of a function, S.
1633
+ - Otherwise, if S is a lambda scope introduced by a *lambda-expression*
1634
+ L, the function parameter scope corresponding to the call operator of
1635
+ the closure type of L.
1636
+ - Otherwise, *`ctx-scope`*`(`S'`)`, where S' is the parent scope of S.
1637
+
1638
+ *Returns:* An `access_context` whose designating class is the null
1639
+ reflection and whose scope represents the function, class, or namespace
1640
+ whose corresponding function parameter scope, class scope, or namespace
1641
+ scope, respectively, is *`ctx-scope`*`(`S`)`, where S is the immediate
1642
+ scope of *`eval-point`*`(`P`)` and P is the point at which the
1643
+ invocation of `current` lexically appears.
1644
+
1645
+ *Remarks:* `current` is not an addressable function [[namespace.std]].
1646
+ An invocation of `current` that appears at a program point P is
1647
+ value-dependent [[temp.dep.constexpr]] if *`eval-point`*`(`P`)` is
1648
+ enclosed by a scope corresponding to a templated entity.
1649
+
1650
+ [*Example 1*:
1651
+
1652
+ ``` cpp
1653
+ struct A {
1654
+ int a = 0;
1655
+ consteval A(int p) : a(p) {}
1656
+ };
1657
+ struct B : A {
1658
+ using A::A;
1659
+ consteval B(int p, int q) : A(p * q) {}
1660
+ info s = access_context::current().scope();
1661
+ };
1662
+ struct C : B { using B::B; };
1663
+
1664
+ struct Agg {
1665
+ consteval bool eq(info rhs = access_context::current().scope()) {
1666
+ return s == rhs;
1667
+ }
1668
+ info s = access_context::current().scope();
1669
+ };
1670
+
1671
+ namespace NS {
1672
+ static_assert(Agg{}.s == access_context::current().scope()); // OK
1673
+ static_assert(Agg{}.eq()); // OK
1674
+ static_assert(B(1).s == ^^B); // OK
1675
+ static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OK
1676
+ static_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OK
1677
+
1678
+ auto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:];
1679
+ static_assert(type_of(^^fn) == ^^auto()->int); // OK
1680
+
1681
+ template<auto R>
1682
+ struct TCls {
1683
+ consteval bool fn()
1684
+ requires (is_type(access_context::current().scope())) {
1685
+ return true; // OK, scope is TCls<R>.
1686
+ }
1687
+ };
1688
+ static_assert(TCls<0>{}.fn()); // OK
1689
+ }
1690
+ ```
1691
+
1692
+ — *end example*]
1693
+
1694
+ ``` cpp
1695
+ static consteval access_context unprivileged() noexcept;
1696
+ ```
1697
+
1698
+ *Returns:* An `access_context` whose designating class is the null
1699
+ reflection and whose scope is the global namespace.
1700
+
1701
+ ``` cpp
1702
+ static consteval access_context unchecked() noexcept;
1703
+ ```
1704
+
1705
+ *Returns:* An `access_context` whose designating class and scope are
1706
+ both the null reflection.
1707
+
1708
+ ``` cpp
1709
+ consteval access_context via(info cls) const;
1710
+ ```
1711
+
1712
+ *Returns:* An `access_context` whose scope is `this->scope()` and whose
1713
+ designating class is `cls`.
1714
+
1715
+ *Throws:* `meta::exception` unless `cls` is either the null reflection
1716
+ or a reflection of a complete class type.
1717
+
1718
+ ### Member accessibility queries <a id="meta.reflection.access.queries">[[meta.reflection.access.queries]]</a>
1719
+
1720
+ ``` cpp
1721
+ consteval bool is_accessible(info r, access_context ctx);
1722
+ ```
1723
+
1724
+ Let *`PARENT-CLS`*`(r)` be:
1725
+
1726
+ - If `parent_of(r)` represents a class C, then C.
1727
+ - Otherwise, *`PARENT-CLS`*`(parent_of(r))`.
1728
+
1729
+ Let *`DESIGNATING-CLS`*`(r, ctx)` be:
1730
+
1731
+ - If `ctx.designating_class()` represents a class C, then C.
1732
+ - Otherwise, *`PARENT-CLS`*`(r)`.
1733
+
1734
+ *Returns:*
1735
+
1736
+ - If `r` represents an unnamed bit-field F, then
1737
+ `is_accessible(``r_H``, ctx)`, where `r_H` represents a hypothetical
1738
+ non-static data member of the class represented by *`PARENT-CLS`*`(r)`
1739
+ with the same access as F. \[*Note 1*: Unnamed bit-fields are treated
1740
+ as class members for the purpose of `is_accessible`. — *end note*]
1741
+ - Otherwise, if `r` does not represent a class member or a direct base
1742
+ class relationship, then `true`.
1743
+ - Otherwise, if `r` represents
1744
+ - a class member that is not a (possibly indirect or variant) member
1745
+ of *`DESIGNATING-CLS`*`(r, ctx)` or
1746
+ - a direct base class relationship such that `parent_of(r)` does not
1747
+ represent *`DESIGNATING-CLS`*`(r, ctx)` or a (direct or indirect)
1748
+ base class thereof,
1749
+
1750
+ then `false`.
1751
+ - Otherwise, if `ctx.scope()` is the null reflection, then `true`.
1752
+ - Otherwise, letting P be a program point whose immediate scope is the
1753
+ function parameter scope, class scope, or namespace scope
1754
+ corresponding to the function, class, or namespace represented by
1755
+ `ctx.scope()`:
1756
+ - If `r` represents a direct base class relationship (D, B), then
1757
+ `true` if base class B of *`DESIGNATING-CLS`*`(r, ctx)` is
1758
+ accessible at P[[class.access.base]]; otherwise `false`.
1759
+ - Otherwise, `r` represents a class member M; `true` if M would be
1760
+ accessible at P with the designating class [[class.access.base]] as
1761
+ *`DESIGNATING-CLS`*`(r, ctx)` if the effect of any
1762
+ *using-declaration*s [[namespace.udecl]] were ignored. Otherwise,
1763
+ `false`.
1764
+
1765
+ [*Note 1*: The definitions of when a class member or base class is
1766
+ accessible from a point P do not consider whether a declaration of that
1767
+ entity is reachable from P. — *end note*]
1768
+
1769
+ *Throws:* `meta::exception` if
1770
+
1771
+ - `r` represents a class member for which *`PARENT-CLS`*`(r)` is an
1772
+ incomplete class or
1773
+ - `r` represents a direct base class relationship (D, B) for which D is
1774
+ incomplete.
1775
+
1776
+ [*Example 1*:
1777
+
1778
+ ``` cpp
1779
+ consteval access_context fn() {
1780
+ return access_context::current();
1781
+ }
1782
+
1783
+ class Cls {
1784
+ int mem;
1785
+ friend consteval access_context fn();
1786
+ public:
1787
+ static constexpr auto r = ^^mem;
1788
+ };
1789
+
1790
+ static_assert(is_accessible(Cls::r, fn())); // OK
1791
+ static_assert(!is_accessible(Cls::r, access_context::current())); // OK
1792
+ static_assert(is_accessible(Cls::r, access_context::unchecked())); // OK
1793
+ ```
1794
+
1795
+ — *end example*]
1796
+
1797
+ ``` cpp
1798
+ consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
1799
+ ```
1800
+
1801
+ *Returns:* `true` if `is_accessible(`R`, ctx)` is `false` for any R in
1802
+ `nonstatic_data_members_of(r, access_context::unchecked())`. Otherwise,
1803
+ `false`.
1804
+
1805
+ *Throws:* `meta::exception` unless
1806
+
1807
+ - `nonstatic_data_members_of(r, access_context::unchecked())` is a
1808
+ constant subexpression and
1809
+ - `r` does not represent a closure type.
1810
+
1811
+ ``` cpp
1812
+ consteval bool has_inaccessible_bases(info r, access_context ctx);
1813
+ ```
1814
+
1815
+ *Returns:* `true` if `is_accessible(`R`, ctx)` is `false` for any R in
1816
+ `bases_of(r, access_context::unchecked())`. Otherwise, `false`.
1817
+
1818
+ *Throws:* `meta::exception` unless
1819
+ `bases_of(r, access_context::unchecked())` is a constant subexpression.
1820
+
1821
+ ``` cpp
1822
+ consteval bool has_inaccessible_subobjects(info r, access_context ctx);
1823
+ ```
1824
+
1825
+ *Effects:* Equivalent to:
1826
+
1827
+ ``` cpp
1828
+ return has_inaccessible_bases(r, ctx) || has_inaccessible_nonstatic_data_members(r, ctx);
1829
+ ```
1830
+
1831
+ ### Reflection member queries <a id="meta.reflection.member.queries">[[meta.reflection.member.queries]]</a>
1832
+
1833
+ ``` cpp
1834
+ consteval vector<info> members_of(info r, access_context ctx);
1835
+ ```
1836
+
1837
+ A declaration D *members-of-precedes* a point P if D precedes either P
1838
+ or the point immediately following the *class-specifier* of the
1839
+ outermost class for which P is in a complete-class context.
1840
+
1841
+ A declaration D of a member M of a class or namespace Q is
1842
+ *Q-members-of-eligible* if
1843
+
1844
+ - the host scope of D[[basic.scope.scope]] is the class scope or
1845
+ namespace scope associated with Q,
1846
+ - D is not a friend declaration,
1847
+ - M is not a closure type [[expr.prim.lambda.closure]],
1848
+ - M is not a specialization of a template [[temp.pre]],
1849
+ - if Q is a class that is not a closure type, then M is a direct member
1850
+ of Q[[class.mem.general]] that is not a variant member of a nested
1851
+ anonymous union of Q[[class.union.anon]], and
1852
+ - if Q is a closure type, then M is a function call operator or function
1853
+ call operator template.
1854
+
1855
+ It is *implementation-defined* whether declarations of other members of
1856
+ a closure type Q are Q-members-of-eligible.
1857
+
1858
+ A member M of a class or namespace Q is *Q-members-of-representable*
1859
+ from a point P if a Q-members-of-eligible declaration of M
1860
+ members-of-precedes P, and M is
1861
+
1862
+ - a class or enumeration type,
1863
+ - a type alias,
1864
+ - a class template, function template, variable template, alias
1865
+ template, or concept,
1866
+ - a variable or reference V for which the type of V does not contain an
1867
+ undeduced placeholder type,
1868
+ - a function F for which
1869
+ - the type of F does not contain an undeduced placeholder type,
1870
+ - the constraints (if any) of F are satisfied, and
1871
+ - if F is a prospective destructor, F is the selected
1872
+ destructor [[class.dtor]],
1873
+ - a non-static data member,
1874
+ - a namespace, or
1875
+ - a namespace alias.
1876
+
1877
+ [*Note 1*: Examples of direct members that are not
1878
+ Q-members-of-representable for any entity Q include: unscoped
1879
+ enumerators [[enum]], partial specializations of
1880
+ templates [[temp.spec.partial]], and closure
1881
+ types [[expr.prim.lambda.closure]]. — *end note*]
1882
+
1883
+ *Returns:* A `vector` containing reflections of all members M of the
1884
+ entity Q represented by `dealias(r)` for which
1885
+
1886
+ - M is Q-members-of-representable from some point in the evaluation
1887
+ context and
1888
+ - `is_accessible(``, ctx)` is `true`.
1889
+
1890
+ If `dealias(r)` represents a class C, then the `vector` also contains
1891
+ reflections representing all unnamed bit-fields B whose declarations
1892
+ inhabit the class scope corresponding to C for which
1893
+ `is_accessible(``, ctx)` is `true`. Reflections of class members and
1894
+ unnamed bit-fields that are declared appear in the order in which they
1895
+ are declared.
1896
+
1897
+ [*Note 2*: Base classes are not members. Implicitly-declared special
1898
+ members appear after any user-declared
1899
+ members [[special]]. — *end note*]
1900
+
1901
+ *Throws:* `meta::exception` unless `dealias(r)` is a reflection
1902
+ representing either a class type that is complete from some point in the
1903
+ evaluation context or a namespace.
1904
+
1905
+ [*Example 1*:
1906
+
1907
+ ``` cpp
1908
+ // TU1
1909
+ export module M;
1910
+ namespace NS {
1911
+ export int m;
1912
+ static int l;
1913
+ }
1914
+ static_assert(members_of(^^NS, access_context::current()).size() == 2);
1915
+
1916
+ // TU2
1917
+ import M;
1918
+
1919
+ static_assert( // NS::l does not precede
1920
+ members_of(^^NS, access_context::current()).size() == 1); // the constant-expression [basic.lookup]
1921
+
1922
+ class B {};
1923
+
1924
+ struct S : B {
1925
+ private:
1926
+ class I;
1927
+ public:
1928
+ int m;
1929
+ };
1930
+
1931
+ static_assert( // 6 special members,
1932
+ members_of(^^S, access_context::current()).size() == 7); // 1 public member,
1933
+ // does not include base
1934
+
1935
+ static_assert( // all of the above,
1936
+ members_of(^^S, access_context::unchecked()).size() == 8); // as well as a reflection
1937
+ // representing S::I
1938
+ ```
1939
+
1940
+ — *end example*]
1941
+
1942
+ ``` cpp
1943
+ consteval vector<info> bases_of(info type, access_context ctx);
1944
+ ```
1945
+
1946
+ *Returns:* Let C be the class represented by `dealias(type)`. A `vector`
1947
+ containing the reflections of all the direct base class relationships B,
1948
+ if any, of C such that `is_accessible(``, ctx)` is `true`. The direct
1949
+ base class relationships appear in the order in which the corresponding
1950
+ base classes appear in the *base-specifier-list* of C.
1951
+
1952
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
1953
+ type that is complete from some point in the evaluation context.
1954
+
1955
+ ``` cpp
1956
+ consteval vector<info> static_data_members_of(info type, access_context ctx);
1957
+ ```
1958
+
1959
+ *Returns:* A `vector` containing each element `e` of
1960
+ `members_of(type, ctx)` such that `is_variable(e)` is `true`, preserving
1961
+ their order.
1962
+
1963
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
1964
+ type that is complete from some point in the evaluation context.
1965
+
1966
+ ``` cpp
1967
+ consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
1968
+ ```
1969
+
1970
+ *Returns:* A `vector` containing each element `e` of
1971
+ `members_of(type, ctx)` such that `is_nonstatic_data_member(e)` is
1972
+ `true`, preserving their order.
1973
+
1974
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
1975
+ type that is complete from some point in the evaluation context.
1976
+
1977
+ ``` cpp
1978
+ consteval vector<info> subobjects_of(info type, access_context ctx);
1979
+ ```
1980
+
1981
+ *Returns:* A `vector` containing each element of `bases_of(type, ctx)`
1982
+ followed by each element of `nonstatic_data_members_of(type, ctx)`,
1983
+ preserving their order.
1984
+
1985
+ *Throws:* `meta::exception` unless `dealias(type)` represents a class
1986
+ type that is complete from some point in the evaluation context.
1987
+
1988
+ ``` cpp
1989
+ consteval vector<info> enumerators_of(info type_enum);
1990
+ ```
1991
+
1992
+ *Returns:* A `vector` containing the reflections of each enumerator of
1993
+ the enumeration represented by `dealias(type_enum)`, in the order in
1994
+ which they are declared.
1995
+
1996
+ *Throws:* `meta::exception` unless `dealias(type_enum)` represents an
1997
+ enumeration type, and `is_enumerable_type(type_enum)` is `true`.
1998
+
1999
+ ### Reflection layout queries <a id="meta.reflection.layout">[[meta.reflection.layout]]</a>
2000
+
2001
+ ``` cpp
2002
+ struct member_offset {
2003
+ ptrdiff_t bytes;
2004
+ ptrdiff_t bits;
2005
+ constexpr ptrdiff_t total_bits() const;
2006
+ auto operator<=>(const member_offset&) const = default;
2007
+ };
2008
+
2009
+ constexpr ptrdiff_t member_offset::total_bits() const;
2010
+ ```
2011
+
2012
+ *Returns:* `bytes * CHAR_BIT + bits`.
2013
+
2014
+ ``` cpp
2015
+ consteval member_offset offset_of(info r);
2016
+ ```
2017
+
2018
+ Let V be the offset in bits from the beginning of a complete object of
2019
+ the type represented by `parent_of(r)` to the subobject associated with
2020
+ the construct represented by `r`.
2021
+
2022
+ *Returns:* `{`V` / CHAR_BIT, `V` % CHAR_BIT}`.
2023
+
2024
+ *Throws:* `meta::exception` unless `r` represents a non-static data
2025
+ member, unnamed bit-field, or direct base class relationship (D, B) for
2026
+ which either B is not a virtual base class or D is not an abstract
2027
+ class.
2028
+
2029
+ ``` cpp
2030
+ consteval size_t size_of(info r);
2031
+ ```
2032
+
2033
+ *Returns:* If
2034
+
2035
+ - `r` represents a non-static data member of type T or a data member
2036
+ description (T, N, A, W, *NUA*) or
2037
+ - `dealias(r)` represents a type T,
2038
+
2039
+ then `sizeof(`T`)` if T is not a reference type and
2040
+ `size_of(add_pointer(``))` otherwise. Otherwise, `size_of(type_of(r))`.
2041
+
2042
+ [*Note 1*: It is possible that while `sizeof(char) == size_of(``)` is
2043
+ `true`, that `sizeof(char&) == size_of(``&)` is `false`. If `b`
2044
+ represents a direct base class relationship of an empty base class, then
2045
+ `size_of(b) > 0` is `true`. — *end note*]
2046
+
2047
+ *Throws:* `meta::exception` unless all of the following conditions are
2048
+ met:
2049
+
2050
+ - `dealias(r)` is a reflection of a type, object, value, variable of
2051
+ non-reference type, non-static data member that is not a bit-field,
2052
+ direct base class relationship, or data member description
2053
+ (T, N, A, W, *NUA*)[[class.mem.general]] where W is $\bot$.
2054
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
2055
+ `true`.
2056
+
2057
+ ``` cpp
2058
+ consteval size_t alignment_of(info r);
2059
+ ```
2060
+
2061
+ *Returns:*
2062
+
2063
+ - If `dealias(r)` represents a type T, then
2064
+ `alignment_of(add_pointer(r))` if T is a reference type and the
2065
+ alignment requirement of T otherwise.
2066
+ - Otherwise, if `dealias(r)` represents a variable or object, then the
2067
+ alignment requirement of the variable or object.
2068
+ - Otherwise, if `r` represents a direct base class relationship, then
2069
+ `alignment_of(type_of(r))`.
2070
+ - Otherwise, if `r` represents a non-static data member M of a class C,
2071
+ then the alignment of the direct member subobject corresponding to M
2072
+ of a complete object of type C.
2073
+ - Otherwise, `r` represents a data member description
2074
+ (T, N, A, W, *NUA*)[[class.mem.general]]. If A is not $\bot$, then the
2075
+ value A. Otherwise, `alignment_of(``)`.
2076
+
2077
+ *Throws:* `meta::exception` unless all of the following conditions are
2078
+ met:
2079
+
2080
+ - `dealias(r)` is a reflection of a type, object, variable of
2081
+ non-reference type, non-static data member that is not a bit-field,
2082
+ direct base class relationship, or data member description.
2083
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
2084
+ `true`.
2085
+
2086
+ ``` cpp
2087
+ consteval size_t bit_size_of(info r);
2088
+ ```
2089
+
2090
+ *Returns:*
2091
+
2092
+ - If `r` represents an unnamed bit-field or a non-static data member
2093
+ that is a bit-field with width W, then W.
2094
+ - Otherwise, if `r` represents a data member description
2095
+ (T, N, A, W, *NUA*)[[class.mem.general]] and W is not $\bot$, then W.
2096
+ - Otherwise, `CHAR_BIT * size_of(r)`.
2097
+
2098
+ *Throws:* `meta::exception` unless all of the following conditions are
2099
+ met:
2100
+
2101
+ - `dealias(r)` is a reflection of a type, object, value, variable of
2102
+ non-reference type, non-static data member, unnamed bit-field, direct
2103
+ base class relationship, or data member description.
2104
+ - If `dealias(r)` represents a type, then `is_complete_type(r)` is
2105
+ `true`.
2106
+
2107
+ ### Annotation reflection <a id="meta.reflection.annotation">[[meta.reflection.annotation]]</a>
2108
+
2109
+ ``` cpp
2110
+ consteval vector<info> annotations_of(info item);
2111
+ ```
2112
+
2113
+ Let E be
2114
+
2115
+ - the corresponding *base-specifier* if `item` represents a direct base
2116
+ class relationship,
2117
+ - otherwise, the entity represented by `item`.
2118
+
2119
+ *Returns:* A `vector` containing all of the reflections R representing
2120
+ each annotation applying to each declaration of E that precedes either
2121
+ some point in the evaluation context [[expr.const]] or a point
2122
+ immediately following the *class-specifier* of the outermost class for
2123
+ which such a point is in a complete-class context. For any two
2124
+ reflections R₁ and R₂ in the returned `vector`, if the annotation
2125
+ represented by R₁ precedes the annotation represented by R₂, then R₁
2126
+ appears before R₂. If R₁ and R₂ represent annotations from the same
2127
+ translation unit T, any element in the returned `vector` between R₁ and
2128
+ R₂ represents an annotation from T.
2129
+
2130
+ [*Note 1*: The order in which two annotations appear is otherwise
2131
+ unspecified. — *end note*]
2132
+
2133
+ *Throws:* `meta::exception` unless `item` represents a type, type alias,
2134
+ variable, function, namespace, enumerator, direct base class
2135
+ relationship, or non-static data member.
2136
+
2137
+ [*Example 1*:
2138
+
2139
+ ``` cpp
2140
+ [[=1]] void f();
2141
+ [[=2, =3]] void g();
2142
+ void g [[=4]] ();
2143
+
2144
+ static_assert(annotations_of(^^f).size() == 1);
2145
+ static_assert(annotations_of(^^g).size() == 3);
2146
+ static_assert([: constant_of(annotations_of(^^g)[0]) :] == 2);
2147
+ static_assert(extract<int>(annotations_of(^^g)[1]) == 3);
2148
+ static_assert(extract<int>(annotations_of(^^g)[2]) == 4);
2149
+
2150
+ struct Option { bool value; };
2151
+
2152
+ struct C {
2153
+ [[=Option{true}]] int a;
2154
+ [[=Option{false}]] int b;
2155
+ };
2156
+
2157
+ static_assert(extract<Option>(annotations_of(^^C::a)[0]).value);
2158
+ static_assert(!extract<Option>(annotations_of(^^C::b)[0]).value);
2159
+
2160
+ template<class T>
2161
+ struct [[=42]] D { };
2162
+
2163
+ constexpr std::meta::info a1 = annotations_of(^^D<int>)[0];
2164
+ constexpr std::meta::info a2 = annotations_of(^^D<char>)[0];
2165
+ static_assert(a1 != a2);
2166
+ static_assert(constant_of(a1) == constant_of(a2));
2167
+
2168
+ [[=1]] int x, y;
2169
+ static_assert(annotations_of(^^x)[0] == annotations_of(^^y)[0]);
2170
+ ```
2171
+
2172
+ — *end example*]
2173
+
2174
+ ``` cpp
2175
+ consteval vector<info> annotations_of_with_type(info item, info type);
2176
+ ```
2177
+
2178
+ *Returns:* A `vector` containing each element `e` of
2179
+ `annotations_of(item)` where
2180
+
2181
+ ``` cpp
2182
+ remove_const(type_of(e)) == remove_const(type)
2183
+ ```
2184
+
2185
+ is `true`, preserving their order.
2186
+
2187
+ *Throws:* `meta::exception` unless
2188
+
2189
+ - `annotations_of(item)` is a constant expression and
2190
+ - `dealias(type)` represents a type and `is_complete_type(type)` is
2191
+ `true`.
2192
+
2193
+ ### Value extraction <a id="meta.reflection.extract">[[meta.reflection.extract]]</a>
2194
+
2195
+ The `extract` function template may be used to extract a value out of a
2196
+ reflection when its type is known.
2197
+
2198
+ The following are defined for exposition only to aid in the
2199
+ specification of `extract`.
2200
+
2201
+ ``` cpp
2202
+ template<class T>
2203
+ consteval T extract-ref(info r); // exposition only
2204
+ ```
2205
+
2206
+ [*Note 1*: `T` is a reference type. — *end note*]
2207
+
2208
+ *Returns:* If `r` represents an object O, then a reference to O.
2209
+ Otherwise, a reference to the object declared, or referred to, by the
2210
+ variable represented by `r`.
2211
+
2212
+ *Throws:* `meta::exception` unless
2213
+
2214
+ - `r` represents a variable or object of type `U`,
2215
+ - `is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]>`
2216
+ is `true`, and \[*Note 1*: The intent is to allow only qualification
2217
+ conversion from `U` to `T`. — *end note*]
2218
+ - If `r` represents a variable, then either that variable is usable in
2219
+ constant expressions or its lifetime began within the core constant
2220
+ expression currently under evaluation.
2221
+
2222
+ ``` cpp
2223
+ template<class T>
2224
+ consteval T extract-member-or-function(info r); // exposition only
2225
+ ```
2226
+
2227
+ *Returns:*
2228
+
2229
+ - If `T` is a pointer type, then a pointer value pointing to the
2230
+ function represented by `r`.
2231
+ - Otherwise, a pointer-to-member value designating the non-static data
2232
+ member or function represented by `r`.
2233
+
2234
+ *Throws:* `meta::exception` unless
2235
+
2236
+ - `r` represents a non-static data member with type `X`, that is not a
2237
+ bit-field, that is a direct member of class `C`, `T` and `X C::*` are
2238
+ similar types [[conv.qual]], and `is_convertible_v<X C::*, T>` is
2239
+ `true`;
2240
+ - `r` represents an implicit object member function with type `F` or
2241
+ `F noexcept` that is a direct member of a class `C`, and `T` is
2242
+ `F C::*`; or
2243
+ - `r` represents a non-member function, static member function, or
2244
+ explicit object member function of function type `F` or `F noexcept`,
2245
+ and `T` is `F*`.
2246
+
2247
+ ``` cpp
2248
+ template<class T>
2249
+ consteval T extract-value(info r); // exposition only
2250
+ ```
2251
+
2252
+ Let `U` be the type of the value or object that `r` represents.
2253
+
2254
+ *Returns:* `static_cast<T>([:`R`:])`, where R is a constant expression
2255
+ of type `info` such that R` == r` is `true`.
2256
+
2257
+ *Throws:* `meta::exception` unless
2258
+
2259
+ - `U` is a pointer type, `T` and `U` are either similar [[conv.qual]] or
2260
+ both function pointer types, and `is_convertible_v<U, T>` is `true`,
2261
+ - `U` is not a pointer type and the cv-unqualified types of `T` and `U`
2262
+ are the same,
2263
+ - `U` is an array type, `T` is a pointer type, and the value `r`
2264
+ represents is convertible to `T`, or
2265
+ - `U` is a closure type, `T` is a function pointer type, and the value
2266
+ that `r` represents is convertible to `T`.
2267
+
2268
+ ``` cpp
2269
+ template<class T>
2270
+ consteval T extract(info r);
2271
+ ```
2272
+
2273
+ Let `U` be `remove_cv_t<T>`.
2274
+
2275
+ *Effects:* Equivalent to:
2276
+
2277
+ ``` cpp
2278
+ if constexpr (is_reference_type(^^T)) {
2279
+ return extract-ref<T>(r);
2280
+ } else if (is_nonstatic_data_member(r) || is_function(r)) {
2281
+ return extract-member-or-function<U>(r);
2282
+ } else {
2283
+ return extract-value<U>(constant_of(r));
2284
+ }
2285
+ ```
2286
+
2287
+ ### Reflection substitution <a id="meta.reflection.substitute">[[meta.reflection.substitute]]</a>
2288
+
2289
+ ``` cpp
2290
+ template<class R>
2291
+ concept reflection_range =
2292
+ ranges::input_range<R> &&
2293
+ same_as<ranges::range_value_t<R>, info> &&
2294
+ same_as<remove_cvref_t<ranges::range_reference_t<R>>, info>;
2295
+
2296
+ template<reflection_range R = initializer_list<info>>
2297
+ consteval bool can_substitute(info templ, R&& arguments);
2298
+ ```
2299
+
2300
+ Let `Z` be the template represented by `templ` and let `Args...` be a
2301
+ sequence of prvalue constant expressions that compute the reflections
2302
+ held by the elements of `arguments`, in order.
2303
+
2304
+ *Returns:* `true` if `Z<[:Args:]...>` is a valid
2305
+ *template-id*[[temp.names]] that does not name a function whose type
2306
+ contains an undeduced placeholder type. Otherwise, `false`.
2307
+
2308
+ *Throws:* `meta::exception` unless `templ` represents a template, and
2309
+ every reflection in `arguments` represents a construct usable as a
2310
+ template argument [[temp.arg]].
2311
+
2312
+ [*Note 1*: If forming `Z<[:Args:]...>` leads to a failure outside of
2313
+ the immediate context, the program is ill-formed. — *end note*]
2314
+
2315
+ ``` cpp
2316
+ template<reflection_range R = initializer_list<info>>
2317
+ consteval info substitute(info templ, R&& arguments);
2318
+ ```
2319
+
2320
+ Let `Z` be the template represented by `templ` and let `Args...` be a
2321
+ sequence of prvalue constant expressions that compute the reflections
2322
+ held by the elements of `arguments`, in order.
2323
+
2324
+ *Returns:* .
2325
+
2326
+ *Throws:* `meta::exception` unless `can_substitute(templ, arguments)` is
2327
+ `true`.
2328
+
2329
+ [*Note 2*: If forming `Z<[:Args:]...>` leads to a failure outside of
2330
+ the immediate context, the program is ill-formed. — *end note*]
2331
+
2332
+ [*Example 1*:
2333
+
2334
+ ``` cpp
2335
+ template<class T>
2336
+ auto fn1();
2337
+
2338
+ static_assert(!can_substitute(^^fn1, {^^int})); // OK
2339
+ constexpr info r1 = substitute(^^fn1, {^^int}); // error: fn1<int> contains an undeduced
2340
+ // placeholder type for its return type
2341
+
2342
+ template<class T>
2343
+ auto fn2() {
2344
+ static_assert(^^T != ^^int); // static assertion failed during instantiation of fn2<int>
2345
+ return 0;
2346
+ }
2347
+
2348
+ constexpr bool r2 = can_substitute(^^fn2, {^^int}); // error: instantiation of body of fn2<int>
2349
+ // is needed to deduce return type
2350
+ ```
2351
+
2352
+ — *end example*]
2353
+
2354
+ [*Example 2*:
2355
+
2356
+ ``` cpp
2357
+ consteval info to_integral_constant(unsigned i) {
2358
+ return substitute(^^integral_constant, {^^unsigned, reflect_constant(i)});
2359
+ }
2360
+ constexpr info r = to_integral_constant(2); // OK, r represents the type
2361
+ // integral_constant<unsigned, 2>
2362
+ ```
2363
+
2364
+ — *end example*]
2365
+
2366
+ ### Expression result reflection <a id="meta.reflection.result">[[meta.reflection.result]]</a>
2367
+
2368
+ ``` cpp
2369
+ template<class T>
2370
+ consteval info reflect_constant(T expr);
2371
+ ```
2372
+
2373
+ *Mandates:* `is_copy_constructible_v<T>` is `true` and `T` is a
2374
+ cv-unqualified structural type [[temp.param]] that is not a reference
2375
+ type.
2376
+
2377
+ Let V be:
2378
+
2379
+ - if `T` is a class type, then an object that is
2380
+ template-argument-equivalent to the value of `expr`;
2381
+ - otherwise, the value of `expr`.
2382
+
2383
+ Let `TCls` be the invented template:
2384
+
2385
+ ``` cpp
2386
+ template<T P> struct TCls;
2387
+ ```
2388
+
2389
+ *Returns:* `template_arguments_of(``)[0]`.
2390
+
2391
+ [*Note 1*: This is a reflection of an object for class types, and a
2392
+ reflection of a value otherwise. — *end note*]
2393
+
2394
+ *Throws:* `meta::exception` unless the *template-id* `TCls<`V`>` would
2395
+ be valid.
2396
+
2397
+ [*Example 1*:
2398
+
2399
+ ``` cpp
2400
+ template<auto D>
2401
+ struct A { };
2402
+
2403
+ struct N { int x; };
2404
+ struct K { char const* p; };
2405
+
2406
+ constexpr info r1 = reflect_constant(42);
2407
+ static_assert(is_value(r1));
2408
+ static_assert(r1 == template_arguments_of(^^A<42>)[0]);
2409
+
2410
+ constexpr info r2 = reflect_constant(N{42});
2411
+ static_assert(is_object(r2));
2412
+ static_assert(r2 == template_arguments_of(^^A<N{42}>)[0]);
2413
+
2414
+ constexpr info r3 = reflect_constant(K{nullptr}); // OK
2415
+ constexpr info r4 = reflect_constant(K{"ebab"}); // error: constituent pointer
2416
+ // points to string literal
2417
+ ```
2418
+
2419
+ — *end example*]
2420
+
2421
+ ``` cpp
2422
+ template<class T>
2423
+ consteval info reflect_object(T& expr);
2424
+ ```
2425
+
2426
+ *Mandates:* `T` is an object type.
2427
+
2428
+ *Returns:* A reflection of the object designated by `expr`.
2429
+
2430
+ *Throws:* `meta::exception` unless `expr` is suitable for use as a
2431
+ constant template argument for a constant template parameter of type
2432
+ `T&` [[temp.arg.nontype]].
2433
+
2434
+ ``` cpp
2435
+ template<class T>
2436
+ consteval info reflect_function(T& fn);
2437
+ ```
2438
+
2439
+ *Mandates:* `T` is a function type.
2440
+
2441
+ *Returns:* A reflection of the function designated by `fn`.
2442
+
2443
+ *Throws:* `meta::exception` unless `fn` is suitable for use as a
2444
+ constant template argument for a constant template parameter of type
2445
+ `T&` [[temp.arg.nontype]].
2446
+
2447
+ ### Reflection class definition generation <a id="meta.reflection.define.aggregate">[[meta.reflection.define.aggregate]]</a>
2448
+
2449
+ ``` cpp
2450
+ namespace std::meta {
2451
+ struct data_member_options {
2452
+ struct name-type { // exposition only
2453
+ template<class T>
2454
+ requires constructible_from<u8string, T>
2455
+ consteval name-type(T&&);
2456
+
2457
+ template<class T>
2458
+ requires constructible_from<string, T>
2459
+ consteval name-type(T&&);
2460
+
2461
+ private:
2462
+ variant<u8string, string> contents; // exposition only
2463
+ };
2464
+
2465
+ optional<name-type> name;
2466
+ optional<int> alignment;
2467
+ optional<int> bit_width;
2468
+ bool no_unique_address = false;
2469
+ };
2470
+ }
2471
+ ```
2472
+
2473
+ The classes `data_member_options` and `data_member_options::name-type`
2474
+ are consteval-only types [[basic.types.general]], and are not structural
2475
+ types [[temp.param]].
2476
+
2477
+ ``` cpp
2478
+ template<class T>
2479
+ requires constructible_from<u8string, T>
2480
+ consteval name-type(T&& value);
2481
+ ```
2482
+
2483
+ *Effects:* Initializes *contents* with
2484
+ `u8string(std::forward<T>(value))`.
2485
+
2486
+ ``` cpp
2487
+ template<class T>
2488
+ requires constructible_from<string, T>
2489
+ consteval name-type(T&& value);
2490
+ ```
2491
+
2492
+ *Effects:* Initializes *contents* with `string(std::forward<T>(value))`.
2493
+
2494
+ [*Note 1*:
2495
+
2496
+ The class *name-type* allows the function `data_member_spec` to accept
2497
+ an ordinary string literal (or `string_view`, `string`, etc.) or a UTF-8
2498
+ string literal (or `u8string_view`, `u8string`, etc.) equally well.
2499
+
2500
+ [*Example 1*:
2501
+
2502
+ consteval void fn() {
2503
+ data_member_options o1 = {.name = "ordinary_literal_encoding"};
2504
+ data_member_options o2 = {.name = u8"utf8_encoding"};
2505
+ }
2506
+
2507
+ — *end example*]
2508
+
2509
+ — *end note*]
2510
+
2511
+ ``` cpp
2512
+ consteval info data_member_spec(info type, data_member_options options);
2513
+ ```
2514
+
2515
+ *Returns:* A reflection of a data member description
2516
+ (T, N, A, W, *NUA*)[[class.mem.general]] where
2517
+
2518
+ - T is the type represented by `dealias(type)`,
2519
+ - N is either the identifier encoded by `options.name` or $\bot$ if
2520
+ `options.name` does not contain a value,
2521
+ - A is either the alignment value held by `options.alignment` or $\bot$
2522
+ if `options.alignment` does not contain a value,
2523
+ - W is either the value held by `options.bit_width` or $\bot$ if
2524
+ `options.bit_width` does not contain a value, and
2525
+ - *NUA* is the value held by `options.no_unique_address`.
2526
+
2527
+ [*Note 2*: The returned reflection value is primarily useful in
2528
+ conjunction with `define_aggregate`; it can also be queried by certain
2529
+ other functions in `std::meta` (e.g., `type_of`,
2530
+ `identifier_of`). — *end note*]
2531
+
2532
+ *Throws:* `meta::exception` unless the following conditions are met:
2533
+
2534
+ - `dealias(type)` represents either an object type or a reference type;
2535
+ - if `options.name` contains a value, then:
2536
+ - `holds_alternative<u8string>(options.name->`*`contents`*`)` is
2537
+ `true` and `get<u8string>(options.name->`*`contents`*`)` contains a
2538
+ valid identifier [[lex.name]] that is not a keyword [[lex.key]] when
2539
+ interpreted with UTF-8, or
2540
+ - `holds_alternative<string>(options.name->`*`contents`*`)` is `true`
2541
+ and `get<string>(options.name->`*`contents`*`)` contains a valid
2542
+ identifier [[lex.name]] that is not a keyword [[lex.key]] when
2543
+ interpreted with the ordinary literal encoding;
2544
+
2545
+ \[*Note 1*: The name corresponds to the spelling of an
2546
+ identifier token after phase 6 of translation [[lex.phases]].
2547
+ Lexical constructs like
2548
+ *universal-character-name*s [[lex.universal.char]] are not
2549
+ processed and will cause evaluation to fail. For example,
2550
+ `R"(\u03B1)"` is an invalid identifier and is not interpreted as
2551
+ `"`α`"`. — *end note*]
2552
+ - if `options.name` does not contain a value, then `options.bit_width`
2553
+ contains a value;
2554
+ - if `options.bit_width` contains a value V, then
2555
+ - `is_integral_type(type) || is_enum_type(type)` is `true`,
2556
+ - `options.alignment` does not contain a value,
2557
+ - `options.no_unique_address` is `false`, and
2558
+ - if V equals `0`, then `options.name` does not contain a value; and
2559
+ - if `options.alignment` contains a value, it is an alignment
2560
+ value [[basic.align]] not less than `alignment_of(type)`.
2561
+
2562
+ ``` cpp
2563
+ consteval bool is_data_member_spec(info r);
2564
+ ```
2565
+
2566
+ *Returns:* `true` if `r` represents a data member description.
2567
+ Otherwise, `false`.
2568
+
2569
+ ``` cpp
2570
+ template<reflection_range R = initializer_list<info>>
2571
+ consteval info define_aggregate(info class_type, R&& mdescrs);
2572
+ ```
2573
+
2574
+ Let C be the class represented by `class_type` and $r_K$ be the Kᵗʰ
2575
+ reflection value in `mdescrs`. For every $r_K$ in `mdescrs`, let
2576
+ $(T_K, N_K, A_K, W_K, *NUA*_K)$ be the corresponding data member
2577
+ description represented by $r_K$.
2578
+
2579
+ - C is incomplete from every point in the evaluation context;
2580
+ \[*Note 2*: C can be a class template specialization for which there
2581
+ is a reachable definition of the class template. In this case, the
2582
+ injected declaration is an explicit specialization. — *end note*]
2583
+ - `is_data_member_spec(`$r_K$`)` is `true` for every $r_K$;
2584
+ - `is_complete_type(`$T_K$`)` is `true` for every $r_K$; and
2585
+ - for every pair $(r_K, r_L)$ where K < L, if $N_K$ is not $\bot$ and
2586
+ $N_L$ is not $\bot$, then either:
2587
+ - $N_K$` != `$N_L$ is `true` or
2588
+ - $N_K$` == u8"_"` is `true`. \[*Note 3*: Every provided identifier is
2589
+ unique or `"_"`. — *end note*]
2590
+
2591
+ *Effects:* Produces an injected declaration D[[expr.const]] that defines
2592
+ C and has properties as follows:
2593
+
2594
+ - The target scope of D is the scope to which C
2595
+ belongs [[basic.scope.scope]].
2596
+ - The locus of D follows immediately after the core constant expression
2597
+ currently under evaluation.
2598
+ - The characteristic sequence of D[[expr.const]] is the sequence of
2599
+ reflection values $r_K$.
2600
+ - If C is a specialization of a templated class T, and C is not a local
2601
+ class, then D is an explicit specialization of T.
2602
+ - For each $r_K$, there is a corresponding entity $M_K$ belonging to the
2603
+ class scope of D with the following properties:
2604
+ - If $N_K$ is $\bot$, $M_K$ is an unnamed bit-field. Otherwise, $M_K$
2605
+ is a non-static data member whose name is the identifier determined
2606
+ by the character sequence encoded by $N_K$ in UTF-8.
2607
+ - The type of $M_K$ is $T_K$.
2608
+ - $M_K$ is declared with the attribute `[[no_unique_address]]` if and
2609
+ only if *NUA*_K is `true`.
2610
+ - If $W_K$ is not $\bot$, $M_K$ is a bit-field whose width is that
2611
+ value. Otherwise, $M_K$ is not a bit-field.
2612
+ - If $A_K$ is not $\bot$, $M_K$ has the *alignment-specifier*
2613
+ `alignas(`$A_K$`)`. Otherwise, $M_K$ has no *alignment-specifier*.
2614
+ - For every $r_L$ in `mdescrs` such that K < L, the declaration
2615
+ corresponding to $r_K$ precedes the declaration corresponding to
2616
+ $r_L$.
2617
+
2618
+ *Returns:* `class_type`.
2619
+
2620
+ ### Reflection type traits <a id="meta.reflection.traits">[[meta.reflection.traits]]</a>
2621
+
2622
+ This subclause specifies `consteval` functions to query the properties
2623
+ of types [[meta.unary]], query the relationships between types
2624
+ [[meta.rel]], or transform types [[meta.trans]], during program
2625
+ translation. Each `consteval` function declared in this class has an
2626
+ associated class template declared elsewhere in this document.
2627
+
2628
+ Every function and function template declared in this subclause throws
2629
+ an exception of type `meta::exception` unless the following conditions
2630
+ are met:
2631
+
2632
+ - For every parameter `p` of type `info`, `is_type(p)` is `true`.
2633
+ - For every parameter `r` whose type is constrained on
2634
+ `reflection_range`, `ranges::{}all_of({}r, is_type)` is `true`.
2635
+
2636
+ ``` cpp
2637
+ // associated with [meta.unary.cat], primary type categories
2638
+ consteval bool is_void_type(info type);
2639
+ consteval bool is_null_pointer_type(info type);
2640
+ consteval bool is_integral_type(info type);
2641
+ consteval bool is_floating_point_type(info type);
2642
+ consteval bool is_array_type(info type);
2643
+ consteval bool is_pointer_type(info type);
2644
+ consteval bool is_lvalue_reference_type(info type);
2645
+ consteval bool is_rvalue_reference_type(info type);
2646
+ consteval bool is_member_object_pointer_type(info type);
2647
+ consteval bool is_member_function_pointer_type(info type);
2648
+ consteval bool is_enum_type(info type);
2649
+ consteval bool is_union_type(info type);
2650
+ consteval bool is_class_type(info type);
2651
+ consteval bool is_function_type(info type);
2652
+ consteval bool is_reflection_type(info type);
2653
+
2654
+ // associated with [meta.unary.comp], composite type categories
2655
+ consteval bool is_reference_type(info type);
2656
+ consteval bool is_arithmetic_type(info type);
2657
+ consteval bool is_fundamental_type(info type);
2658
+ consteval bool is_object_type(info type);
2659
+ consteval bool is_scalar_type(info type);
2660
+ consteval bool is_compound_type(info type);
2661
+ consteval bool is_member_pointer_type(info type);
2662
+
2663
+ // associated with [meta.unary.prop], type properties
2664
+ consteval bool is_const_type(info type);
2665
+ consteval bool is_volatile_type(info type);
2666
+ consteval bool is_trivially_copyable_type(info type);
2667
+ consteval bool is_trivially_relocatable_type(info type);
2668
+ consteval bool is_replaceable_type(info type);
2669
+ consteval bool is_standard_layout_type(info type);
2670
+ consteval bool is_empty_type(info type);
2671
+ consteval bool is_polymorphic_type(info type);
2672
+ consteval bool is_abstract_type(info type);
2673
+ consteval bool is_final_type(info type);
2674
+ consteval bool is_aggregate_type(info type);
2675
+ consteval bool is_consteval_only_type(info type);
2676
+ consteval bool is_signed_type(info type);
2677
+ consteval bool is_unsigned_type(info type);
2678
+ consteval bool is_bounded_array_type(info type);
2679
+ consteval bool is_unbounded_array_type(info type);
2680
+ consteval bool is_scoped_enum_type(info type);
2681
+
2682
+ template<reflection_range R = initializer_list<info>>
2683
+ consteval bool is_constructible_type(info type, R&& type_args);
2684
+ consteval bool is_default_constructible_type(info type);
2685
+ consteval bool is_copy_constructible_type(info type);
2686
+ consteval bool is_move_constructible_type(info type);
2687
+
2688
+ consteval bool is_assignable_type(info type_dst, info type_src);
2689
+ consteval bool is_copy_assignable_type(info type);
2690
+ consteval bool is_move_assignable_type(info type);
2691
+
2692
+ consteval bool is_swappable_with_type(info type1, info type2);
2693
+ consteval bool is_swappable_type(info type);
2694
+
2695
+ consteval bool is_destructible_type(info type);
2696
+
2697
+ template<reflection_range R = initializer_list<info>>
2698
+ consteval bool is_trivially_constructible_type(info type, R&& type_args);
2699
+ consteval bool is_trivially_default_constructible_type(info type);
2700
+ consteval bool is_trivially_copy_constructible_type(info type);
2701
+ consteval bool is_trivially_move_constructible_type(info type);
2702
+
2703
+ consteval bool is_trivially_assignable_type(info type_dst, info type_src);
2704
+ consteval bool is_trivially_copy_assignable_type(info type);
2705
+ consteval bool is_trivially_move_assignable_type(info type);
2706
+ consteval bool is_trivially_destructible_type(info type);
2707
+
2708
+ template<reflection_range R = initializer_list<info>>
2709
+ consteval bool is_nothrow_constructible_type(info type, R&& type_args);
2710
+ consteval bool is_nothrow_default_constructible_type(info type);
2711
+ consteval bool is_nothrow_copy_constructible_type(info type);
2712
+ consteval bool is_nothrow_move_constructible_type(info type);
2713
+
2714
+ consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
2715
+ consteval bool is_nothrow_copy_assignable_type(info type);
2716
+ consteval bool is_nothrow_move_assignable_type(info type);
2717
+
2718
+ consteval bool is_nothrow_swappable_with_type(info type1, info type2);
2719
+ consteval bool is_nothrow_swappable_type(info type);
2720
+
2721
+ consteval bool is_nothrow_destructible_type(info type);
2722
+ consteval bool is_nothrow_relocatable_type(info type);
2723
+
2724
+ consteval bool is_implicit_lifetime_type(info type);
2725
+
2726
+ consteval bool has_virtual_destructor(info type);
2727
+
2728
+ consteval bool has_unique_object_representations(info type);
2729
+
2730
+ consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
2731
+ consteval bool reference_converts_from_temporary(info type_dst, info type_src);
2732
+
2733
+ // associated with [meta.rel], type relations
2734
+ consteval bool is_same_type(info type1, info type2);
2735
+ consteval bool is_base_of_type(info type_base, info type_derived);
2736
+ consteval bool is_virtual_base_of_type(info type_base, info type_derived);
2737
+ consteval bool is_convertible_type(info type_src, info type_dst);
2738
+ consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
2739
+ consteval bool is_layout_compatible_type(info type1, info type2);
2740
+ consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
2741
+
2742
+ template<reflection_range R = initializer_list<info>>
2743
+ consteval bool is_invocable_type(info type, R&& type_args);
2744
+ template<reflection_range R = initializer_list<info>>
2745
+ consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
2746
+
2747
+ template<reflection_range R = initializer_list<info>>
2748
+ consteval bool is_nothrow_invocable_type(info type, R&& type_args);
2749
+ template<reflection_range R = initializer_list<info>>
2750
+ consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
2751
+
2752
+ // associated with [meta.trans.cv], const-volatile modifications
2753
+ consteval info remove_const(info type);
2754
+ consteval info remove_volatile(info type);
2755
+ consteval info remove_cv(info type);
2756
+ consteval info add_const(info type);
2757
+ consteval info add_volatile(info type);
2758
+ consteval info add_cv(info type);
2759
+
2760
+ // associated with [meta.trans.ref], reference modifications
2761
+ consteval info remove_reference(info type);
2762
+ consteval info add_lvalue_reference(info type);
2763
+ consteval info add_rvalue_reference(info type);
2764
+
2765
+ // associated with [meta.trans.sign], sign modifications
2766
+ consteval info make_signed(info type);
2767
+ consteval info make_unsigned(info type);
2768
+
2769
+ // associated with [meta.trans.arr], array modifications
2770
+ consteval info remove_extent(info type);
2771
+ consteval info remove_all_extents(info type);
2772
+
2773
+ // associated with [meta.trans.ptr], pointer modifications
2774
+ consteval info remove_pointer(info type);
2775
+ consteval info add_pointer(info type);
2776
+
2777
+ // associated with [meta.trans.other], other transformations
2778
+ consteval info remove_cvref(info type);
2779
+ consteval info decay(info type);
2780
+ template<reflection_range R = initializer_list<info>>
2781
+ consteval info common_type(R&& type_args);
2782
+ template<reflection_range R = initializer_list<info>>
2783
+ consteval info common_reference(R&& type_args);
2784
+ consteval info underlying_type(info type);
2785
+ template<reflection_range R = initializer_list<info>>
2786
+ consteval info invoke_result(info type, R&& type_args);
2787
+ consteval info unwrap_reference(info type);
2788
+ consteval info unwrap_ref_decay(info type);
2789
+ ```
2790
+
2791
+ Each function or function template declared above has the following
2792
+ behavior based on the signature and return type of that function or
2793
+ function template.
2794
+
2795
+ [*Note 1*: The associated class template need not be
2796
+ instantiated. — *end note*]
2797
+
2798
+ [*Note 2*: For those functions or function templates which return a
2799
+ reflection, that reflection always represents a type and never a type
2800
+ alias. — *end note*]
2801
+
2802
+ [*Note 3*: If `t` is a reflection of the type `int` and `u` is a
2803
+ reflection of an alias to the type `int`, then `t == u` is `false` but
2804
+ `is_same_type(t, u)` is `true`. Also, `t == dealias(u)` is
2805
+ `true`. — *end note*]
2806
+
2807
+ ``` cpp
2808
+ consteval size_t rank(info type);
2809
+ ```
2810
+
2811
+ *Returns:* `rank_v<`T`>`, where T is the type represented by
2812
+ `dealias(type)`.
2813
+
2814
+ ``` cpp
2815
+ consteval size_t extent(info type, unsigned i = 0);
2816
+ ```
2817
+
2818
+ *Returns:* `extent_v<`T`, `I`>`, where T is the type represented by
2819
+ `dealias(type)` and I is a constant equal to `i`.
2820
+
2821
+ ``` cpp
2822
+ consteval size_t tuple_size(info type);
2823
+ ```
2824
+
2825
+ *Returns:* `tuple_size_v<`T`>`, where T is the type represented by
2826
+ `dealias(type)`.
2827
+
2828
+ ``` cpp
2829
+ consteval info tuple_element(size_t index, info type);
2830
+ ```
2831
+
2832
+ *Returns:* A reflection representing the type denoted by
2833
+ `tuple_element_t<`I`, `T`>`, where T is the type represented by
2834
+ `dealias(type)` and I is a constant equal to `index`.
2835
+
2836
+ ``` cpp
2837
+ consteval size_t variant_size(info type);
2838
+ ```
2839
+
2840
+ *Returns:* `variant_size_v<`T`>`, where T is the type represented by
2841
+ `dealias(type)`.
2842
+
2843
+ ``` cpp
2844
+ consteval info variant_alternative(size_t index, info type);
2845
+ ```
2846
+
2847
+ *Returns:* A reflection representing the type denoted by
2848
+ `variant_alternative_t<`I`, `T`>`, where T is the type represented by
2849
+ `dealias(type)` and I is a constant equal to `index`.
2850
+
2851
+ ``` cpp
2852
+ consteval strong_ordering type_order(info t1, info t2);
2853
+ ```
2854
+
2855
+ *Returns:* `type_order_v<`T₁`, `T₂`>`, where T₁ and T₂ are the types
2856
+ represented by `dealias(t1)` and `dealias(t2)`, respectively.
2857
+