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

1112 lines
33 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.6Functions"))[.](#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.1Enumeration 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.1Enumeration declarations[dcl.enum]") as specified in [[dcl.enum]](dcl.enum "9.8.1Enumeration 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.1General")),
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.1General")), 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.7Constant 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.9Expression splicing[expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9Expression 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.3Deleted definitions"))
or defaulted function ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2Explicitly-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.2Explicitly-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.5Exception 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.1General"))
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.6Storage 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.7Program 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.9Types"))[.](#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.1Enumeration declarations[dcl.enum]") of D ([[dcl.enum]](dcl.enum "9.8.1Enumeration 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.3Conversion functions")),
operator function ([[over.oper]](over.oper "12.4Overloaded operators")), or
literal operator ([[over.literal]](over.literal "12.6User-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.4Special 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.6Functions"))[.](#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.6Functions"))[.](#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.12Linkage 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.1General[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.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble")),
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.3Constant 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.6Functions")) 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.4Function 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)