From Jason Turner

[meta.trans.other]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp11u9u45b/{from.md → to.md} +71 -28
tmp/tmp11u9u45b/{from.md → to.md} RENAMED
@@ -1,65 +1,108 @@
1
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
2
 
 
 
 
 
 
 
 
 
 
3
  A typical implementation would define `aligned_storage` as:
4
 
5
  ``` cpp
6
- template <std::size_t Len, std::size_t Alignment>
7
  struct aligned_storage {
8
  typedef struct {
9
  alignas(Alignment) unsigned char __data[Len];
10
  } type;
11
  };
12
  ```
13
 
 
 
14
  It is *implementation-defined* whether any extended alignment is
15
  supported ([[basic.align]]).
16
 
17
- The nested typedef `common_type::type` shall be defined as follows:
 
 
18
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  ``` cpp
20
- template <class ...T> struct common_type;
21
-
22
- template <class T>
23
- struct common_type<T> {
24
- typedef decay_t<T> type;
25
- };
26
-
27
- template <class T, class U>
28
- struct common_type<T, U> {
29
- typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type;
30
- };
31
-
32
- template <class T, class U, class... V>
33
- struct common_type<T, U, V...> {
34
- typedef common_type_t<common_type_t<T, U>, V...> type;
35
- };
36
  ```
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  Given these definitions:
39
 
40
  ``` cpp
41
- typedef bool (&PF1)();
42
- typedef short (*PF2)(long);
43
 
44
  struct S {
45
  operator PF2() const;
46
  double operator()(char, int&);
47
  void fn(long) const;
48
  char data;
49
  };
50
 
51
- typedef void (S::*PMF)(long) const;
52
- typedef char S::*PMD;
53
  ```
54
 
55
  the following assertions will hold:
56
 
57
  ``` cpp
58
- static_assert(is_same<result_of_t<S(int)>, short>::value, "Error!");
59
- static_assert(is_same<result_of_t<S&(unsigned char, int&)>, double>::value, "Error!");
60
- static_assert(is_same<result_of_t<PF1()>, bool>::value, "Error!");
61
- static_assert(is_same<result_of_t<PMF(unique_ptr<S>, int)>, void>::value, "Error!");
62
- static_assert(is_same<result_of_t<PMD(S)>, char&&>::value, "Error!");
63
- static_assert(is_same<result_of_t<PMD(const S*)>, const char&>::value, "Error!");
64
  ```
65
 
 
 
 
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
 
14
  ``` cpp
15
+ template <size_t Len, size_t Alignment>
16
  struct aligned_storage {
17
  typedef struct {
18
  alignas(Alignment) unsigned char __data[Len];
19
  } type;
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
36
+ member `type`.
37
+ - If `sizeof...(T)` is two, let the first and second types constituting
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
55
+ constituting `T`. Let `C` denote the same type, if any, as
56
+ `common_type_t<T1, T2>`. If there is such a type `C`, the member
57
+ *typedef-name* `type` shall denote the same type, if any, as
58
+ `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
59
+
60
+ Note B: Notwithstanding the provisions of [[meta.type.synop]], and
61
+ pursuant to [[namespace.std]], a program may specialize
62
+ `common_type<T1, T2>` for types `T1` and `T2` such that
63
+ `is_same_v<T1, decay_t<T1>>` and `is_same_v<T2, decay_t<T2>>` are each
64
+ `true`.
65
+
66
+ [*Note 4*: Such specializations are needed when only explicit
67
+ conversions are desired between the template arguments. — *end note*]
68
+
69
+ Such a specialization need not have a member named `type`, but if it
70
+ does, that member shall be a *typedef-name* for an accessible and
71
+ 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 (&)();
83
+ using PF2 = short (*)(long);
84
 
85
  struct S {
86
  operator PF2() const;
87
  double operator()(char, int&);
88
  void fn(long) const;
89
  char data;
90
  };
91
 
92
+ using PMF = void (S::*)(long) const;
93
+ using PMD = char S::*;
94
  ```
95
 
96
  the following assertions will hold:
97
 
98
  ``` cpp
99
+ static_assert(is_same_v<invoke_result_t<S, int>, short>);
100
+ static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
101
+ static_assert(is_same_v<invoke_result_t<PF1>, bool>);
102
+ static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
103
+ static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
104
+ static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
105
  ```
106
 
107
+ — *end example*]
108
+