Init
This commit is contained in:
219
cppdraft/expr/reflect.md
Normal file
219
cppdraft/expr/reflect.md
Normal file
@@ -0,0 +1,219 @@
|
||||
[expr.reflect]
|
||||
|
||||
# 7 Expressions [[expr]](./#expr)
|
||||
|
||||
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.reflect)
|
||||
|
||||
### 7.6.2 Unary expressions [[expr.unary]](expr.unary#expr.reflect)
|
||||
|
||||
#### 7.6.2.10 The reflection operator [expr.reflect]
|
||||
|
||||
[reflect-expression:](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]")
|
||||
^^ ::
|
||||
^^ [*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]")
|
||||
^^ [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")
|
||||
^^ [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]")
|
||||
|
||||
[reflection-name:](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]")
|
||||
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||||
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") template [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6637)
|
||||
|
||||
The unary ^^ operator,
|
||||
called the [*reflection operator*](#def:operator,reflection "7.6.2.10 The reflection operator [expr.reflect]"),
|
||||
yields a prvalue of type std::meta::info ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This document places no restriction on representing, by reflections,
|
||||
constructs not described by this document or
|
||||
using the names of such constructs
|
||||
as operands of [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]")*s*[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6648)
|
||||
|
||||
The component names of a [*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") are those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") (if any) and
|
||||
its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")[.](#2.sentence-1)
|
||||
|
||||
The terminal name of a [*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") of the form[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") template [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") shall denote a template[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6656)
|
||||
|
||||
A [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") is parsed as
|
||||
the longest possible sequence of tokens
|
||||
that could syntactically form a [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]")[.](#3.sentence-1)
|
||||
|
||||
An unparenthesized [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") that represents a template shall not be followed by <[.](#3.sentence-2)
|
||||
|
||||
[*Example [1](#example-1)*: static_assert(std::meta::is_type(^^int())); // ^^ applies to the type-id int()template<bool> struct X {};consteval bool operator<(std::meta::info, X<false>) { return false; }consteval void g(std::meta::info r, X<false> xv) { r == ^^int && true; // error: ^^ applies to the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") int&& r == ^^int & true; // error: ^^ applies to the type-id int& r == (^^int) && true; // OK r == ^^int &&&& true; // error: int &&&& is not a valid [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")^^X < xv; // error: [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") that represents a template is followed by <(^^X) < xv; // OK^^X<true> < xv; // OK} â *end example*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6680)
|
||||
|
||||
A [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") of the form ^^:: represents the global namespace[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6684)
|
||||
|
||||
If a [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") R matches
|
||||
the form ^^[*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]"),
|
||||
it is interpreted as such;
|
||||
the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is looked up and
|
||||
the representation of R is determined as follows:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If lookup finds a declaration
|
||||
that replaced a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") during a single search ([[basic.lookup.general]](basic.lookup.general "6.5.1 General"), [[namespace.udecl]](namespace.udecl "9.10 The using declaration")),R is ill-formed[.](#5.1.sentence-1)
|
||||
[*Example [2](#example-2)*: struct A { struct S {}; };struct B : A { using A::S; };constexpr std::meta::info r1 = ^^B::S; // error: A::S found through [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")struct C : virtual B { struct S {}; };struct D : virtual B, C {};
|
||||
D::S s; // OK, names C::S per [[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup")constexpr std::meta::info r2 = ^^D::S; // OK, result C::S not found through [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") â *end example*]
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
Otherwise, if lookup finds a namespace alias ([[namespace.alias]](namespace.alias "9.9.3 Namespace alias")),R represents that namespace alias[.](#5.2.sentence-1)
|
||||
For any other [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),R represents the denoted namespace[.](#5.2.sentence-2)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
Otherwise, if lookup finds a namespace ([[basic.namespace]](basic.namespace "9.9 Namespaces")),R represents that namespace[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
Otherwise, if lookup finds a concept ([[temp.concept]](temp.concept "13.7.9 Concept definitions")),R represents the denoted concept[.](#5.4.sentence-1)
|
||||
|
||||
- [(5.5)](#5.5)
|
||||
|
||||
Otherwise, if lookup finds a template ([[temp.names]](temp.names "13.3 Names of template specializations")),
|
||||
the representation of R is determined as follows:
|
||||
* [(5.5.1)](#5.5.1)
|
||||
|
||||
If lookup finds an injected-class-name ([[class.pre]](class.pre "11.1 Preamble")), then:
|
||||
+
|
||||
[(5.5.1.1)](#5.5.1.1)
|
||||
If the [*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") is of the form[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") template [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"),
|
||||
then R represents the class template named by the injected-class-name[.](#5.5.1.1.sentence-1)
|
||||
|
||||
+
|
||||
[(5.5.1.2)](#5.5.1.2)
|
||||
Otherwise, the injected-class-name shall be unambiguous
|
||||
when considered as a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") andR represents the class template specialization so named[.](#5.5.1.2.sentence-1)
|
||||
|
||||
* [(5.5.2)](#5.5.2)
|
||||
|
||||
Otherwise, if lookup finds an overload set,
|
||||
that overload set shall contain only
|
||||
declarations of a unique function template F;R represents F[.](#5.5.2.sentence-1)
|
||||
|
||||
* [(5.5.3)](#5.5.3)
|
||||
|
||||
Otherwise, if lookup finds
|
||||
a class template, variable template, or alias template,R represents that template[.](#5.5.3.sentence-1)
|
||||
[*Note [2](#note-2)*:
|
||||
Lookup never finds a partial or explicit specialization[.](#5.5.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(5.6)](#5.6)
|
||||
|
||||
Otherwise, if lookup finds a type alias A,R represents the underlying entity of A if A was introduced by the declaration of a template parameter;
|
||||
otherwise, R represents A[.](#5.6.sentence-1)
|
||||
|
||||
- [(5.7)](#5.7)
|
||||
|
||||
Otherwise, if lookup finds a class or an enumeration,R represents the denoted type[.](#5.7.sentence-1)
|
||||
|
||||
- [(5.8)](#5.8)
|
||||
|
||||
Otherwise, if lookup finds a class member of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions")), R represents that class member[.](#5.8.sentence-1)
|
||||
|
||||
- [(5.9)](#5.9)
|
||||
|
||||
Otherwise,
|
||||
the [*reflection-name*](#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") shall be an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") I and R is ^^I (see below)[.](#5.9.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6764)
|
||||
|
||||
A [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") R of the form^^[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") represents an entity determined as follows:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") designates
|
||||
a placeholder type ([[dcl.spec.auto.general]](dcl.spec.auto.general "9.2.9.7.1 General")),R is ill-formed[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
Otherwise, if the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") names a type alias
|
||||
that is a specialization of an alias template ([[temp.alias]](temp.alias "13.7.8 Alias templates")),R represents that type alias[.](#6.2.sentence-1)
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
Otherwise, R represents the type denoted by the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")[.](#6.3.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L6781)
|
||||
|
||||
A [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") R of the form^^[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") represents an entity determined as follows:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
If the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") denotes
|
||||
* [(7.1.1)](#7.1.1)
|
||||
|
||||
a variable declared by
|
||||
an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures")),
|
||||
|
||||
* [(7.1.2)](#7.1.2)
|
||||
|
||||
a function-local predefined variable ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1 General")),
|
||||
|
||||
* [(7.1.3)](#7.1.3)
|
||||
|
||||
a local parameter introduced by
|
||||
a [*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") ([[expr.prim.req]](expr.prim.req "7.5.8 Requires expressions")), or
|
||||
|
||||
* [(7.1.4)](#7.1.4)
|
||||
|
||||
a local entity E ([[basic.pre]](basic.pre "6.1 Preamble")) for which a lambda scope intervenes
|
||||
between the point at which E was introduced and R,
|
||||
|
||||
then R is ill-formed[.](#7.1.sentence-1)
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
Otherwise, if the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") denotes an overload set S,
|
||||
overload resolution for the expression &S with no target
|
||||
shall select a unique function ([[over.over]](over.over "12.3 Address of an overload set"));R represents that function[.](#7.2.sentence-1)
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
Otherwise, if the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") denotes
|
||||
a variable, structured binding, enumerator, or non-static data member,R represents that entity[.](#7.3.sentence-1)
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
Otherwise, R is ill-formed[.](#7.4.sentence-1)
|
||||
[*Note [3](#note-3)*:
|
||||
This includes [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")*s* that name a constant template parameter and[*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]")*s*[.](#7.4.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
The [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of
|
||||
a [*reflect-expression*](#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") is an unevaluated operand ([[expr.context]](expr.context "7.2.3 Context dependence"))[.](#7.sentence-2)
|
||||
|
||||
[*Example [3](#example-3)*: template<typename T> void fn() requires (^^T != ^^int);template<typename T> void fn() requires (^^T == ^^int);template<typename T> void fn() requires (sizeof(T) == sizeof(int));
|
||||
|
||||
constexpr std::meta::info a = ^^fn<char>; // OKconstexpr std::meta::info b = ^^fn<int>; // error: ambiguousconstexpr std::meta::info c = ^^std::vector; // OKtemplate<typename T>struct S {static constexpr std::meta::info r = ^^T; using type = T;};static_assert(S<int>::r == ^^int);static_assert(^^S<int>::type != ^^int);
|
||||
|
||||
typedef struct X {} Y;typedef struct Z {} Z;constexpr std::meta::info e = ^^Y; // OK, represents the type alias Yconstexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type ([[basic.lookup.general]](basic.lookup.general "6.5.1 General")) â *end example*]
|
||||
Reference in New Issue
Block a user