From Jason Turner

[meta.reflection.access.context]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpbaze85t3/{from.md → to.md} +172 -0
tmp/tmpbaze85t3/{from.md → to.md} RENAMED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Access control context <a id="meta.reflection.access.context">[[meta.reflection.access.context]]</a>
2
+
3
+ The `access_context` class is a non-aggregate type that represents a
4
+ namespace, class, or function from which queries pertaining to access
5
+ rules may be performed, as well as the designating class
6
+ [[class.access.base]], if any.
7
+
8
+ An `access_context` has an associated scope and designating class.
9
+
10
+ ``` cpp
11
+ namespace std::meta {
12
+ struct access_context {
13
+ access_context() = delete;
14
+
15
+ consteval info scope() const;
16
+ consteval info designating_class() const;
17
+
18
+ static consteval access_context current() noexcept;
19
+ static consteval access_context unprivileged() noexcept;
20
+ static consteval access_context unchecked() noexcept;
21
+ consteval access_context via(info cls) const;
22
+ };
23
+ }
24
+ ```
25
+
26
+ `access_context` is a structural type. Two values `ac1` and `ac2` of
27
+ type `access_context` are template-argument-equivalent [[temp.type]] if
28
+ `ac1.scope()` and `ac2.scope()` are template-argument-equivalent and
29
+ `ac1.designating_class()` and `ac2.designating_class()` are
30
+ template-argument-equivalent.
31
+
32
+ ``` cpp
33
+ consteval info scope() const;
34
+ consteval info designating_class() const;
35
+ ```
36
+
37
+ *Returns:* The `access_context`’s associated scope and designating
38
+ class, respectively.
39
+
40
+ ``` cpp
41
+ static consteval access_context current() noexcept;
42
+ ```
43
+
44
+ Given a program point P, let *`eval-point`*`(`P`)` be the following
45
+ program point:
46
+
47
+ - If a potentially-evaluated subexpression [[intro.execution]] of a
48
+ default member initializer I for a member of class
49
+ C[[class.mem.general]] appears at P, then a point determined as
50
+ follows:
51
+ - If an aggregate initialization is using I, *`eval-point`*`(`Q`)`,
52
+ where Q is the point at which that aggregate initialization appears.
53
+ - Otherwise, if an initialization by an inherited
54
+ constructor [[class.inhctor.init]] is using I, a point whose
55
+ immediate scope is the class scope corresponding to C.
56
+ - Otherwise, a point whose immediate scope is the function parameter
57
+ scope corresponding to the constructor definition that is using I.
58
+ - Otherwise, if a potentially-evaluated subexpression of a default
59
+ argument [[dcl.fct.default]] appears at P, *`eval-point`*`(`Q`)`,
60
+ where Q is the point at which the invocation of the
61
+ function [[expr.call]] using that default argument appears.
62
+ - Otherwise, if the immediate scope of P is a function parameter scope
63
+ introduced by a declaration D, and P appears either before the locus
64
+ of D or within the trailing *requires-clause* of D, a point whose
65
+ immediate scope is the innermost scope enclosing the locus of D that
66
+ is not a template parameter scope.
67
+ - Otherwise, if the immediate scope of P is a function parameter scope
68
+ introduced by a *lambda-expression* L whose *lambda-introducer*
69
+ appears at point Q, and P appears either within the
70
+ *trailing-return-type* or the trailing *requires-clause* of L,
71
+ *`eval-point`*`(`Q`)`.
72
+ - Otherwise, if the innermost non-block scope enclosing P is the
73
+ function parameter scope introduced by a
74
+ *consteval-block-declaration*[[dcl.pre]], a point whose immediate
75
+ scope is that inhabited by the outermost *consteval-block-declaration*
76
+ D containing P such that each scope (if any) that intervenes between P
77
+ and the function parameter scope introduced by D is either
78
+ - a block scope or
79
+ - a function parameter scope or lambda scope introduced by a
80
+ *consteval-block-declaration*.
81
+ - Otherwise, P.
82
+
83
+ Given a scope S, let *`ctx-scope`*`(`S`)` be the following scope:
84
+
85
+ - If S is a class scope or namespace scope, S.
86
+ - Otherwise, if S is a function parameter scope introduced by the
87
+ declaration of a function, S.
88
+ - Otherwise, if S is a lambda scope introduced by a *lambda-expression*
89
+ L, the function parameter scope corresponding to the call operator of
90
+ the closure type of L.
91
+ - Otherwise, *`ctx-scope`*`(`S'`)`, where S' is the parent scope of S.
92
+
93
+ *Returns:* An `access_context` whose designating class is the null
94
+ reflection and whose scope represents the function, class, or namespace
95
+ whose corresponding function parameter scope, class scope, or namespace
96
+ scope, respectively, is *`ctx-scope`*`(`S`)`, where S is the immediate
97
+ scope of *`eval-point`*`(`P`)` and P is the point at which the
98
+ invocation of `current` lexically appears.
99
+
100
+ *Remarks:* `current` is not an addressable function [[namespace.std]].
101
+ An invocation of `current` that appears at a program point P is
102
+ value-dependent [[temp.dep.constexpr]] if *`eval-point`*`(`P`)` is
103
+ enclosed by a scope corresponding to a templated entity.
104
+
105
+ [*Example 1*:
106
+
107
+ ``` cpp
108
+ struct A {
109
+ int a = 0;
110
+ consteval A(int p) : a(p) {}
111
+ };
112
+ struct B : A {
113
+ using A::A;
114
+ consteval B(int p, int q) : A(p * q) {}
115
+ info s = access_context::current().scope();
116
+ };
117
+ struct C : B { using B::B; };
118
+
119
+ struct Agg {
120
+ consteval bool eq(info rhs = access_context::current().scope()) {
121
+ return s == rhs;
122
+ }
123
+ info s = access_context::current().scope();
124
+ };
125
+
126
+ namespace NS {
127
+ static_assert(Agg{}.s == access_context::current().scope()); // OK
128
+ static_assert(Agg{}.eq()); // OK
129
+ static_assert(B(1).s == ^^B); // OK
130
+ static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OK
131
+ static_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OK
132
+
133
+ auto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:];
134
+ static_assert(type_of(^^fn) == ^^auto()->int); // OK
135
+
136
+ template<auto R>
137
+ struct TCls {
138
+ consteval bool fn()
139
+ requires (is_type(access_context::current().scope())) {
140
+ return true; // OK, scope is TCls<R>.
141
+ }
142
+ };
143
+ static_assert(TCls<0>{}.fn()); // OK
144
+ }
145
+ ```
146
+
147
+ — *end example*]
148
+
149
+ ``` cpp
150
+ static consteval access_context unprivileged() noexcept;
151
+ ```
152
+
153
+ *Returns:* An `access_context` whose designating class is the null
154
+ reflection and whose scope is the global namespace.
155
+
156
+ ``` cpp
157
+ static consteval access_context unchecked() noexcept;
158
+ ```
159
+
160
+ *Returns:* An `access_context` whose designating class and scope are
161
+ both the null reflection.
162
+
163
+ ``` cpp
164
+ consteval access_context via(info cls) const;
165
+ ```
166
+
167
+ *Returns:* An `access_context` whose scope is `this->scope()` and whose
168
+ designating class is `cls`.
169
+
170
+ *Throws:* `meta::exception` unless `cls` is either the null reflection
171
+ or a reflection of a complete class type.
172
+