1112 lines
33 KiB
Markdown
1112 lines
33 KiB
Markdown
[meta.reflection.queries]
|
||
|
||
# 21 Metaprogramming library [[meta]](./#meta)
|
||
|
||
## 21.4 Reflection [[meta.reflection]](meta.reflection#queries)
|
||
|
||
### 21.4.7 Reflection queries [meta.reflection.queries]
|
||
|
||
[ð](#itemdecl:1)
|
||
|
||
`consteval bool has-type(info r); // exposition only
|
||
`
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3881)
|
||
|
||
*Returns*: true if r represents a
|
||
value,
|
||
annotation,
|
||
object,
|
||
variable,
|
||
function whose type does not contain an undeduced placeholder type
|
||
and that is not a constructor or destructor,
|
||
enumerator,
|
||
non-static data member,
|
||
unnamed bit-field,
|
||
direct base class relationship,
|
||
data member description, or
|
||
function parameter[.](#1.sentence-1)
|
||
|
||
Otherwise, false[.](#1.sentence-2)
|
||
|
||
[ð](#lib:type_of)
|
||
|
||
`consteval info type_of(info r);
|
||
`
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3905)
|
||
|
||
*Returns*:
|
||
|
||
- [(2.1)](#2.1)
|
||
|
||
If r represents the ith parameter of a function F,
|
||
then the ith type
|
||
in the parameter-type-list of F ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#2.1.sentence-1)
|
||
|
||
- [(2.2)](#2.2)
|
||
|
||
Otherwise, if r represents a
|
||
value,
|
||
object,
|
||
variable,
|
||
function,
|
||
non-static data member, or
|
||
unnamed bit-field,
|
||
then the type of what is represented by r[.](#2.2.sentence-1)
|
||
|
||
- [(2.3)](#2.3)
|
||
|
||
Otherwise, if r represents an annotation,
|
||
then type_of(constant_of(r))[.](#2.3.sentence-1)
|
||
|
||
- [(2.4)](#2.4)
|
||
|
||
Otherwise, if r represents
|
||
an enumerator N of an enumeration E, then:
|
||
* [(2.4.1)](#2.4.1)
|
||
|
||
If E is defined by a declaration D that precedes a point P in the evaluation context
|
||
and P does not occur within an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") of D,
|
||
then a reflection of E[.](#2.4.1.sentence-1)
|
||
|
||
* [(2.4.2)](#2.4.2)
|
||
|
||
Otherwise, a reflection of the type of N prior to the closing brace of the [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") as specified in [[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")[.](#2.4.2.sentence-1)
|
||
|
||
- [(2.5)](#2.5)
|
||
|
||
Otherwise, if r represents
|
||
a direct base class relationship (D,B),
|
||
then a reflection of B[.](#2.5.sentence-1)
|
||
|
||
- [(2.6)](#2.6)
|
||
|
||
Otherwise, for a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")),
|
||
a reflection of the type T[.](#2.6.sentence-1)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3947)
|
||
|
||
*Throws*: meta::exception unless*has-type*(r) is true[.](#3.sentence-1)
|
||
|
||
[ð](#lib:object_of)
|
||
|
||
`consteval info object_of(info r);
|
||
`
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3959)
|
||
|
||
*Returns*:
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
If r represents an object,
|
||
then r[.](#4.1.sentence-1)
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
Otherwise, if r represents a reference,
|
||
then a reflection of the object referred to by that reference[.](#4.2.sentence-1)
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
Otherwise, r represents a variable;
|
||
a reflection of the object declared by that variable[.](#4.3.sentence-1)
|
||
|
||
[*Example [1](#example-1)*: int x;int& y = x;
|
||
|
||
static_assert(^^x != ^^y); // OK, r and y are different variables so their// reflections compare differentstatic_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference// to x, their underlying objects are the same â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3984)
|
||
|
||
*Throws*: meta::exception unlessr is a reflection representing either
|
||
|
||
- [(5.1)](#5.1)
|
||
|
||
an object with static storage duration ([[basic.stc.general]](basic.stc.general "6.8.6.1 General")), or
|
||
|
||
- [(5.2)](#5.2)
|
||
|
||
a variable that either declares or refers to such an object,
|
||
and if that variable is a reference R, then either
|
||
* [(5.2.1)](#5.2.1)
|
||
|
||
R is usable in constant expressions ([[expr.const]](expr.const "7.7 Constant expressions")), or
|
||
|
||
* [(5.2.2)](#5.2.2)
|
||
|
||
the lifetime of R began within the core constant expression
|
||
currently under evaluation[.](#5.sentence-1)
|
||
|
||
[ð](#lib:constant_of)
|
||
|
||
`consteval info constant_of(info r);
|
||
`
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4010)
|
||
|
||
Let R be a constant expression of type info such that R == r is true[.](#6.sentence-1)
|
||
|
||
If r represents an annotation,
|
||
then let C be its underlying constant[.](#6.sentence-2)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4016)
|
||
|
||
*Effects*: Equivalent to:if constexpr (is_annotation(R)) {return C;} else {return reflect_constant([: R :]);}
|
||
|
||
[*Example [2](#example-2)*: constexpr int x = 0;constexpr int y = 0;
|
||
|
||
static_assert(^^x != ^^y); // OK, x and y are different variables,// so their reflections compare differentstatic_assert(constant_of(^^x) == constant_of(^^y)); // OK, both constant_of(^^x) and// constant_of(^^y) represent the value 0static_assert(constant_of(^^x) == reflect_constant(0)); // OK, likewisestruct S { int m; };constexpr S s {42};static_assert(is_object(constant_of(^^s)) && is_object(reflect_object(s)));static_assert(constant_of(^^s) != // OK, template parameter object that is template-argument- reflect_object(s)); // equivalent to s is a different object than sstatic_assert(constant_of(^^s) == constant_of(reflect_object(s))); // OKconsteval info fn() {constexpr int x = 42; return ^^x;}constexpr info r = constant_of(fn()); // error: x is outside its lifetime â *end example*]
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4056)
|
||
|
||
*Throws*: meta::exception unless
|
||
either r represents an annotation or[: R :] is a valid[*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing"))[.](#8.sentence-1)
|
||
|
||
[ð](#lib:is_public)
|
||
|
||
`consteval bool is_public(info r);
|
||
consteval bool is_protected(info r);
|
||
consteval bool is_private(info r);
|
||
`
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4074)
|
||
|
||
*Returns*: true if r represents either
|
||
|
||
- [(9.1)](#9.1)
|
||
|
||
a class member or unnamed bit-field
|
||
that is public, protected, or private, respectively, or
|
||
|
||
- [(9.2)](#9.2)
|
||
|
||
a direct base class relationship (D,B) for which B is, respectively,
|
||
a public, protected, or private base class of D[.](#9.sentence-1)
|
||
|
||
Otherwise, false[.](#9.sentence-2)
|
||
|
||
[ð](#lib:is_virtual)
|
||
|
||
`consteval bool is_virtual(info r);
|
||
`
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4094)
|
||
|
||
*Returns*: true if r represents either a virtual member function
|
||
or a direct base class relationship (D,B) for which B is a virtual base class of D[.](#10.sentence-1)
|
||
|
||
Otherwise, false[.](#10.sentence-2)
|
||
|
||
[ð](#lib:is_pure_virtual)
|
||
|
||
`consteval bool is_pure_virtual(info r);
|
||
consteval bool is_override(info r);
|
||
`
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4110)
|
||
|
||
*Returns*: true if r represents a member function that is pure virtual
|
||
or overrides another member function, respectively[.](#11.sentence-1)
|
||
|
||
Otherwise, false[.](#11.sentence-2)
|
||
|
||
[ð](#lib:is_final)
|
||
|
||
`consteval bool is_final(info r);
|
||
`
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4123)
|
||
|
||
*Returns*: true if r represents a final class or a final member function[.](#12.sentence-1)
|
||
|
||
Otherwise, false[.](#12.sentence-2)
|
||
|
||
[ð](#lib:is_deleted)
|
||
|
||
`consteval bool is_deleted(info r);
|
||
consteval bool is_defaulted(info r);
|
||
`
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4137)
|
||
|
||
*Returns*: true if r represents a function that is
|
||
a deleted function ([[dcl.fct.def.delete]](dcl.fct.def.delete "9.6.3 Deleted definitions"))
|
||
or defaulted function ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")), respectively[.](#13.sentence-1)
|
||
|
||
Otherwise, false[.](#13.sentence-2)
|
||
|
||
[ð](#lib:is_user_provided)
|
||
|
||
`consteval bool is_user_provided(info r);
|
||
consteval bool is_user_declared(info r);
|
||
`
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4153)
|
||
|
||
*Returns*: true if r represents a function that is
|
||
user-provided or user-declared ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")), respectively[.](#14.sentence-1)
|
||
|
||
Otherwise, false[.](#14.sentence-2)
|
||
|
||
[ð](#lib:is_explicit)
|
||
|
||
`consteval bool is_explicit(info r);
|
||
`
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4166)
|
||
|
||
*Returns*: true if r represents a member function that is declared explicit[.](#15.sentence-1)
|
||
|
||
Otherwise, false[.](#15.sentence-2)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
If r represents a member function template that is declared explicit,is_explicit(r) is still false because in general,
|
||
such queries for templates cannot be answered[.](#15.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:is_noexcept)
|
||
|
||
`consteval bool is_noexcept(info r);
|
||
`
|
||
|
||
[16](#16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4184)
|
||
|
||
*Returns*: true if r represents a noexcept function type
|
||
or a function with a non-throwing exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#16.sentence-1)
|
||
|
||
Otherwise, false[.](#16.sentence-2)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
If r represents a function template that is declared noexcept,is_noexcept(r) is still false because in general,
|
||
such queries for templates cannot be answered[.](#16.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:is_bit_field)
|
||
|
||
`consteval bool is_bit_field(info r);
|
||
`
|
||
|
||
[17](#17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4203)
|
||
|
||
*Returns*: true if r represents a bit-field,
|
||
or if r represents a data member description(T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"))
|
||
for which W is not â¥[.](#17.sentence-1)
|
||
|
||
Otherwise, false[.](#17.sentence-2)
|
||
|
||
[ð](#lib:is_enumerator)
|
||
|
||
`consteval bool is_enumerator(info r);
|
||
consteval bool is_annotation(info r);
|
||
`
|
||
|
||
[18](#18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4220)
|
||
|
||
*Returns*: true if r represents an enumerator or annotation, respectively[.](#18.sentence-1)
|
||
|
||
Otherwise, false[.](#18.sentence-2)
|
||
|
||
[ð](#lib:is_const)
|
||
|
||
`consteval bool is_const(info r);
|
||
consteval bool is_volatile(info r);
|
||
`
|
||
|
||
[19](#19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4234)
|
||
|
||
Let T be type_of(r) if *has-type*(r) is true[.](#19.sentence-1)
|
||
|
||
Otherwise, let T be dealias(r)[.](#19.sentence-2)
|
||
|
||
[20](#20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4238)
|
||
|
||
*Returns*: true if T represents a const or volatile type, respectively,
|
||
or a const- or volatile-qualified function type, respectively[.](#20.sentence-1)
|
||
|
||
Otherwise, false[.](#20.sentence-2)
|
||
|
||
[ð](#lib:is_mutable_member)
|
||
|
||
`consteval bool is_mutable_member(info r);
|
||
`
|
||
|
||
[21](#21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4251)
|
||
|
||
*Returns*: true if r represents a mutable non-static data member[.](#21.sentence-1)
|
||
|
||
Otherwise, false[.](#21.sentence-2)
|
||
|
||
[ð](#lib:is_lvalue_reference_qualified)
|
||
|
||
`consteval bool is_lvalue_reference_qualified(info r);
|
||
consteval bool is_rvalue_reference_qualified(info r);
|
||
`
|
||
|
||
[22](#22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4265)
|
||
|
||
Let T be type_of(r) if *has-type*(r) is true[.](#22.sentence-1)
|
||
|
||
Otherwise, let T be dealias(r)[.](#22.sentence-2)
|
||
|
||
[23](#23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4269)
|
||
|
||
*Returns*: true if T represents an
|
||
lvalue- or rvalue-qualified function type, respectively[.](#23.sentence-1)
|
||
|
||
Otherwise, false[.](#23.sentence-2)
|
||
|
||
[ð](#lib:has_static_storage_duration)
|
||
|
||
`consteval bool has_static_storage_duration(info r);
|
||
consteval bool has_thread_storage_duration(info r);
|
||
consteval bool has_automatic_storage_duration(info r);
|
||
`
|
||
|
||
[24](#24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4286)
|
||
|
||
*Returns*: true if r represents an object or variable that has
|
||
static, thread, or automatic storage duration, respectively ([[basic.stc]](basic.stc "6.8.6 Storage duration"))[.](#24.sentence-1)
|
||
|
||
Otherwise, false[.](#24.sentence-2)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
It is not possible to have a reflection
|
||
representing an object or variable having dynamic storage duration[.](#24.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:has_internal_linkage)
|
||
|
||
`consteval bool has_internal_linkage(info r);
|
||
consteval bool has_module_linkage(info r);
|
||
consteval bool has_external_linkage(info r);
|
||
consteval bool has_c_language_linkage(info r);
|
||
consteval bool has_linkage(info r);
|
||
`
|
||
|
||
[25](#25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4311)
|
||
|
||
*Returns*: true if r represents a
|
||
variable,
|
||
function,
|
||
type,
|
||
template, or
|
||
namespace
|
||
whose name has
|
||
internal linkage,
|
||
module linkage,
|
||
C language linkage, or
|
||
any linkage, respectively ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#25.sentence-1)
|
||
|
||
Otherwise, false[.](#25.sentence-2)
|
||
|
||
[ð](#lib:is_complete_type)
|
||
|
||
`consteval bool is_complete_type(info r);
|
||
`
|
||
|
||
[26](#26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4333)
|
||
|
||
*Returns*: true if is_type(r) is true and there is some point in the evaluation context
|
||
from which the type represented by dealias(r) is not an incomplete type ([[basic.types]](basic.types "6.9 Types"))[.](#26.sentence-1)
|
||
|
||
Otherwise, false[.](#26.sentence-2)
|
||
|
||
[ð](#lib:is_enumerable_type)
|
||
|
||
`consteval bool is_enumerable_type(info r);
|
||
`
|
||
|
||
[27](#27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4348)
|
||
|
||
A type T is [*enumerable*](#def:enumerable) from a point P if either
|
||
|
||
- [(27.1)](#27.1)
|
||
|
||
T is a class type complete at point P or
|
||
|
||
- [(27.2)](#27.2)
|
||
|
||
T is an enumeration type defined by a declaration D such that D is reachable from P but P does not occur within an [*enum-specifier*](dcl.enum#nt:enum-specifier "9.8.1 Enumeration declarations [dcl.enum]") of D ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations"))[.](#27.sentence-1)
|
||
|
||
[28](#28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4359)
|
||
|
||
*Returns*: true if dealias(r) represents a type that is enumerable
|
||
from some point in the evaluation context[.](#28.sentence-1)
|
||
|
||
Otherwise, false[.](#28.sentence-2)
|
||
|
||
[*Example [3](#example-3)*: class S;enum class E;static_assert(!is_enumerable_type(^^S));static_assert(!is_enumerable_type(^^E));
|
||
|
||
class S {void mfn() {static_assert(is_enumerable_type(^^S)); }static_assert(!is_enumerable_type(^^S));};static_assert(is_enumerable_type(^^S));
|
||
|
||
enum class E { A = is_enumerable_type(^^E) ? 1 : 2};static_assert(is_enumerable_type(^^E));static_assert(static_cast<int>(E::A) == 2); â *end example*]
|
||
|
||
[ð](#lib:is_variable)
|
||
|
||
`consteval bool is_variable(info r);
|
||
`
|
||
|
||
[29](#29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4394)
|
||
|
||
*Returns*: true if r represents a variable[.](#29.sentence-1)
|
||
|
||
Otherwise, false[.](#29.sentence-2)
|
||
|
||
[ð](#lib:is_type)
|
||
|
||
`consteval bool is_type(info r);
|
||
consteval bool is_namespace(info r);
|
||
`
|
||
|
||
[30](#30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4408)
|
||
|
||
*Returns*: true if r represents an entity
|
||
whose underlying entity is a type or namespace, respectively[.](#30.sentence-1)
|
||
|
||
Otherwise, false[.](#30.sentence-2)
|
||
|
||
[ð](#lib:is_type_alias)
|
||
|
||
`consteval bool is_type_alias(info r);
|
||
consteval bool is_namespace_alias(info r);
|
||
`
|
||
|
||
[31](#31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4423)
|
||
|
||
*Returns*: true if r represents a type alias or namespace alias, respectively[.](#31.sentence-1)
|
||
|
||
Otherwise, false[.](#31.sentence-2)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
A specialization of an alias template is a type alias[.](#31.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:is_function)
|
||
|
||
`consteval bool is_function(info r);
|
||
`
|
||
|
||
[32](#32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4438)
|
||
|
||
*Returns*: true if r represents a function[.](#32.sentence-1)
|
||
|
||
Otherwise, false[.](#32.sentence-2)
|
||
|
||
[ð](#lib:is_conversion_function)
|
||
|
||
`consteval bool is_conversion_function(info r);
|
||
consteval bool is_operator_function(info r);
|
||
consteval bool is_literal_operator(info r);
|
||
`
|
||
|
||
[33](#33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4454)
|
||
|
||
*Returns*: true if r represents a function that is a
|
||
conversion function ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions")),
|
||
operator function ([[over.oper]](over.oper "12.4 Overloaded operators")), or
|
||
literal operator ([[over.literal]](over.literal "12.6 User-defined literals")), respectively[.](#33.sentence-1)
|
||
|
||
Otherwise, false[.](#33.sentence-2)
|
||
|
||
[ð](#lib:is_special_member_function)
|
||
|
||
`consteval bool is_special_member_function(info r);
|
||
consteval bool is_constructor(info r);
|
||
consteval bool is_default_constructor(info r);
|
||
consteval bool is_copy_constructor(info r);
|
||
consteval bool is_move_constructor(info r);
|
||
consteval bool is_assignment(info r);
|
||
consteval bool is_copy_assignment(info r);
|
||
consteval bool is_move_assignment(info r);
|
||
consteval bool is_destructor(info r);
|
||
`
|
||
|
||
[34](#34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4485)
|
||
|
||
*Returns*: true if r represents a function that is a
|
||
special member function ([[special]](special "11.4.4 Special member functions")),
|
||
a constructor,
|
||
a default constructor,
|
||
a copy constructor,
|
||
a move constructor,
|
||
an assignment operator,
|
||
a copy assignment operator,
|
||
a move assignment operator, or
|
||
a destructor, respectively[.](#34.sentence-1)
|
||
|
||
Otherwise, false[.](#34.sentence-2)
|
||
|
||
[ð](#lib:is_function_parameter)
|
||
|
||
`consteval bool is_function_parameter(info r);
|
||
`
|
||
|
||
[35](#35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4506)
|
||
|
||
*Returns*: true if r represents a function parameter[.](#35.sentence-1)
|
||
|
||
Otherwise, false[.](#35.sentence-2)
|
||
|
||
[ð](#lib:is_explicit_object_parameter)
|
||
|
||
`consteval bool is_explicit_object_parameter(info r);
|
||
`
|
||
|
||
[36](#36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4518)
|
||
|
||
*Returns*: true if r represents a function parameter
|
||
that is an explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#36.sentence-1)
|
||
|
||
Otherwise, false[.](#36.sentence-2)
|
||
|
||
[ð](#lib:has_default_argument)
|
||
|
||
`consteval bool has_default_argument(info r);
|
||
`
|
||
|
||
[37](#37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4531)
|
||
|
||
*Returns*: If r represents a parameter P of a function F, then:
|
||
|
||
- [(37.1)](#37.1)
|
||
|
||
If F is a specialization of a templated function T,
|
||
then true if there exists a declaration D of T that precedes some point in the evaluation context
|
||
and D specifies a default argument
|
||
for the parameter of T corresponding to P[.](#37.1.sentence-1)
|
||
Otherwise, false[.](#37.1.sentence-2)
|
||
|
||
- [(37.2)](#37.2)
|
||
|
||
Otherwise, if there exists a declaration D of F that precedes some point in the evaluation context
|
||
and D specifies a default argument for P,
|
||
then true[.](#37.2.sentence-1)
|
||
|
||
Otherwise, false[.](#37.sentence-2)
|
||
|
||
[ð](#lib:has_ellipsis_parameter)
|
||
|
||
`consteval bool has_ellipsis_parameter(info r);
|
||
`
|
||
|
||
[38](#38)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4557)
|
||
|
||
*Returns*: true if r represents a function or function type
|
||
that has an ellipsis in its parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#38.sentence-1)
|
||
|
||
Otherwise, false[.](#38.sentence-2)
|
||
|
||
[ð](#lib:is_template)
|
||
|
||
`consteval bool is_template(info r);
|
||
`
|
||
|
||
[39](#39)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4570)
|
||
|
||
*Returns*: true if r represents a
|
||
function template,
|
||
class template,
|
||
variable template,
|
||
alias template, or
|
||
concept[.](#39.sentence-1)
|
||
|
||
Otherwise, false[.](#39.sentence-2)
|
||
|
||
[40](#40)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4580)
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
A template specialization is not a template[.](#40.sentence-1)
|
||
|
||
For example,is_template(^^std::vector) is true but is_template(^^std::vector<int>) is false[.](#40.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:is_function_template)
|
||
|
||
`consteval bool is_function_template(info r);
|
||
consteval bool is_variable_template(info r);
|
||
consteval bool is_class_template(info r);
|
||
consteval bool is_alias_template(info r);
|
||
consteval bool is_conversion_function_template(info r);
|
||
consteval bool is_operator_function_template(info r);
|
||
consteval bool is_literal_operator_template(info r);
|
||
consteval bool is_constructor_template(info r);
|
||
consteval bool is_concept(info r);
|
||
`
|
||
|
||
[41](#41)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4611)
|
||
|
||
*Returns*: true if r represents a
|
||
function template,
|
||
variable template,
|
||
class template,
|
||
alias template,
|
||
conversion function template,
|
||
operator function template,
|
||
literal operator template,
|
||
constructor template, or
|
||
concept, respectively[.](#41.sentence-1)
|
||
|
||
Otherwise, false[.](#41.sentence-2)
|
||
|
||
[ð](#lib:is_value)
|
||
|
||
`consteval bool is_value(info r);
|
||
consteval bool is_object(info r);
|
||
`
|
||
|
||
[42](#42)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4634)
|
||
|
||
*Returns*: true if r represents a value or object, respectively[.](#42.sentence-1)
|
||
|
||
Otherwise, false[.](#42.sentence-2)
|
||
|
||
[ð](#lib:is_structured_binding)
|
||
|
||
`consteval bool is_structured_binding(info r);
|
||
`
|
||
|
||
[43](#43)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4646)
|
||
|
||
*Returns*: true if r represents a structured binding[.](#43.sentence-1)
|
||
|
||
Otherwise, false[.](#43.sentence-2)
|
||
|
||
[ð](#lib:is_class_member)
|
||
|
||
`consteval bool is_class_member(info r);
|
||
consteval bool is_namespace_member(info r);
|
||
consteval bool is_nonstatic_data_member(info r);
|
||
consteval bool is_static_member(info r);
|
||
consteval bool is_base(info r);
|
||
`
|
||
|
||
[44](#44)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4666)
|
||
|
||
*Returns*: true if r represents a
|
||
class member,
|
||
namespace member,
|
||
non-static data member,
|
||
static member, or
|
||
direct base class relationship, respectively[.](#44.sentence-1)
|
||
|
||
Otherwise, false[.](#44.sentence-2)
|
||
|
||
[ð](#lib:has_default_member_initializer)
|
||
|
||
`consteval bool has_default_member_initializer(info r);
|
||
`
|
||
|
||
[45](#45)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4683)
|
||
|
||
*Returns*: true if r represents a non-static data member
|
||
that has a default member initializer[.](#45.sentence-1)
|
||
|
||
Otherwise, false[.](#45.sentence-2)
|
||
|
||
[ð](#lib:has_parent)
|
||
|
||
`consteval bool has_parent(info r);
|
||
`
|
||
|
||
[46](#46)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4696)
|
||
|
||
*Returns*:
|
||
|
||
- [(46.1)](#46.1)
|
||
|
||
If r represents the global namespace,
|
||
then false[.](#46.1.sentence-1)
|
||
|
||
- [(46.2)](#46.2)
|
||
|
||
Otherwise, if r represents an entity that has C language linkage ([[dcl.link]](dcl.link "9.12 Linkage specifications")),
|
||
then false[.](#46.2.sentence-1)
|
||
|
||
- [(46.3)](#46.3)
|
||
|
||
Otherwise, if r represents an entity that has a
|
||
language linkage other than C++ language linkage,
|
||
then an implementation-defined
|
||
value[.](#46.3.sentence-1)
|
||
|
||
- [(46.4)](#46.4)
|
||
|
||
Otherwise, if r represents a type that is neither a class nor enumeration type,
|
||
then false[.](#46.4.sentence-1)
|
||
|
||
- [(46.5)](#46.5)
|
||
|
||
Otherwise, if r represents an entity or direct base class relationship,
|
||
then true[.](#46.5.sentence-1)
|
||
|
||
- [(46.6)](#46.6)
|
||
|
||
Otherwise, false[.](#46.6.sentence-1)
|
||
|
||
[ð](#lib:parent_of)
|
||
|
||
`consteval info parent_of(info r);
|
||
`
|
||
|
||
[47](#47)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4729)
|
||
|
||
*Returns*:
|
||
|
||
- [(47.1)](#47.1)
|
||
|
||
If r represents a non-static data member
|
||
that is a direct member of an anonymous union,
|
||
or an unnamed bit-field declared
|
||
within the [*member-specification*](class.mem.general#nt:member-specification "11.4.1 General [class.mem.general]") of such a union,
|
||
then a reflection representing the innermost enclosing anonymous union[.](#47.1.sentence-1)
|
||
|
||
- [(47.2)](#47.2)
|
||
|
||
Otherwise, if r represents an enumerator,
|
||
then a reflection representing the corresponding enumeration type[.](#47.2.sentence-1)
|
||
|
||
- [(47.3)](#47.3)
|
||
|
||
Otherwise, if r represents a direct base class relationship (D,B),
|
||
then a reflection representing D[.](#47.3.sentence-1)
|
||
|
||
- [(47.4)](#47.4)
|
||
|
||
Otherwise, let E be a class, function, or namespace
|
||
whose class scope, function parameter scope, or namespace scope, respectively,
|
||
is the innermost such scope that either is, or encloses,
|
||
the target scope of a declaration of what is represented by r[.](#47.4.sentence-1)
|
||
|
||
* [(47.4.1)](#47.4.1)
|
||
|
||
If E is the function call operator of a closure type
|
||
for a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||
then parent_of(parent_of(^^E))[.](#47.4.1.sentence-1)
|
||
[*Note [6](#note-6)*:
|
||
In this case,
|
||
the first parent_of will be the closure type,
|
||
so the second parent_of is necessary
|
||
to give the parent of that closure type[.](#47.4.1.sentence-2)
|
||
â *end note*]
|
||
|
||
* [(47.4.2)](#47.4.2)
|
||
|
||
Otherwise, ^^E[.](#47.4.2.sentence-1)
|
||
|
||
[*Example [4](#example-4)*: struct I { };
|
||
|
||
struct F : I {union {int o; }; enum N { A };};
|
||
|
||
constexpr auto ctx = std::meta::access_context::current();
|
||
|
||
static_assert(parent_of(^^F) == ^^::);static_assert(parent_of(bases_of(^^F, ctx)[0]) == ^^F);static_assert(is_union_type(parent_of(^^F::o)));static_assert(parent_of(^^F::N) == ^^F);static_assert(parent_of(^^F::A) == ^^F::N); â *end example*]
|
||
|
||
[48](#48)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4788)
|
||
|
||
*Throws*: meta::exception unlesshas_parent(r) is true[.](#48.sentence-1)
|
||
|
||
[ð](#lib:dealias)
|
||
|
||
`consteval info dealias(info r);
|
||
`
|
||
|
||
[49](#49)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4800)
|
||
|
||
*Returns*: A reflection representing the underlying entity of what r represents[.](#49.sentence-1)
|
||
|
||
[*Example [5](#example-5)*: using X = int;using Y = X;static_assert(dealias(^^int) == ^^int);static_assert(dealias(^^X) == ^^int);static_assert(dealias(^^Y) == ^^int); â *end example*]
|
||
|
||
[50](#50)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4813)
|
||
|
||
*Throws*: meta::exception unlessr represents an entity[.](#50.sentence-1)
|
||
|
||
[ð](#lib:has_template_arguments)
|
||
|
||
`consteval bool has_template_arguments(info r);
|
||
`
|
||
|
||
[51](#51)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4825)
|
||
|
||
*Returns*: true if r represents a specialization of a
|
||
function template,
|
||
variable template,
|
||
class template, or
|
||
an alias template[.](#51.sentence-1)
|
||
|
||
Otherwise, false[.](#51.sentence-2)
|
||
|
||
[ð](#lib:template_of)
|
||
|
||
`consteval info template_of(info r);
|
||
`
|
||
|
||
[52](#52)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4841)
|
||
|
||
*Returns*: A reflection of the template of the specialization represented by r[.](#52.sentence-1)
|
||
|
||
[53](#53)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4845)
|
||
|
||
*Throws*: meta::exception unlesshas_template_arguments(r) is true[.](#53.sentence-1)
|
||
|
||
[ð](#lib:template_arguments_of)
|
||
|
||
`consteval vector<info> template_arguments_of(info r);
|
||
`
|
||
|
||
[54](#54)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4857)
|
||
|
||
*Returns*: A vector containing reflections
|
||
of the template arguments
|
||
of the template specialization represented by r,
|
||
in the order in which they appear in the corresponding template argument list[.](#54.sentence-1)
|
||
|
||
For a given template argument A,
|
||
its corresponding reflection R is determined as follows:
|
||
|
||
- [(54.1)](#54.1)
|
||
|
||
If A denotes a type or type alias,
|
||
then R is a reflection representing the underlying entity of A[.](#54.1.sentence-1)
|
||
[*Note [7](#note-7)*:
|
||
R always represents a type, never a type alias[.](#54.1.sentence-2)
|
||
â *end note*]
|
||
|
||
- [(54.2)](#54.2)
|
||
|
||
Otherwise, if A denotes a
|
||
class template,
|
||
variable template,
|
||
concept, or
|
||
alias template,
|
||
then R is a reflection representing A[.](#54.2.sentence-1)
|
||
|
||
- [(54.3)](#54.3)
|
||
|
||
Otherwise, A is a constant template argument ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#54.3.sentence-1)
|
||
Let P be the corresponding template parameter[.](#54.3.sentence-2)
|
||
|
||
* [(54.3.1)](#54.3.1)
|
||
|
||
If P has reference type,
|
||
then R is a reflection
|
||
representing the object or function referred to by A[.](#54.3.1.sentence-1)
|
||
|
||
* [(54.3.2)](#54.3.2)
|
||
|
||
Otherwise, if P has class type,
|
||
then R represents the corresponding template parameter object[.](#54.3.2.sentence-1)
|
||
|
||
* [(54.3.3)](#54.3.3)
|
||
|
||
Otherwise, R is a reflection representing the value of A[.](#54.3.3.sentence-1)
|
||
|
||
[*Example [6](#example-6)*: template<class T, class U = T> struct Pair { };template<class T> struct Pair<char, T> { };template<class T> using PairPtr = Pair<T*>;
|
||
|
||
static_assert(template_of(^^Pair<int>) == ^^Pair);static_assert(template_of(^^Pair<char, char>) == ^^Pair);static_assert(template_arguments_of(^^Pair<int>).size() == 2);static_assert(template_arguments_of(^^Pair<int>)[0] == ^^int);
|
||
|
||
static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);
|
||
|
||
struct S { };int i;template<int, int&, S, template<class> class>struct X { };constexpr auto T = ^^X<1, i, S{}, PairPtr>;static_assert(is_value(template_arguments_of(T)[0]));static_assert(is_object(template_arguments_of(T)[1]));static_assert(is_object(template_arguments_of(T)[2]));static_assert(template_arguments_of(T)[3] == ^^PairPtr); â *end example*]
|
||
|
||
[55](#55)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4920)
|
||
|
||
*Throws*: meta::exception unlesshas_template_arguments(r) is true[.](#55.sentence-1)
|
||
|
||
[ð](#lib:parameters_of)
|
||
|
||
`consteval vector<info> parameters_of(info r);
|
||
`
|
||
|
||
[56](#56)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4932)
|
||
|
||
*Returns*:
|
||
|
||
- [(56.1)](#56.1)
|
||
|
||
If r represents a function F,
|
||
then a vector containing reflections of the parameters of F,
|
||
in the order in which they appear in a declaration of F[.](#56.1.sentence-1)
|
||
|
||
- [(56.2)](#56.2)
|
||
|
||
Otherwise, r represents a function type T;
|
||
a vector containing reflections of the types
|
||
in parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of T,
|
||
in the order in which they appear in the parameter-type-list[.](#56.2.sentence-1)
|
||
|
||
[57](#57)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4946)
|
||
|
||
*Throws*: meta::exception unlessr represents a function or a function type[.](#57.sentence-1)
|
||
|
||
[ð](#lib:variable_of)
|
||
|
||
`consteval info variable_of(info r);
|
||
`
|
||
|
||
[58](#58)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4958)
|
||
|
||
*Returns*: The reflection of the parameter variable corresponding to r[.](#58.sentence-1)
|
||
|
||
[59](#59)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4962)
|
||
|
||
*Throws*: meta::exception unless
|
||
|
||
- [(59.1)](#59.1)
|
||
|
||
r represents a parameter of a function F and
|
||
|
||
- [(59.2)](#59.2)
|
||
|
||
there is a point P in the evaluation context
|
||
for which the innermost non-block scope enclosing P is the function parameter scope ([[basic.scope.param]](basic.scope.param "6.4.4 Function parameter scope"))
|
||
associated with F[.](#59.sentence-1)
|
||
|
||
[ð](#lib:return_type_of)
|
||
|
||
`consteval info return_type_of(info r);
|
||
`
|
||
|
||
[60](#60)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4982)
|
||
|
||
*Returns*: The reflection of the return type
|
||
of the function or function type represented by r[.](#60.sentence-1)
|
||
|
||
[61](#61)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4987)
|
||
|
||
*Throws*: meta::exception unless
|
||
either r represents a function
|
||
and *has-type*(r) is true or r represents a function type[.](#61.sentence-1)
|