tmp/tmp2tk1t3d_/{from.md → to.md}
RENAMED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
### Constraint normalization <a id="temp.constr.normal">[[temp.constr.normal]]</a>
|
| 2 |
+
|
| 3 |
+
The *normal form* of an *expression* `E` is a constraint
|
| 4 |
+
[[temp.constr.constr]] that is defined as follows:
|
| 5 |
+
|
| 6 |
+
- The normal form of an expression `( E )` is the normal form of `E`.
|
| 7 |
+
- The normal form of an expression `E1 || E2` is the disjunction
|
| 8 |
+
[[temp.constr.op]] of the normal forms of `E1` and `E2`.
|
| 9 |
+
- The normal form of an expression `E1 && E2` is the conjunction of the
|
| 10 |
+
normal forms of `E1` and `E2`.
|
| 11 |
+
- The normal form of a concept-id `C<A₁, A₂, ..., Aₙ>` is the normal
|
| 12 |
+
form of the *constraint-expression* of `C`, after substituting
|
| 13 |
+
`A₁, A₂, ..., Aₙ` for `C`'s respective template parameters in the
|
| 14 |
+
parameter mappings in each atomic constraint. If any such substitution
|
| 15 |
+
results in an invalid type or expression, the program is ill-formed;
|
| 16 |
+
no diagnostic is required.
|
| 17 |
+
\[*Example 1*:
|
| 18 |
+
``` cpp
|
| 19 |
+
template<typename T> concept A = T::value || true;
|
| 20 |
+
template<typename U> concept B = A<U*>;
|
| 21 |
+
template<typename V> concept C = B<V&>;
|
| 22 |
+
```
|
| 23 |
+
|
| 24 |
+
Normalization of `B`'s *constraint-expression* is valid and results in
|
| 25 |
+
`T::value` (with the mapping `T` ↦ `U*`) ∨ `true` (with an empty
|
| 26 |
+
mapping), despite the expression `T::value` being ill-formed for a
|
| 27 |
+
pointer type `T`. Normalization of `C`'s *constraint-expression*
|
| 28 |
+
results in the program being ill-formed, because it would form the
|
| 29 |
+
invalid type `V&*` in the parameter mapping.
|
| 30 |
+
— *end example*]
|
| 31 |
+
- The normal form of any other expression `E` is the atomic constraint
|
| 32 |
+
whose expression is `E` and whose parameter mapping is the identity
|
| 33 |
+
mapping.
|
| 34 |
+
|
| 35 |
+
The process of obtaining the normal form of a *constraint-expression* is
|
| 36 |
+
called *normalization*.
|
| 37 |
+
|
| 38 |
+
[*Note 1*: Normalization of *constraint-expression*s is performed when
|
| 39 |
+
determining the associated constraints [[temp.constr.constr]] of a
|
| 40 |
+
declaration and when evaluating the value of an *id-expression* that
|
| 41 |
+
names a concept specialization [[expr.prim.id]]. — *end note*]
|
| 42 |
+
|
| 43 |
+
[*Example 2*:
|
| 44 |
+
|
| 45 |
+
``` cpp
|
| 46 |
+
template<typename T> concept C1 = sizeof(T) == 1;
|
| 47 |
+
template<typename T> concept C2 = C1<T> && 1 == 2;
|
| 48 |
+
template<typename T> concept C3 = requires { typename T::type; };
|
| 49 |
+
template<typename T> concept C4 = requires (T x) { ++x; }
|
| 50 |
+
|
| 51 |
+
template<C2 U> void f1(U); // #1
|
| 52 |
+
template<C3 U> void f2(U); // #2
|
| 53 |
+
template<C4 U> void f3(U); // #3
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
The associated constraints of \#1 are `sizeof(T) == 1` (with mapping
|
| 57 |
+
`T` ↦ `U`) ∧ `1 == 2`.
|
| 58 |
+
The associated constraints of \#2 are `requires { typename T::type; }`
|
| 59 |
+
(with mapping `T` ↦ `U`).
|
| 60 |
+
The associated constraints of \#3 are `requires (T x) { ++x; }` (with
|
| 61 |
+
mapping `T` ↦ `U`).
|
| 62 |
+
|
| 63 |
+
— *end example*]
|
| 64 |
+
|