From Jason Turner

[meta.trans.other]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpe2a9d8cd/{from.md → to.md} +102 -15
tmp/tmpe2a9d8cd/{from.md → to.md} RENAMED
@@ -1,13 +1,12 @@
1
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
2
 
3
- [*Note 1*: This behavior is similar to the lvalue-to-rvalue (
4
- [[conv.lval]]), array-to-pointer ([[conv.array]]), and
5
- function-to-pointer ([[conv.func]]) conversions applied when an lvalue
6
- expression is used as an rvalue, but also strips cv-qualifiers from
7
- class types in order to more closely model by-value argument
8
- passing. — *end note*]
9
 
10
  [*Note 2*:
11
 
12
  A typical implementation would define `aligned_storage` as:
13
 
@@ -20,16 +19,51 @@ struct aligned_storage {
20
  };
21
  ```
22
 
23
  — *end note*]
24
 
25
- It is *implementation-defined* whether any extended alignment is
26
- supported ([[basic.align]]).
 
 
27
 
28
- Note A: For the `common_type` trait applied to a parameter pack `T` of
29
- types, the member `type` shall be either defined or not present as
30
- follows:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  - If `sizeof...(T)` is zero, there shall be no member `type`.
33
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
34
  the pack `T`. The member *typedef-name* `type` shall denote the same
35
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
@@ -38,17 +72,22 @@ follows:
38
  `T` be denoted by `T1` and `T2`, respectively, and let `D1` and `D2`
39
  denote the same types as `decay_t<T1>` and `decay_t<T2>`,
40
  respectively.
41
  - If `is_same_v<T1, D1>` is `false` or `is_same_v<T2, D2>` is `false`,
42
  let `C` denote the same type, if any, as `common_type_t<D1, D2>`.
43
- - Otherwise, let `C` denote the same type, if any, as
 
 
44
  ``` cpp
45
  decay_t<decltype(false ? declval<D1>() : declval<D2>())>
46
  ```
47
 
48
- \[*Note 3*: This will not apply if there is a specialization
49
- `common_type<D1, D2>`. — *end note*]
 
 
 
50
 
51
  In either case, the member *typedef-name* `type` shall denote the same
52
  type, if any, as `C`. Otherwise, there shall be no member `type`.
53
  - If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`,
54
  respectively, denote the first, second, and (pack of) remaining types
@@ -72,11 +111,59 @@ unambiguous cv-unqualified non-reference type `C` to which each of the
72
  types `T1` and `T2` is explicitly convertible. Moreover,
73
  `common_type_t<T1, T2>` shall denote the same type, if any, as does
74
  `common_type_t<T2, T1>`. No diagnostic is required for a violation of
75
  this Note’s rules.
76
 
77
- [*Example 1*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  Given these definitions:
80
 
81
  ``` cpp
82
  using PF1 = bool (&)();
 
1
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
2
 
3
+ [*Note 1*: This behavior is similar to the lvalue-to-rvalue
4
+ [[conv.lval]], array-to-pointer [[conv.array]], and function-to-pointer
5
+ [[conv.func]] conversions applied when an lvalue is used as an rvalue,
6
+ but also strips cv-qualifiers from class types in order to more closely
7
+ model by-value argument passing. — *end note*]
 
8
 
9
  [*Note 2*:
10
 
11
  A typical implementation would define `aligned_storage` as:
12
 
 
19
  };
20
  ```
21
 
22
  — *end note*]
23
 
24
+ In addition to being available via inclusion of the `<type_traits>`
25
+ header, the templates `unwrap_reference`, `unwrap_ref_decay`,
26
+ `unwrap_reference_t`, and `unwrap_ref_decay_t` are available when the
27
+ header `<functional>` [[functional.syn]] is included.
28
 
29
+ Let:
30
+
31
+ - `CREF(A)` be `add_lvalue_reference_t<const remove_reference_t<A>{}>`,
32
+ - `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes
33
+ the same type as `U` with the addition of `A`’s cv and reference
34
+ qualifiers, for a non-reference cv-unqualified type `U`,
35
+ - `COPYCV(FROM, TO)` be an alias for type `TO` with the addition of
36
+ `FROM`’s top-level cv-qualifiers,
37
+ \[*Example 1*: `COPYCV(const int, volatile short)` is an alias for
38
+ `const volatile short`. — *end example*]
39
+ - `COND-RES(X, Y)` be
40
+ `decltype(false ? declval<X(&)()>()() : declval<Y(&)()>()())`.
41
+
42
+ Given types `A` and `B`, let `X` be `remove_reference_t<A>`, let `Y` be
43
+ `remove_reference_t<B>`, and let `COMMON-{REF}(A, B)` be:
44
+
45
+ - If `A` and `B` are both lvalue reference types, `COMMON-REF(A, B)` is
46
+ `COND-RES(COPYCV(X, Y) &,
47
+ COPYCV({}Y, X) &)` if that type exists and is a reference type.
48
+ - Otherwise, let `C` be `remove_reference_t<COMMON-REF(X&, Y&)>&&`. If
49
+ `A` and `B` are both rvalue reference types, `C` is well-formed, and
50
+ `is_convertible_v<A, C> && is_convertible_v<B, C>` is `true`, then
51
+ `COMMON-REF(A, B)` is `C`.
52
+ - Otherwise, let `D` be `COMMON-REF(const X&, Y&)`. If `A` is an rvalue
53
+ reference and `B` is an lvalue reference and `D` is well-formed and
54
+ `is_convertible_v<A, D>` is `true`, then `COMMON-REF(A, B)` is `D`.
55
+ - Otherwise, if `A` is an lvalue reference and `B` is an rvalue
56
+ reference, then `COMMON-REF(A, B)` is `COMMON-REF(B, A)`.
57
+ - Otherwise, `COMMON-REF(A, B)` is ill-formed.
58
+
59
+ If any of the types computed above is ill-formed, then
60
+ `COMMON-REF(A, B)` is ill-formed.
61
+
62
+ Note A: For the `common_type` trait applied to a template parameter pack
63
+ `T` of types, the member `type` shall be either defined or not present
64
+ as follows:
65
 
66
  - If `sizeof...(T)` is zero, there shall be no member `type`.
67
  - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
68
  the pack `T`. The member *typedef-name* `type` shall denote the same
69
  type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
 
72
  `T` be denoted by `T1` and `T2`, respectively, and let `D1` and `D2`
73
  denote the same types as `decay_t<T1>` and `decay_t<T2>`,
74
  respectively.
75
  - If `is_same_v<T1, D1>` is `false` or `is_same_v<T2, D2>` is `false`,
76
  let `C` denote the same type, if any, as `common_type_t<D1, D2>`.
77
+ - \[*Note 3*: None of the following will apply if there is a
78
+ specialization `common_type<D1, D2>`. — *end note*]
79
+ - Otherwise, if
80
  ``` cpp
81
  decay_t<decltype(false ? declval<D1>() : declval<D2>())>
82
  ```
83
 
84
+ denotes a valid type, let `C` denote that type.
85
+ - Otherwise, if `COND-RES(CREF(D1),
86
+ CREF(D2))` denotes a type, let `C` denote the type
87
+ `decay_t<COND-RES(CREF(D1),
88
+ CREF(D2))>`.
89
 
90
  In either case, the member *typedef-name* `type` shall denote the same
91
  type, if any, as `C`. Otherwise, there shall be no member `type`.
92
  - If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`,
93
  respectively, denote the first, second, and (pack of) remaining types
 
111
  types `T1` and `T2` is explicitly convertible. Moreover,
112
  `common_type_t<T1, T2>` shall denote the same type, if any, as does
113
  `common_type_t<T2, T1>`. No diagnostic is required for a violation of
114
  this Note’s rules.
115
 
116
+ Note C: For the `common_reference` trait applied to a parameter pack `T`
117
+ of types, the member `type` shall be either defined or not present as
118
+ follows:
119
+
120
+ - If `sizeof...(T)` is zero, there shall be no member `type`.
121
+ - Otherwise, if `sizeof...(T)` is one, let `T0` denote the sole type in
122
+ the pack `T`. The member typedef `type` shall denote the same type as
123
+ `T0`.
124
+ - Otherwise, if `sizeof...(T)` is two, let `T1` and `T2` denote the two
125
+ types in the pack `T`. Then
126
+ - If `T1` and `T2` are reference types and `COMMON-REF(T1, T2)` is
127
+ well-formed, then the member typedef `type` denotes that type.
128
+ - Otherwise, if
129
+ `basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
130
+ {}XREF({}T1), XREF(T2)>::type` is well-formed, then the member
131
+ typedef `type` denotes that type.
132
+ - Otherwise, if `COND-RES(T1, T2)` is well-formed, then the member
133
+ typedef `type` denotes that type.
134
+ - Otherwise, if `common_type_t<T1, T2>` is well-formed, then the
135
+ member typedef `type` denotes that type.
136
+ - Otherwise, there shall be no member `type`.
137
+ - Otherwise, if `sizeof...(T)` is greater than two, let `T1`, `T2`, and
138
+ `Rest`, respectively, denote the first, second, and (pack of)
139
+ remaining types comprising `T`. Let `C` be the type
140
+ `common_reference_t<T1, T2>`. Then:
141
+ - If there is such a type `C`, the member typedef `type` shall denote
142
+ the same type, if any, as `common_reference_t<C, Rest...>`.
143
+ - Otherwise, there shall be no member `type`.
144
+
145
+ Note D: Notwithstanding the provisions of [[meta.type.synop]], and
146
+ pursuant to [[namespace.std]], a program may partially specialize
147
+ `basic_common_reference<T, U, TQual, UQual>` for types `T` and `U` such
148
+ that `is_same_v<T, decay_t<T>{>}` and `is_same_v<U, decay_t<U>{>}` are
149
+ each `true`.
150
+
151
+ [*Note 5*: Such specializations can be used to influence the result of
152
+ `common_reference`, and are needed when only explicit conversions are
153
+ desired between the template arguments. — *end note*]
154
+
155
+ Such a specialization need not have a member named `type`, but if it
156
+ does, that member shall be a *typedef-name* for an accessible and
157
+ unambiguous type `C` to which each of the types `TQual<T>` and
158
+ `UQual<U>` is convertible. Moreover,
159
+ `basic_common_reference<T, U, TQual, UQual>::type` shall denote the same
160
+ type, if any, as does
161
+ `basic_common_reference<U, T, UQual, TQual>::type`. No diagnostic is
162
+ required for a violation of these rules.
163
+
164
+ [*Example 2*:
165
 
166
  Given these definitions:
167
 
168
  ``` cpp
169
  using PF1 = bool (&)();