[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)
