From Jason Turner

[expr.reflect]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpcxr7frc9/{from.md → to.md} +172 -0
tmp/tmpcxr7frc9/{from.md → to.md} RENAMED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### The reflection operator <a id="expr.reflect">[[expr.reflect]]</a>
2
+
3
+ ``` bnf
4
+ reflect-expression:
5
+ '^^' '::'
6
+ '^^' reflection-name
7
+ '^^' type-id
8
+ '^^' id-expression
9
+ ```
10
+
11
+ ``` bnf
12
+ reflection-name:
13
+ nested-name-specifierₒₚₜ identifier
14
+ nested-name-specifier template identifier
15
+ ```
16
+
17
+ The unary `^^` operator, called the *reflection operator*, yields a
18
+ prvalue of type `std::meta::info` [[basic.fundamental]].
19
+
20
+ [*Note 1*: This document places no restriction on representing, by
21
+ reflections, constructs not described by this document or using the
22
+ names of such constructs as operands of
23
+ *reflect-expression*s. — *end note*]
24
+
25
+ The component names of a *reflection-name* are those of its
26
+ *nested-name-specifier* (if any) and its *identifier*. The terminal name
27
+ of a *reflection-name* of the form *nested-name-specifier* `template`
28
+ *identifier* shall denote a template.
29
+
30
+ A *reflect-expression* is parsed as the longest possible sequence of
31
+ tokens that could syntactically form a *reflect-expression*. An
32
+ unparenthesized *reflect-expression* that represents a template shall
33
+ not be followed by `<`.
34
+
35
+ [*Example 1*:
36
+
37
+ ``` cpp
38
+ static_assert(std::meta::is_type(^^int())); // ^^ applies to the type-id int()
39
+
40
+ template<bool> struct X {};
41
+ consteval bool operator<(std::meta::info, X<false>) { return false; }
42
+ consteval void g(std::meta::info r, X<false> xv) {
43
+ r == ^^int && true; // error: ^^ applies to the type-id int&&
44
+ r == ^^int & true; // error: ^^ applies to the type-id int&
45
+ r == (^^int) && true; // OK
46
+ r == ^^int &&&& true; // error: int &&&& is not a valid type-id
47
+ ^^X < xv; // error: reflect-expression that represents a template is followed by <
48
+ (^^X) < xv; // OK
49
+ ^^X<true> < xv; // OK
50
+ }
51
+ ```
52
+
53
+ — *end example*]
54
+
55
+ A *reflect-expression* of the form `^^ ::` represents the global
56
+ namespace.
57
+
58
+ If a *reflect-expression* R matches the form `^^ reflection-name`, it is
59
+ interpreted as such; the *identifier* is looked up and the
60
+ representation of R is determined as follows:
61
+
62
+ - If lookup finds a declaration that replaced a *using-declarator*
63
+ during a single search [[basic.lookup.general]], [[namespace.udecl]],
64
+ R is ill-formed.
65
+ \[*Example 2*:
66
+ ``` cpp
67
+ struct A { struct S {}; };
68
+ struct B : A { using A::S; };
69
+ constexpr std::meta::info r1 = ^^B::S; // error: A::S found through using-declarator
70
+
71
+ struct C : virtual B { struct S {}; };
72
+ struct D : virtual B, C {};
73
+ D::S s; // OK, names C::S per [class.member.lookup]
74
+ constexpr std::meta::info r2 = ^^D::S; // OK, result C::S not found through using-declarator
75
+ ```
76
+
77
+ — *end example*]
78
+ - Otherwise, if lookup finds a namespace alias [[namespace.alias]], R
79
+ represents that namespace alias.
80
+ - Otherwise, if lookup finds a namespace [[basic.namespace]], R
81
+ represents that namespace.
82
+ - Otherwise, if lookup finds a concept [[temp.concept]], R represents
83
+ the denoted concept.
84
+ - Otherwise, if lookup finds a template [[temp.names]], the
85
+ representation of R is determined as follows:
86
+ - If lookup finds an injected-class-name [[class.pre]], then:
87
+ - If the *reflection-name* is of the form
88
+ `nested-name-specifier template identifier`, then R represents the
89
+ class template named by the injected-class-name.
90
+ - Otherwise, the injected-class-name shall be unambiguous when
91
+ considered as a *type-name* and R represents the class template
92
+ specialization so named.
93
+ - Otherwise, if lookup finds an overload set, that overload set shall
94
+ contain only declarations of a unique function template F; R
95
+ represents F.
96
+ - Otherwise, if lookup finds a class template, variable template, or
97
+ alias template, R represents that template. \[*Note 2*: Lookup never
98
+ finds a partial or explicit specialization. — *end note*]
99
+ - Otherwise, if lookup finds a type alias A, R represents the underlying
100
+ entity of A if A was introduced by the declaration of a template
101
+ parameter; otherwise, R represents A.
102
+ - Otherwise, if lookup finds a class or an enumeration, R represents the
103
+ denoted type.
104
+ - Otherwise, if lookup finds a class member of an anonymous union
105
+ [[class.union.anon]], R represents that class member.
106
+ - Otherwise, the *reflection-name* shall be an *id-expression* `I` and R
107
+ is `^^ I` (see below).
108
+
109
+ A *reflect-expression* R of the form `^^ type-id` represents an entity
110
+ determined as follows:
111
+
112
+ - If the *type-id* designates a placeholder type
113
+ [[dcl.spec.auto.general]], R is ill-formed.
114
+ - Otherwise, if the *type-id* names a type alias that is a
115
+ specialization of an alias template [[temp.alias]], R represents that
116
+ type alias.
117
+ - Otherwise, R represents the type denoted by the *type-id*.
118
+
119
+ A *reflect-expression* R of the form `^^ id-expression` represents an
120
+ entity determined as follows:
121
+
122
+ - If the *id-expression* denotes
123
+ - a variable declared by an *init-capture*
124
+ [[expr.prim.lambda.capture]],
125
+ - a function-local predefined variable [[dcl.fct.def.general]],
126
+ - a local parameter introduced by a *requires-expression*
127
+ [[expr.prim.req]], or
128
+ - a local entity E [[basic.pre]] for which a lambda scope intervenes
129
+ between the point at which E was introduced and R,
130
+
131
+ then R is ill-formed.
132
+ - Otherwise, if the *id-expression* denotes an overload set S, overload
133
+ resolution for the expression `&S` with no target shall select a
134
+ unique function [[over.over]]; R represents that function.
135
+ - Otherwise, if the *id-expression* denotes a variable, structured
136
+ binding, enumerator, or non-static data member, R represents that
137
+ entity.
138
+ - Otherwise, R is ill-formed. \[*Note 3*: This includes
139
+ *unqualified-id*s that name a constant template parameter and
140
+ *pack-index-expression*s. — *end note*]
141
+
142
+ The *id-expression* of a *reflect-expression* is an unevaluated operand
143
+ [[expr.context]].
144
+
145
+ [*Example 3*:
146
+
147
+ ``` cpp
148
+ template<typename T> void fn() requires (^^T != ^^int);
149
+ template<typename T> void fn() requires (^^T == ^^int);
150
+ template<typename T> void fn() requires (sizeof(T) == sizeof(int));
151
+
152
+ constexpr std::meta::info a = ^^fn<char>; // OK
153
+ constexpr std::meta::info b = ^^fn<int>; // error: ambiguous
154
+
155
+ constexpr std::meta::info c = ^^std::vector; // OK
156
+
157
+ template<typename T>
158
+ struct S {
159
+ static constexpr std::meta::info r = ^^T;
160
+ using type = T;
161
+ };
162
+ static_assert(S<int>::r == ^^int);
163
+ static_assert(^^S<int>::type != ^^int);
164
+
165
+ typedef struct X {} Y;
166
+ typedef struct Z {} Z;
167
+ constexpr std::meta::info e = ^^Y; // OK, represents the type alias Y
168
+ constexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type[basic.lookup.general]
169
+ ```
170
+
171
+ — *end example*]
172
+