From Jason Turner

[expr.prim.req]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpkd9xf9bs/{from.md → to.md} +304 -0
tmp/tmpkd9xf9bs/{from.md → to.md} RENAMED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Requires expressions <a id="expr.prim.req">[[expr.prim.req]]</a>
2
+
3
+ A *requires-expression* provides a concise way to express requirements
4
+ on template arguments that can be checked by name lookup
5
+ [[basic.lookup]] or by checking properties of types and expressions.
6
+
7
+ ``` bnf
8
+ requires-expression:
9
+ requires requirement-parameter-listₒₚₜ requirement-body
10
+ ```
11
+
12
+ ``` bnf
13
+ requirement-parameter-list:
14
+ '(' parameter-declaration-clauseₒₚₜ ')'
15
+ ```
16
+
17
+ ``` bnf
18
+ requirement-body:
19
+ '{' requirement-seq '}'
20
+ ```
21
+
22
+ ``` bnf
23
+ requirement-seq:
24
+ requirement
25
+ requirement-seq requirement
26
+ ```
27
+
28
+ ``` bnf
29
+ requirement:
30
+ simple-requirement
31
+ type-requirement
32
+ compound-requirement
33
+ nested-requirement
34
+ ```
35
+
36
+ A *requires-expression* is a prvalue of type `bool` whose value is
37
+ described below. Expressions appearing within a *requirement-body* are
38
+ unevaluated operands [[expr.prop]].
39
+
40
+ [*Example 1*:
41
+
42
+ A common use of *requires-expression*s is to define requirements in
43
+ concepts such as the one below:
44
+
45
+ ``` cpp
46
+ template<typename T>
47
+ concept R = requires (T i) {
48
+ typename T::type;
49
+ {*i} -> std::convertible_to<const typename T::type&>;
50
+ };
51
+ ```
52
+
53
+ A *requires-expression* can also be used in a *requires-clause*
54
+ [[temp.pre]] as a way of writing ad hoc constraints on template
55
+ arguments such as the one below:
56
+
57
+ ``` cpp
58
+ template<typename T>
59
+ requires requires (T x) { x + x; }
60
+ T add(T a, T b) { return a + b; }
61
+ ```
62
+
63
+ The first `requires` introduces the *requires-clause*, and the second
64
+ introduces the *requires-expression*.
65
+
66
+ — *end example*]
67
+
68
+ A *requires-expression* may introduce local parameters using a
69
+ *parameter-declaration-clause* [[dcl.fct]]. A local parameter of a
70
+ *requires-expression* shall not have a default argument. Each name
71
+ introduced by a local parameter is in scope from the point of its
72
+ declaration until the closing brace of the *requirement-body*. These
73
+ parameters have no linkage, storage, or lifetime; they are only used as
74
+ notation for the purpose of defining *requirement*s. The
75
+ *parameter-declaration-clause* of a *requirement-parameter-list* shall
76
+ not terminate with an ellipsis.
77
+
78
+ [*Example 2*:
79
+
80
+ ``` cpp
81
+ template<typename T>
82
+ concept C = requires(T t, ...) { // error: terminates with an ellipsis
83
+ t;
84
+ };
85
+ ```
86
+
87
+ — *end example*]
88
+
89
+ The *requirement-body* contains a sequence of *requirement*s. These
90
+ *requirement*s may refer to local parameters, template parameters, and
91
+ any other declarations visible from the enclosing context.
92
+
93
+ The substitution of template arguments into a *requires-expression* may
94
+ result in the formation of invalid types or expressions in its
95
+ *requirement*s or the violation of the semantic constraints of those
96
+ *requirement*s. In such cases, the *requires-expression* evaluates to
97
+ `false`; it does not cause the program to be ill-formed. The
98
+ substitution and semantic constraint checking proceeds in lexical order
99
+ and stops when a condition that determines the result of the
100
+ *requires-expression* is encountered. If substitution (if any) and
101
+ semantic constraint checking succeed, the *requires-expression*
102
+ evaluates to `true`.
103
+
104
+ [*Note 1*: If a *requires-expression* contains invalid types or
105
+ expressions in its *requirement*s, and it does not appear within the
106
+ declaration of a templated entity, then the program is
107
+ ill-formed. — *end note*]
108
+
109
+ If the substitution of template arguments into a *requirement* would
110
+ always result in a substitution failure, the program is ill-formed; no
111
+ diagnostic required.
112
+
113
+ [*Example 3*:
114
+
115
+ ``` cpp
116
+ template<typename T> concept C =
117
+ requires {
118
+ new int[-(int)sizeof(T)]; // ill-formed, no diagnostic required
119
+ };
120
+ ```
121
+
122
+ — *end example*]
123
+
124
+ #### Simple requirements <a id="expr.prim.req.simple">[[expr.prim.req.simple]]</a>
125
+
126
+ ``` bnf
127
+ simple-requirement:
128
+ expression ';'
129
+ ```
130
+
131
+ A *simple-requirement* asserts the validity of an *expression*.
132
+
133
+ [*Note 1*: The enclosing *requires-expression* will evaluate to `false`
134
+ if substitution of template arguments into the *expression* fails. The
135
+ *expression* is an unevaluated operand [[expr.prop]]. — *end note*]
136
+
137
+ [*Example 1*:
138
+
139
+ ``` cpp
140
+ template<typename T> concept C =
141
+ requires (T a, T b) {
142
+ a + b; // C<T> is true if a + b is a valid expression
143
+ };
144
+ ```
145
+
146
+ — *end example*]
147
+
148
+ A *requirement* that starts with a `requires` token is never interpreted
149
+ as a *simple-requirement*.
150
+
151
+ [*Note 2*: This simplifies distinguishing between a
152
+ *simple-requirement* and a *nested-requirement*. — *end note*]
153
+
154
+ #### Type requirements <a id="expr.prim.req.type">[[expr.prim.req.type]]</a>
155
+
156
+ ``` bnf
157
+ type-requirement:
158
+ typename nested-name-specifierₒₚₜ type-name ';'
159
+ ```
160
+
161
+ A *type-requirement* asserts the validity of a type.
162
+
163
+ [*Note 1*: The enclosing *requires-expression* will evaluate to `false`
164
+ if substitution of template arguments fails. — *end note*]
165
+
166
+ [*Example 1*:
167
+
168
+ ``` cpp
169
+ template<typename T, typename T::type = 0> struct S;
170
+ template<typename T> using Ref = T&;
171
+
172
+ template<typename T> concept C = requires {
173
+ typename T::inner; // required nested member name
174
+ typename S<T>; // required class template specialization
175
+ typename Ref<T>; // required alias template substitution, fails if T is void
176
+ };
177
+ ```
178
+
179
+ — *end example*]
180
+
181
+ A *type-requirement* that names a class template specialization does not
182
+ require that type to be complete [[basic.types]].
183
+
184
+ #### Compound requirements <a id="expr.prim.req.compound">[[expr.prim.req.compound]]</a>
185
+
186
+ ``` bnf
187
+ compound-requirement:
188
+ '{' expression '}' noexceptₒₚₜ return-type-requirementₒₚₜ ';'
189
+ ```
190
+
191
+ ``` bnf
192
+ return-type-requirement:
193
+ '->' type-constraint
194
+ ```
195
+
196
+ A *compound-requirement* asserts properties of the *expression* E.
197
+ Substitution of template arguments (if any) and verification of semantic
198
+ properties proceed in the following order:
199
+
200
+ - Substitution of template arguments (if any) into the *expression* is
201
+ performed.
202
+ - If the `noexcept` specifier is present, E shall not be a
203
+ potentially-throwing expression [[except.spec]].
204
+ - If the *return-type-requirement* is present, then:
205
+ - Substitution of template arguments (if any) into the
206
+ *return-type-requirement* is performed.
207
+ - The immediately-declared constraint [[temp.param]] of the
208
+ *type-constraint* for `decltype((E))` shall be satisfied.
209
+ \[*Example 1*:
210
+ Given concepts `C` and `D`,
211
+ ``` cpp
212
+ requires {
213
+ { E1 } -> C;
214
+ { E2 } -> D<A₁, ⋯, Aₙ>;
215
+ };
216
+ ```
217
+
218
+ is equivalent to
219
+ ``` cpp
220
+ requires {
221
+ E1; requires C<decltype((E1))>;
222
+ E2; requires D<decltype((E2)), A₁, ⋯, Aₙ>;
223
+ };
224
+ ```
225
+
226
+ (including in the case where n is zero).
227
+ — *end example*]
228
+
229
+ [*Example 2*:
230
+
231
+ ``` cpp
232
+ template<typename T> concept C1 = requires(T x) {
233
+ {x++};
234
+ };
235
+ ```
236
+
237
+ The *compound-requirement* in `C1` requires that `x++` is a valid
238
+ expression. It is equivalent to the *simple-requirement* `x++;`.
239
+
240
+ ``` cpp
241
+ template<typename T> concept C2 = requires(T x) {
242
+ {*x} -> std::same_as<typename T::inner>;
243
+ };
244
+ ```
245
+
246
+ The *compound-requirement* in `C2` requires that `*x` is a valid
247
+ expression, that `typename T::inner` is a valid type, and that
248
+ `std::same_as<decltype((*x)), typename T::inner>` is satisfied.
249
+
250
+ ``` cpp
251
+ template<typename T> concept C3 =
252
+ requires(T x) {
253
+ {g(x)} noexcept;
254
+ };
255
+ ```
256
+
257
+ The *compound-requirement* in `C3` requires that `g(x)` is a valid
258
+ expression and that `g(x)` is non-throwing.
259
+
260
+ — *end example*]
261
+
262
+ #### Nested requirements <a id="expr.prim.req.nested">[[expr.prim.req.nested]]</a>
263
+
264
+ ``` bnf
265
+ nested-requirement:
266
+ requires constraint-expression ';'
267
+ ```
268
+
269
+ A *nested-requirement* can be used to specify additional constraints in
270
+ terms of local parameters. The *constraint-expression* shall be
271
+ satisfied [[temp.constr.decl]] by the substituted template arguments, if
272
+ any. Substitution of template arguments into a *nested-requirement* does
273
+ not result in substitution into the *constraint-expression* other than
274
+ as specified in [[temp.constr.constr]].
275
+
276
+ [*Example 1*:
277
+
278
+ ``` cpp
279
+ template<typename U> concept C = sizeof(U) == 1;
280
+
281
+ template<typename T> concept D = requires (T t) {
282
+ requires C<decltype (+t)>;
283
+ };
284
+ ```
285
+
286
+ `D<T>` is satisfied if `sizeof(decltype (+t)) == 1`
287
+ [[temp.constr.atomic]].
288
+
289
+ — *end example*]
290
+
291
+ A local parameter shall only appear as an unevaluated operand
292
+ [[expr.prop]] within the *constraint-expression*.
293
+
294
+ [*Example 2*:
295
+
296
+ ``` cpp
297
+ template<typename T> concept C = requires (T a) {
298
+ requires sizeof(a) == 4; // OK
299
+ requires a == 0; // error: evaluation of a constraint variable
300
+ };
301
+ ```
302
+
303
+ — *end example*]
304
+