[meta.reflection.access.context]

# 21 Metaprogramming library [[meta]](./#meta)

## 21.4 Reflection [[meta.reflection]](meta.reflection#access.context)

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

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4997)

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]](class.access.base "11.8.3 Accessibility of base classes and base class members")), if any[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5004)

An access_context has an associated scope and designating class[.](#2.sentence-1)

[ð](#lib:access_context_)

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](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5024)

access_context is a structural type[.](#3.sentence-1)

Two values ac1 and ac2 of type access_context are template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence"))
if ac1.scope() and ac2.scope() are template-argument-equivalent
and ac1.designating_class() and ac2.designating_class() are template-argument-equivalent[.](#3.sentence-2)

[ð](#itemdecl:1)

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

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5039)

*Returns*: The access_context's associated scope
and designating class, respectively[.](#4.sentence-1)

[ð](#itemdecl:2)

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

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5050)

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

- [(5.1)](#5.1)

  If a potentially-evaluated subexpression ([[intro.execution]](intro.execution "6.10.1 Sequential execution"))
 of a default member initializer I for a member of class C ([[class.mem.general]](class.mem.general "11.4.1 General"))
 appears at P,
 then a point determined as follows:
  * [(5.1.1)](#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.1.sentence-1)

  * [(5.1.2)](#5.1.2)

      Otherwise, if an initialization
 by an inherited constructor ([[class.inhctor.init]](class.inhctor.init "11.9.4 Initialization by inherited constructor")) is using I,
 a point whose immediate scope is the class scope corresponding to C[.](#5.1.2.sentence-1)

  * [(5.1.3)](#5.1.3)

      Otherwise, a point whose immediate scope
 is the function parameter scope
 corresponding to the constructor definition that is using I[.](#5.1.3.sentence-1)

- [(5.2)](#5.2)

  Otherwise, if a potentially-evaluated subexpression
 of a default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")) appears at P, *eval-point*(Q),
 where Q is the point at which the invocation of the function ([[expr.call]](expr.call "7.6.1.3 Function call"))
 using that default argument appears[.](#5.2.sentence-1)

- [(5.3)](#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*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of D,
 a point whose immediate scope is the innermost scope enclosing the locus of D that is not a template parameter scope[.](#5.3.sentence-1)

- [(5.4)](#5.4)

  Otherwise, if the immediate scope of P is a function parameter scope
 introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") L whose [*lambda-introducer*](expr.prim.lambda.general#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") appears at point Q,
 and P appears either within the [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") or the trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of L, *eval-point*(Q)[.](#5.4.sentence-1)

- [(5.5)](#5.5)

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

a block scope or

  * [(5.5.2)](#5.5.2)

a function parameter scope or lambda scope
 introduced by a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]")[.](#5.5.sentence-1)

- [(5.6)](#5.6)

  Otherwise, P[.](#5.6.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5114)

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

- [(6.1)](#6.1)

  If S is a class scope or namespace scope, S[.](#6.1.sentence-1)

- [(6.2)](#6.2)

  Otherwise, if S is a function parameter scope
 introduced by the declaration of a function, S[.](#6.2.sentence-1)

- [(6.3)](#6.3)

  Otherwise, if S is a lambda scope
 introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") L,
 the function parameter scope
 corresponding to the call operator of the closure type of L[.](#6.3.sentence-1)

- [(6.4)](#6.4)

  Otherwise, *ctx-scope*(Sâ²),
 where Sâ² is the parent scope of S[.](#6.4.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5135)

*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[.](#7.sentence-1)

[*Example [1](#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); // OKtemplate<auto R>struct TCls {consteval bool fn()requires (is_type(access_context::current().scope())) {return true; // OK, scope is TCls<R>.}}; static_assert(TCls<0>{}.fn()); // OK} â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5185)

*Remarks*: current is not an addressable function ([[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"))[.](#8.sentence-1)

An invocation of current that appears at a program point P is value-dependent ([[temp.dep.constexpr]](temp.dep.constexpr "13.8.3.4 Value-dependent expressions"))
if *eval-point*​(​P) is enclosed by a scope
corresponding to a templated entity[.](#8.sentence-2)

[ð](#itemdecl:3)

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

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5199)

*Returns*: An access_context whose designating class is the null reflection
and whose scope is the global namespace[.](#9.sentence-1)

[ð](#itemdecl:4)

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

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5210)

*Returns*: An access_context whose designating class and scope
are both the null reflection[.](#10.sentence-1)

[ð](#itemdecl:5)

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

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5221)

*Returns*: An access_context whose scope is this->scope() and whose designating class is cls[.](#11.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5226)

*Throws*: meta​::​exception unlesscls is either the null reflection
or a reflection of a complete class type[.](#12.sentence-1)
