Files
2025-10-25 03:02:53 +03:00

10 KiB
Raw Permalink Blame History

[meta.reflection.access.context]

21 Metaprogramming library [meta]

21.4 Reflection [meta.reflection]

21.4.8 Access control context [meta.reflection.access.context]

1

#

The access_context class is a non-aggregate type that represents a namespace, class, or function from which queries pertaining to access rules may be performed, as well as the designating class ([class.access.base]), if any.

2

#

An access_context has an associated scope and designating class.

🔗

namespace std::meta {struct access_context { access_context() = delete; consteval info scope() const; consteval info designating_class() const; static consteval access_context current() noexcept; static consteval access_context unprivileged() noexcept; static consteval access_context unchecked() noexcept; consteval access_context via(info cls) const; };}

3

#

access_context is a structural type.

Two values ac1 and ac2 of type access_context are template-argument-equivalent ([temp.type]) if ac1.scope() and ac2.scope() are template-argument-equivalent and ac1.designating_class() and ac2.designating_class() are template-argument-equivalent.

🔗

consteval info [scope](#lib:access_context,scope "21.4.8Access control context[meta.reflection.access.context]")() const; consteval info [designating_class](#lib:access_context,designating_class "21.4.8Access control context[meta.reflection.access.context]")() const;

4

#

Returns: The access_context's associated scope and designating class, respectively.

🔗

static consteval access_context [current](#lib:access_context,current "21.4.8Access control context[meta.reflection.access.context]")() noexcept;

5

#

Given a program point P, let eval-point(P) be the following program point:

  • (5.1)

    If a potentially-evaluated subexpression ([intro.execution]) of a default member initializer I for a member of class C ([class.mem.general]) appears at P, then a point determined as follows:

    • (5.1.1)

      If an aggregate initialization is using I, eval-point(Q), where Q is the point at which that aggregate initialization appears.

    • (5.1.2)

      Otherwise, if an initialization by an inherited constructor ([class.inhctor.init]) is using I, a point whose immediate scope is the class scope corresponding to C.

    • (5.1.3)

      Otherwise, a point whose immediate scope is the function parameter scope corresponding to the constructor definition that is using I.

  • (5.2)

    Otherwise, if a potentially-evaluated subexpression of a default argument ([dcl.fct.default]) appears at P, eval-point(Q), where Q is the point at which the invocation of the function ([expr.call]) using that default argument appears.

  • (5.3)

    Otherwise, if the immediate scope of P is a function parameter scope introduced by a declaration D, and P appears either before the locus of D or within the trailing requires-clause of D, a point whose immediate scope is the innermost scope enclosing the locus of D that is not a template parameter scope.

  • (5.4)

    Otherwise, if the immediate scope of P is a function parameter scope introduced by a lambda-expression L whose lambda-introducer appears at point Q, and P appears either within the trailing-return-type or the trailing requires-clause of L, eval-point(Q).

  • (5.5)

    Otherwise, if the innermost non-block scope enclosing P is the function parameter scope introduced by a consteval-block-declaration ([dcl.pre]), a point whose immediate scope is that inhabited by the outermost consteval-block-declaration D containing P such that each scope (if any) that intervenes between P and the function parameter scope introduced by D is either

a block scope or

a function parameter scope or lambda scope introduced by a consteval-block-declaration.

6

#

Given a scope S, let ctx-scope(S) be the following scope:

  • (6.1)

    If S is a class scope or namespace scope, S.

  • (6.2)

    Otherwise, if S is a function parameter scope introduced by the declaration of a function, S.

  • (6.3)

    Otherwise, if S is a lambda scope introduced by a lambda-expression L, the function parameter scope corresponding to the call operator of the closure type of L.

  • (6.4)

    Otherwise, ctx-scope(S′), where S′ is the parent scope of S.

7

#

Returns: An access_context whose designating class is the null reflection and whose scope represents the function, class, or namespace whose corresponding function parameter scope, class scope, or namespace scope, respectively, is ctx-scope(S), where S is the immediate scope of eval-point(P) and P is the point at which the invocation of current lexically appears.

[Example 1: struct A {int a = 0; consteval A(int p) : a(p) {}};struct B : A {using A::A; consteval B(int p, int q) : A(p * q) {} info s = access_context::current().scope();};struct C : B { using B::B; };

struct Agg {consteval bool eq(info rhs = access_context::current().scope()) {return s == rhs; } info s = access_context::current().scope();};

namespace NS {static_assert(Agg{}.s == access_context::current().scope()); // OKstatic_assert(Agg{}.eq()); // OKstatic_assert(B(1).s == ^^B); // OKstatic_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OKstatic_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OKauto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:]; static_assert(type_of(^^fn) == ^^auto()->int); // OKtemplatestruct TCls {consteval bool fn()requires (is_type(access_context::current().scope())) {return true; // OK, scope is TCls.}}; static_assert(TCls<0>{}.fn()); // OK} — end example]

8

#

Remarks: current is not an addressable function ([namespace.std]).

An invocation of current that appears at a program point P is value-dependent ([temp.dep.constexpr]) if eval-point(P) is enclosed by a scope corresponding to a templated entity.

🔗

static consteval access_context [unprivileged](#lib:access_context,unprivileged "21.4.8Access control context[meta.reflection.access.context]")() noexcept;

9

#

Returns: An access_context whose designating class is the null reflection and whose scope is the global namespace.

🔗

static consteval access_context [unchecked](#lib:access_context,unchecked "21.4.8Access control context[meta.reflection.access.context]")() noexcept;

10

#

Returns: An access_context whose designating class and scope are both the null reflection.

🔗

static consteval access_context [via](#lib:access_context,via "21.4.8Access control context[meta.reflection.access.context]")(info cls) const;

11

#

Returns: An access_context whose scope is this->scope() and whose designating class is cls.

12

#

Throws: meta::exception unlesscls is either the null reflection or a reflection of a complete class type.