From Jason Turner

[meta.trans]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpty7ex04y/{from.md → to.md} +101 -39
tmp/tmpty7ex04y/{from.md → to.md} RENAMED
@@ -1,99 +1,161 @@
1
  ### Transformations between types <a id="meta.trans">[[meta.trans]]</a>
2
 
3
- This sub-clause contains templates that may be used to transform one
4
- type 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
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
12
 
 
 
 
13
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
14
 
15
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
16
 
 
 
 
 
 
 
17
  ``` cpp
18
  // the following assertions hold:
19
- assert((is_same<remove_extent_t<int>, int>::value));
20
- assert((is_same<remove_extent_t<int[2]>, int>::value));
21
- assert((is_same<remove_extent_t<int[2][3]>, int[3]>::value));
22
- assert((is_same<remove_extent_t<int[][3]>, int[3]>::value));
23
  ```
24
 
 
 
 
 
25
  ``` cpp
26
  // the following assertions hold:
27
- assert((is_same<remove_all_extents_t<int>, int>::value));
28
- assert((is_same<remove_all_extents_t<int[2]>, int>::value));
29
- assert((is_same<remove_all_extents_t<int[2][3]>, int>::value));
30
- assert((is_same<remove_all_extents_t<int[][3]>, int>::value));
31
  ```
32
 
 
 
33
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
34
 
35
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
36
 
 
 
 
 
 
 
 
 
 
37
  A typical implementation would define `aligned_storage` as:
38
 
39
  ``` cpp
40
- template <std::size_t Len, std::size_t Alignment>
41
  struct aligned_storage {
42
  typedef struct {
43
  alignas(Alignment) unsigned char __data[Len];
44
  } type;
45
  };
46
  ```
47
 
 
 
48
  It is *implementation-defined* whether any extended alignment is
49
  supported ([[basic.align]]).
50
 
51
- The nested typedef `common_type::type` shall be defined as follows:
 
 
52
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ``` cpp
54
- template <class ...T> struct common_type;
55
-
56
- template <class T>
57
- struct common_type<T> {
58
- typedef decay_t<T> type;
59
- };
60
-
61
- template <class T, class U>
62
- struct common_type<T, U> {
63
- typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type;
64
- };
65
-
66
- template <class T, class U, class... V>
67
- struct common_type<T, U, V...> {
68
- typedef common_type_t<common_type_t<T, U>, V...> type;
69
- };
70
  ```
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  Given these definitions:
73
 
74
  ``` cpp
75
- typedef bool (&PF1)();
76
- typedef short (*PF2)(long);
77
 
78
  struct S {
79
  operator PF2() const;
80
  double operator()(char, int&);
81
  void fn(long) const;
82
  char data;
83
  };
84
 
85
- typedef void (S::*PMF)(long) const;
86
- typedef char S::*PMD;
87
  ```
88
 
89
  the following assertions will hold:
90
 
91
  ``` cpp
92
- static_assert(is_same<result_of_t<S(int)>, short>::value, "Error!");
93
- static_assert(is_same<result_of_t<S&(unsigned char, int&)>, double>::value, "Error!");
94
- static_assert(is_same<result_of_t<PF1()>, bool>::value, "Error!");
95
- static_assert(is_same<result_of_t<PMF(unique_ptr<S>, int)>, void>::value, "Error!");
96
- static_assert(is_same<result_of_t<PMD(S)>, char&&>::value, "Error!");
97
- static_assert(is_same<result_of_t<PMD(const S*)>, const char&>::value, "Error!");
98
  ```
99
 
 
 
 
1
  ### Transformations between types <a id="meta.trans">[[meta.trans]]</a>
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
 
24
+ [*Note 1*: For multidimensional arrays, only the first array dimension
25
+ is removed. For a type “array of `const U`”, the resulting type is
26
+ `const U`. — *end note*]
27
+
28
+ [*Example 1*:
29
+
30
  ``` cpp
31
  // the following assertions hold:
32
+ assert((is_same_v<remove_extent_t<int>, int>));
33
+ assert((is_same_v<remove_extent_t<int[2]>, int>));
34
+ assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
35
+ assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
36
  ```
37
 
38
+ — *end example*]
39
+
40
+ [*Example 2*:
41
+
42
  ``` cpp
43
  // the following assertions hold:
44
+ assert((is_same_v<remove_all_extents_t<int>, int>));
45
+ assert((is_same_v<remove_all_extents_t<int[2]>, int>));
46
+ assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
47
+ assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
48
  ```
49
 
50
+ — *end example*]
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
 
67
  ``` cpp
68
+ template <size_t Len, size_t Alignment>
69
  struct aligned_storage {
70
  typedef struct {
71
  alignas(Alignment) unsigned char __data[Len];
72
  } type;
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
89
+ member `type`.
90
+ - If `sizeof...(T)` is two, let the first and second types constituting
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
108
+ constituting `T`. Let `C` denote the same type, if any, as
109
+ `common_type_t<T1, T2>`. If there is such a type `C`, the member
110
+ *typedef-name* `type` shall denote the same type, if any, as
111
+ `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
112
+
113
+ Note B: Notwithstanding the provisions of [[meta.type.synop]], and
114
+ pursuant to [[namespace.std]], a program may specialize
115
+ `common_type<T1, T2>` for types `T1` and `T2` such that
116
+ `is_same_v<T1, decay_t<T1>>` and `is_same_v<T2, decay_t<T2>>` are each
117
+ `true`.
118
+
119
+ [*Note 4*: Such specializations are needed when only explicit
120
+ conversions are desired between the template arguments. — *end note*]
121
+
122
+ Such a specialization need not have a member named `type`, but if it
123
+ does, that member shall be a *typedef-name* for an accessible and
124
+ 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 (&)();
136
+ using PF2 = short (*)(long);
137
 
138
  struct S {
139
  operator PF2() const;
140
  double operator()(char, int&);
141
  void fn(long) const;
142
  char data;
143
  };
144
 
145
+ using PMF = void (S::*)(long) const;
146
+ using PMD = char S::*;
147
  ```
148
 
149
  the following assertions will hold:
150
 
151
  ``` cpp
152
+ static_assert(is_same_v<invoke_result_t<S, int>, short>);
153
+ static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
154
+ static_assert(is_same_v<invoke_result_t<PF1>, bool>);
155
+ static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
156
+ static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
157
+ static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
158
  ```
159
 
160
+ — *end example*]
161
+