From Jason Turner

[meta.reflection.define.aggregate]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpj_3x929e/{from.md → to.md} +173 -0
tmp/tmpj_3x929e/{from.md → to.md} RENAMED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Reflection class definition generation <a id="meta.reflection.define.aggregate">[[meta.reflection.define.aggregate]]</a>
2
+
3
+ ``` cpp
4
+ namespace std::meta {
5
+ struct data_member_options {
6
+ struct name-type { // exposition only
7
+ template<class T>
8
+ requires constructible_from<u8string, T>
9
+ consteval name-type(T&&);
10
+
11
+ template<class T>
12
+ requires constructible_from<string, T>
13
+ consteval name-type(T&&);
14
+
15
+ private:
16
+ variant<u8string, string> contents; // exposition only
17
+ };
18
+
19
+ optional<name-type> name;
20
+ optional<int> alignment;
21
+ optional<int> bit_width;
22
+ bool no_unique_address = false;
23
+ };
24
+ }
25
+ ```
26
+
27
+ The classes `data_member_options` and `data_member_options::name-type`
28
+ are consteval-only types [[basic.types.general]], and are not structural
29
+ types [[temp.param]].
30
+
31
+ ``` cpp
32
+ template<class T>
33
+ requires constructible_from<u8string, T>
34
+ consteval name-type(T&& value);
35
+ ```
36
+
37
+ *Effects:* Initializes *contents* with
38
+ `u8string(std::forward<T>(value))`.
39
+
40
+ ``` cpp
41
+ template<class T>
42
+ requires constructible_from<string, T>
43
+ consteval name-type(T&& value);
44
+ ```
45
+
46
+ *Effects:* Initializes *contents* with `string(std::forward<T>(value))`.
47
+
48
+ [*Note 1*:
49
+
50
+ The class *name-type* allows the function `data_member_spec` to accept
51
+ an ordinary string literal (or `string_view`, `string`, etc.) or a UTF-8
52
+ string literal (or `u8string_view`, `u8string`, etc.) equally well.
53
+
54
+ [*Example 1*:
55
+
56
+ consteval void fn() {
57
+ data_member_options o1 = {.name = "ordinary_literal_encoding"};
58
+ data_member_options o2 = {.name = u8"utf8_encoding"};
59
+ }
60
+
61
+ — *end example*]
62
+
63
+ — *end note*]
64
+
65
+ ``` cpp
66
+ consteval info data_member_spec(info type, data_member_options options);
67
+ ```
68
+
69
+ *Returns:* A reflection of a data member description
70
+ (T, N, A, W, *NUA*)[[class.mem.general]] where
71
+
72
+ - T is the type represented by `dealias(type)`,
73
+ - N is either the identifier encoded by `options.name` or $\bot$ if
74
+ `options.name` does not contain a value,
75
+ - A is either the alignment value held by `options.alignment` or $\bot$
76
+ if `options.alignment` does not contain a value,
77
+ - W is either the value held by `options.bit_width` or $\bot$ if
78
+ `options.bit_width` does not contain a value, and
79
+ - *NUA* is the value held by `options.no_unique_address`.
80
+
81
+ [*Note 2*: The returned reflection value is primarily useful in
82
+ conjunction with `define_aggregate`; it can also be queried by certain
83
+ other functions in `std::meta` (e.g., `type_of`,
84
+ `identifier_of`). — *end note*]
85
+
86
+ *Throws:* `meta::exception` unless the following conditions are met:
87
+
88
+ - `dealias(type)` represents either an object type or a reference type;
89
+ - if `options.name` contains a value, then:
90
+ - `holds_alternative<u8string>(options.name->`*`contents`*`)` is
91
+ `true` and `get<u8string>(options.name->`*`contents`*`)` contains a
92
+ valid identifier [[lex.name]] that is not a keyword [[lex.key]] when
93
+ interpreted with UTF-8, or
94
+ - `holds_alternative<string>(options.name->`*`contents`*`)` is `true`
95
+ and `get<string>(options.name->`*`contents`*`)` contains a valid
96
+ identifier [[lex.name]] that is not a keyword [[lex.key]] when
97
+ interpreted with the ordinary literal encoding;
98
+
99
+ \[*Note 1*: The name corresponds to the spelling of an
100
+ identifier token after phase 6 of translation [[lex.phases]].
101
+ Lexical constructs like
102
+ *universal-character-name*s [[lex.universal.char]] are not
103
+ processed and will cause evaluation to fail. For example,
104
+ `R"(\u03B1)"` is an invalid identifier and is not interpreted as
105
+ `"`α`"`. — *end note*]
106
+ - if `options.name` does not contain a value, then `options.bit_width`
107
+ contains a value;
108
+ - if `options.bit_width` contains a value V, then
109
+ - `is_integral_type(type) || is_enum_type(type)` is `true`,
110
+ - `options.alignment` does not contain a value,
111
+ - `options.no_unique_address` is `false`, and
112
+ - if V equals `0`, then `options.name` does not contain a value; and
113
+ - if `options.alignment` contains a value, it is an alignment
114
+ value [[basic.align]] not less than `alignment_of(type)`.
115
+
116
+ ``` cpp
117
+ consteval bool is_data_member_spec(info r);
118
+ ```
119
+
120
+ *Returns:* `true` if `r` represents a data member description.
121
+ Otherwise, `false`.
122
+
123
+ ``` cpp
124
+ template<reflection_range R = initializer_list<info>>
125
+ consteval info define_aggregate(info class_type, R&& mdescrs);
126
+ ```
127
+
128
+ Let C be the class represented by `class_type` and $r_K$ be the Kᵗʰ
129
+ reflection value in `mdescrs`. For every $r_K$ in `mdescrs`, let
130
+ $(T_K, N_K, A_K, W_K, *NUA*_K)$ be the corresponding data member
131
+ description represented by $r_K$.
132
+
133
+ - C is incomplete from every point in the evaluation context;
134
+ \[*Note 2*: C can be a class template specialization for which there
135
+ is a reachable definition of the class template. In this case, the
136
+ injected declaration is an explicit specialization. — *end note*]
137
+ - `is_data_member_spec(`$r_K$`)` is `true` for every $r_K$;
138
+ - `is_complete_type(`$T_K$`)` is `true` for every $r_K$; and
139
+ - for every pair $(r_K, r_L)$ where K < L, if $N_K$ is not $\bot$ and
140
+ $N_L$ is not $\bot$, then either:
141
+ - $N_K$` != `$N_L$ is `true` or
142
+ - $N_K$` == u8"_"` is `true`. \[*Note 3*: Every provided identifier is
143
+ unique or `"_"`. — *end note*]
144
+
145
+ *Effects:* Produces an injected declaration D[[expr.const]] that defines
146
+ C and has properties as follows:
147
+
148
+ - The target scope of D is the scope to which C
149
+ belongs [[basic.scope.scope]].
150
+ - The locus of D follows immediately after the core constant expression
151
+ currently under evaluation.
152
+ - The characteristic sequence of D[[expr.const]] is the sequence of
153
+ reflection values $r_K$.
154
+ - If C is a specialization of a templated class T, and C is not a local
155
+ class, then D is an explicit specialization of T.
156
+ - For each $r_K$, there is a corresponding entity $M_K$ belonging to the
157
+ class scope of D with the following properties:
158
+ - If $N_K$ is $\bot$, $M_K$ is an unnamed bit-field. Otherwise, $M_K$
159
+ is a non-static data member whose name is the identifier determined
160
+ by the character sequence encoded by $N_K$ in UTF-8.
161
+ - The type of $M_K$ is $T_K$.
162
+ - $M_K$ is declared with the attribute `[[no_unique_address]]` if and
163
+ only if *NUA*_K is `true`.
164
+ - If $W_K$ is not $\bot$, $M_K$ is a bit-field whose width is that
165
+ value. Otherwise, $M_K$ is not a bit-field.
166
+ - If $A_K$ is not $\bot$, $M_K$ has the *alignment-specifier*
167
+ `alignas(`$A_K$`)`. Otherwise, $M_K$ has no *alignment-specifier*.
168
+ - For every $r_L$ in `mdescrs` such that K < L, the declaration
169
+ corresponding to $r_K$ precedes the declaration corresponding to
170
+ $r_L$.
171
+
172
+ *Returns:* `class_type`.
173
+