From Jason Turner

[meta.trans]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpi8ts_fbf/{from.md → to.md} +105 -18
tmp/tmpi8ts_fbf/{from.md → to.md} RENAMED
@@ -2,22 +2,22 @@
2
 
3
  This subclause contains templates that may be used to transform one type
4
  to another following some predefined rule.
5
 
6
  Each of the templates in this subclause shall be a
7
- `TransformationTrait` ([[meta.rqmts]]).
8
 
9
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
10
 
11
  [*Example 1*: `remove_const_t<const volatile int>` evaluates to
12
  `volatile int`, whereas `remove_const_t<const int*>` evaluates to
13
  `const int*`. — *end example*]
14
 
15
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
16
 
17
- [*Note 1*: This rule reflects the semantics of reference collapsing (
18
- [[dcl.ref]]). — *end note*]
19
 
20
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
21
 
22
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
23
 
@@ -51,16 +51,15 @@ assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
51
 
52
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
53
 
54
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
55
 
56
- [*Note 1*: This behavior is similar to the lvalue-to-rvalue (
57
- [[conv.lval]]), array-to-pointer ([[conv.array]]), and
58
- function-to-pointer ([[conv.func]]) conversions applied when an lvalue
59
- expression is used as an rvalue, but also strips cv-qualifiers from
60
- class types in order to more closely model by-value argument
61
- passing. — *end note*]
62
 
63
  [*Note 2*:
64
 
65
  A typical implementation would define `aligned_storage` as:
66
 
@@ -73,16 +72,51 @@ struct aligned_storage {
73
  };
74
  ```
75
 
76
  — *end note*]
77
 
78
- It is *implementation-defined* whether any extended alignment is
79
- supported ([[basic.align]]).
 
 
80
 
81
- Note A: For the `common_type` trait applied to a parameter pack `T` of
82
- types, the member `type` shall be either defined or not present as
83
- follows:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  - If `sizeof...(T)` is zero, there shall be no member `type`.
86
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
87
  the pack `T`. The member *typedef-name* `type` shall denote the same
88
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
@@ -91,17 +125,22 @@ follows:
91
  `T` be denoted by `T1` and `T2`, respectively, and let `D1` and `D2`
92
  denote the same types as `decay_t<T1>` and `decay_t<T2>`,
93
  respectively.
94
  - If `is_same_v<T1, D1>` is `false` or `is_same_v<T2, D2>` is `false`,
95
  let `C` denote the same type, if any, as `common_type_t<D1, D2>`.
96
- - Otherwise, let `C` denote the same type, if any, as
 
 
97
  ``` cpp
98
  decay_t<decltype(false ? declval<D1>() : declval<D2>())>
99
  ```
100
 
101
- \[*Note 3*: This will not apply if there is a specialization
102
- `common_type<D1, D2>`. — *end note*]
 
 
 
103
 
104
  In either case, the member *typedef-name* `type` shall denote the same
105
  type, if any, as `C`. Otherwise, there shall be no member `type`.
106
  - If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`,
107
  respectively, denote the first, second, and (pack of) remaining types
@@ -125,11 +164,59 @@ unambiguous cv-unqualified non-reference type `C` to which each of the
125
  types `T1` and `T2` is explicitly convertible. Moreover,
126
  `common_type_t<T1, T2>` shall denote the same type, if any, as does
127
  `common_type_t<T2, T1>`. No diagnostic is required for a violation of
128
  this Note’s rules.
129
 
130
- [*Example 1*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  Given these definitions:
133
 
134
  ``` cpp
135
  using PF1 = bool (&)();
 
2
 
3
  This subclause contains templates that may be used to transform one type
4
  to another following some predefined rule.
5
 
6
  Each of the templates in this subclause shall be a
7
+ *Cpp17TransformationTrait* [[meta.rqmts]].
8
 
9
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
10
 
11
  [*Example 1*: `remove_const_t<const volatile int>` evaluates to
12
  `volatile int`, whereas `remove_const_t<const int*>` evaluates to
13
  `const int*`. — *end example*]
14
 
15
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
16
 
17
+ [*Note 1*: This rule reflects the semantics of reference collapsing
18
+ [[dcl.ref]]. — *end note*]
19
 
20
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
21
 
22
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
23
 
 
51
 
52
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
53
 
54
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
55
 
56
+ [*Note 1*: This behavior is similar to the lvalue-to-rvalue
57
+ [[conv.lval]], array-to-pointer [[conv.array]], and function-to-pointer
58
+ [[conv.func]] conversions applied when an lvalue is used as an rvalue,
59
+ but also strips cv-qualifiers from class types in order to more closely
60
+ model by-value argument passing. — *end note*]
 
61
 
62
  [*Note 2*:
63
 
64
  A typical implementation would define `aligned_storage` as:
65
 
 
72
  };
73
  ```
74
 
75
  — *end note*]
76
 
77
+ In addition to being available via inclusion of the `<type_traits>`
78
+ header, the templates `unwrap_reference`, `unwrap_ref_decay`,
79
+ `unwrap_reference_t`, and `unwrap_ref_decay_t` are available when the
80
+ header `<functional>` [[functional.syn]] is included.
81
 
82
+ Let:
83
+
84
+ - `CREF(A)` be `add_lvalue_reference_t<const remove_reference_t<A>{}>`,
85
+ - `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes
86
+ the same type as `U` with the addition of `A`’s cv and reference
87
+ qualifiers, for a non-reference cv-unqualified type `U`,
88
+ - `COPYCV(FROM, TO)` be an alias for type `TO` with the addition of
89
+ `FROM`’s top-level cv-qualifiers,
90
+ \[*Example 1*: `COPYCV(const int, volatile short)` is an alias for
91
+ `const volatile short`. — *end example*]
92
+ - `COND-RES(X, Y)` be
93
+ `decltype(false ? declval<X(&)()>()() : declval<Y(&)()>()())`.
94
+
95
+ Given types `A` and `B`, let `X` be `remove_reference_t<A>`, let `Y` be
96
+ `remove_reference_t<B>`, and let `COMMON-{REF}(A, B)` be:
97
+
98
+ - If `A` and `B` are both lvalue reference types, `COMMON-REF(A, B)` is
99
+ `COND-RES(COPYCV(X, Y) &,
100
+ COPYCV({}Y, X) &)` if that type exists and is a reference type.
101
+ - Otherwise, let `C` be `remove_reference_t<COMMON-REF(X&, Y&)>&&`. If
102
+ `A` and `B` are both rvalue reference types, `C` is well-formed, and
103
+ `is_convertible_v<A, C> && is_convertible_v<B, C>` is `true`, then
104
+ `COMMON-REF(A, B)` is `C`.
105
+ - Otherwise, let `D` be `COMMON-REF(const X&, Y&)`. If `A` is an rvalue
106
+ reference and `B` is an lvalue reference and `D` is well-formed and
107
+ `is_convertible_v<A, D>` is `true`, then `COMMON-REF(A, B)` is `D`.
108
+ - Otherwise, if `A` is an lvalue reference and `B` is an rvalue
109
+ reference, then `COMMON-REF(A, B)` is `COMMON-REF(B, A)`.
110
+ - Otherwise, `COMMON-REF(A, B)` is ill-formed.
111
+
112
+ If any of the types computed above is ill-formed, then
113
+ `COMMON-REF(A, B)` is ill-formed.
114
+
115
+ Note A: For the `common_type` trait applied to a template parameter pack
116
+ `T` of types, the member `type` shall be either defined or not present
117
+ as follows:
118
 
119
  - If `sizeof...(T)` is zero, there shall be no member `type`.
120
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
121
  the pack `T`. The member *typedef-name* `type` shall denote the same
122
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
 
125
  `T` be denoted by `T1` and `T2`, respectively, and let `D1` and `D2`
126
  denote the same types as `decay_t<T1>` and `decay_t<T2>`,
127
  respectively.
128
  - If `is_same_v<T1, D1>` is `false` or `is_same_v<T2, D2>` is `false`,
129
  let `C` denote the same type, if any, as `common_type_t<D1, D2>`.
130
+ - \[*Note 3*: None of the following will apply if there is a
131
+ specialization `common_type<D1, D2>`. — *end note*]
132
+ - Otherwise, if
133
  ``` cpp
134
  decay_t<decltype(false ? declval<D1>() : declval<D2>())>
135
  ```
136
 
137
+ denotes a valid type, let `C` denote that type.
138
+ - Otherwise, if `COND-RES(CREF(D1),
139
+ CREF(D2))` denotes a type, let `C` denote the type
140
+ `decay_t<COND-RES(CREF(D1),
141
+ CREF(D2))>`.
142
 
143
  In either case, the member *typedef-name* `type` shall denote the same
144
  type, if any, as `C`. Otherwise, there shall be no member `type`.
145
  - If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`,
146
  respectively, denote the first, second, and (pack of) remaining types
 
164
  types `T1` and `T2` is explicitly convertible. Moreover,
165
  `common_type_t<T1, T2>` shall denote the same type, if any, as does
166
  `common_type_t<T2, T1>`. No diagnostic is required for a violation of
167
  this Note’s rules.
168
 
169
+ Note C: For the `common_reference` trait applied to a parameter pack `T`
170
+ of types, the member `type` shall be either defined or not present as
171
+ follows:
172
+
173
+ - If `sizeof...(T)` is zero, there shall be no member `type`.
174
+ - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
175
+ the pack `T`. The member typedef `type` shall denote the same type as
176
+ `T0`.
177
+ - Otherwise, if `sizeof...(T)` is two, let `T1` and `T2` denote the two
178
+ types in the pack `T`. Then
179
+ - If `T1` and `T2` are reference types and `COMMON-REF(T1, T2)` is
180
+ well-formed, then the member typedef `type` denotes that type.
181
+ - Otherwise, if
182
+ `basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
183
+ {}XREF({}T1), XREF(T2)>::type` is well-formed, then the member
184
+ typedef `type` denotes that type.
185
+ - Otherwise, if `COND-RES(T1, T2)` is well-formed, then the member
186
+ typedef `type` denotes that type.
187
+ - Otherwise, if `common_type_t<T1, T2>` is well-formed, then the
188
+ member typedef `type` denotes that type.
189
+ - Otherwise, there shall be no member `type`.
190
+ - Otherwise, if `sizeof...(T)` is greater than two, let `T1`, `T2`, and
191
+ `Rest`, respectively, denote the first, second, and (pack of)
192
+ remaining types comprising `T`. Let `C` be the type
193
+ `common_reference_t<T1, T2>`. Then:
194
+ - If there is such a type `C`, the member typedef `type` shall denote
195
+ the same type, if any, as `common_reference_t<C, Rest...>`.
196
+ - Otherwise, there shall be no member `type`.
197
+
198
+ Note D: Notwithstanding the provisions of [[meta.type.synop]], and
199
+ pursuant to [[namespace.std]], a program may partially specialize
200
+ `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
201
+ that `is_same_v<T, decay_t<T>{>}` and `is_same_v<U, decay_t<U>{>}` are
202
+ each `true`.
203
+
204
+ [*Note 5*: Such specializations can be used to influence the result of
205
+ `common_reference`, and are needed when only explicit conversions are
206
+ desired between the template arguments. — *end note*]
207
+
208
+ Such a specialization need not have a member named `type`, but if it
209
+ does, that member shall be a *typedef-name* for an accessible and
210
+ unambiguous type `C` to which each of the types `TQual<T>` and
211
+ `UQual<U>` is convertible. Moreover,
212
+ `basic_common_reference<T, U, TQual, UQual>::type` shall denote the same
213
+ type, if any, as does
214
+ `basic_common_reference<U, T, UQual, TQual>::type`. No diagnostic is
215
+ required for a violation of these rules.
216
+
217
+ [*Example 2*:
218
 
219
  Given these definitions:
220
 
221
  ``` cpp
222
  using PF1 = bool (&)();