Init
This commit is contained in:
54
cppdraft/meta/const/eval.md
Normal file
54
cppdraft/meta/const/eval.md
Normal file
@@ -0,0 +1,54 @@
|
||||
[meta.const.eval]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.const.eval)
|
||||
|
||||
### 21.3.12 Constant evaluation context [meta.const.eval]
|
||||
|
||||
[ð](#lib:is_constant_evaluated)
|
||||
|
||||
`constexpr bool is_constant_evaluated() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2816)
|
||||
|
||||
*Effects*: Equivalent to:if consteval {return true;} else {return false;}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2827)
|
||||
|
||||
[*Example [1](#example-1)*: constexpr void f(unsigned char *p, int n) {if (std::is_constant_evaluated()) { // should not be a constexpr if statementfor (int k = 0; k<n; ++k) p[k] = 0; } else { memset(p, 0, n); // not a core constant expression}} â *end example*]
|
||||
|
||||
[ð](#lib:is_within_lifetime)
|
||||
|
||||
`consteval bool is_within_lifetime(const auto* p) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2847)
|
||||
|
||||
*Returns*: true if p is a pointer to an object that is
|
||||
within its lifetime ([[basic.life]](basic.life "6.8.4 Lifetime")); otherwise, false[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2852)
|
||||
|
||||
*Remarks*: During the evaluation of an expression E as a core constant expression,
|
||||
a call to this function is ill-formed
|
||||
unless p points to an object that is usable
|
||||
in constant expressions or
|
||||
whose complete object's lifetime began within E[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2860)
|
||||
|
||||
[*Example [2](#example-2)*: struct OptBool {union { bool b; char c; }; // note: this assumes common implementation properties for bool and char:// * sizeof(bool) == sizeof(char), and// * the value representations for true and false are distinct// from the value representation for 2constexpr OptBool() : c(2) { }constexpr OptBool(bool b) : b(b) { }constexpr auto has_value() const -> bool {if consteval {return std::is_within_lifetime(&b); // during constant evaluation, cannot read from c} else {return c != 2; // during runtime, must read from c}}constexpr auto operator*() const -> const bool& {return b; }};
|
||||
|
||||
constexpr OptBool disengaged;constexpr OptBool engaged(true);static_assert(!disengaged.has_value());static_assert(engaged.has_value());static_assert(*engaged); â *end example*]
|
||||
62
cppdraft/meta/define/static.md
Normal file
62
cppdraft/meta/define/static.md
Normal file
@@ -0,0 +1,62 @@
|
||||
[meta.define.static]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#meta.define.static)
|
||||
|
||||
### 21.4.3 Promoting to static storage strings [meta.define.static]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3367)
|
||||
|
||||
The functions in this subclause promote compile-time storage into static storage[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:define_static_string)
|
||||
|
||||
`template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||||
consteval const ranges::range_value_t<R>* define_static_string(R&& r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3377)
|
||||
|
||||
*Effects*: Equivalent to:return extract<const ranges::range_value_t<R>*>(meta::reflect_constant_string(r));
|
||||
|
||||
[ð](#lib:define_static_array)
|
||||
|
||||
`template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||||
consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3392)
|
||||
|
||||
*Effects*: Equivalent to:using T = ranges::range_value_t<R>;
|
||||
meta::info array = meta::reflect_constant_array(r);if (is_array_type(type_of(array))) {return span<const T>(extract<const T*>(array), extent(type_of(array)));} else {return span<const T>();}
|
||||
|
||||
[ð](#lib:define_static_object)
|
||||
|
||||
`template<class T>
|
||||
consteval const remove_cvref_t<T>* define_static_object(T&& t);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3413)
|
||||
|
||||
*Effects*: Equivalent to:using U = remove_cvref_t<T>;if constexpr (is_class_type(^^U)) {return addressof(extract<const U&>(meta::reflect_constant(std::forward<T>(t))));} else {return define_static_array(span(addressof(t), 1)).data();}
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3425)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
For class types,define_static_object provides
|
||||
the address of the template parameter object ([[temp.param]](temp.param "13.2 Template parameters"))
|
||||
that is template-argument equivalent to t[.](#5.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
22
cppdraft/meta/general.md
Normal file
22
cppdraft/meta/general.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[meta.general]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.1 General [meta.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6)
|
||||
|
||||
This Clause describes metaprogramming facilities[.](#1.sentence-1)
|
||||
|
||||
These facilities are summarized in Table [51](#tab:meta.summary "Table 51: Metaprogramming library summary")[.](#1.sentence-2)
|
||||
|
||||
Table [51](#tab:meta.summary) — Metaprogramming library summary [[tab:meta.summary]](./tab:meta.summary)
|
||||
|
||||
| [ð](#tab:meta.summary-row-1) | **Subclause** | **Header** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.summary-row-2)<br>[[intseq]](intseq "21.2 Compile-time integer sequences") | Integer sequences | <utility> |
|
||||
| [ð](#tab:meta.summary-row-3)<br>[[type.traits]](type.traits "21.3 Metaprogramming and type traits") | Type traits | <type_traits> |
|
||||
| [ð](#tab:meta.summary-row-4)<br>[[meta.reflection]](meta.reflection "21.4 Reflection") | Reflection | <meta> |
|
||||
| [ð](#tab:meta.summary-row-5)<br>[[ratio]](ratio "21.5 Compile-time rational arithmetic") | Rational arithmetic | <ratio> |
|
||||
20
cppdraft/meta/help.md
Normal file
20
cppdraft/meta/help.md
Normal file
@@ -0,0 +1,20 @@
|
||||
[meta.help]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.help)
|
||||
|
||||
### 21.3.4 Helper classes [meta.help]
|
||||
|
||||
[ð](#lib:value_type,integral_constant)
|
||||
|
||||
namespace std {template<class T, T v> struct [integral_constant](#lib:integral_constant "21.3.4 Helper classes [meta.help]") {static constexpr T value = v; using value_type = T; using type = integral_constant<T, v>; constexpr operator value_type() const noexcept { return value; }constexpr value_type operator()() const noexcept { return value; }};}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L643)
|
||||
|
||||
The class template integral_constant,
|
||||
alias template bool_constant, and
|
||||
its associated [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s*true_type and false_type are used as base classes to define
|
||||
the interface for various type traits[.](#1.sentence-1)
|
||||
160
cppdraft/meta/logical.md
Normal file
160
cppdraft/meta/logical.md
Normal file
@@ -0,0 +1,160 @@
|
||||
[meta.logical]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.logical)
|
||||
|
||||
### 21.3.10 Logical operator traits [meta.logical]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2616)
|
||||
|
||||
This subclause describes type traits for applying logical operators
|
||||
to other type traits[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:conjunction)
|
||||
|
||||
`template<class... B> struct conjunction : see below { };
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2626)
|
||||
|
||||
The class template conjunction forms the logical conjunction of its template type arguments[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2630)
|
||||
|
||||
For a specialization conjunction<B1, …, BN>,
|
||||
if there is a template type argument Bi for which bool(Bi::value) is false,
|
||||
then instantiating conjunction<B1, …, BN>::value does not require the instantiation of Bj::value for j>i[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This is analogous to the short-circuiting behavior of
|
||||
the built-in operator &&[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2641)
|
||||
|
||||
Every template type argument
|
||||
for which Bi::value is instantiated
|
||||
shall be usable as a base class and
|
||||
shall have a member value which
|
||||
is convertible to bool,
|
||||
is not hidden, and
|
||||
is unambiguously available in the type[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2650)
|
||||
|
||||
The specialization conjunction<B1, …, BN> has a public and unambiguous base that is either
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
the first type Bi in the list true_type, B1, …, BN for which bool(Bi::value) is false, or
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
if there is no such Bi, the last type in the list[.](#5.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
This means a specialization of conjunction does not necessarily inherit from
|
||||
either true_type or false_type[.](#5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2666)
|
||||
|
||||
The member names of the base class, other than conjunction andoperator=, shall not be hidden and shall be unambiguously available
|
||||
in conjunction[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:disjunction)
|
||||
|
||||
`template<class... B> struct disjunction : see below { };
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2678)
|
||||
|
||||
The class template disjunction forms the logical disjunction of its template type arguments[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2682)
|
||||
|
||||
For a specialization disjunction<B1, …, BN>,
|
||||
if there is a template type argument Bi for which bool(Bi::value) is true,
|
||||
then instantiating disjunction<B1, …, BN>::value does not require the instantiation of Bj::value for j>i[.](#8.sentence-1)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
This is analogous to the short-circuiting behavior of
|
||||
the built-in operator ||[.](#8.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2693)
|
||||
|
||||
Every template type argument
|
||||
for which Bi::value is instantiated
|
||||
shall be usable as a base class and
|
||||
shall have a member value which
|
||||
is convertible to bool,
|
||||
is not hidden, and
|
||||
is unambiguously available in the type[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2702)
|
||||
|
||||
The specialization disjunction<B1, …, BN> has a public and unambiguous base that is either
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
the first type Bi in the list false_type, B1, …, BN for which bool(Bi::value) is true, or
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
if there is no such Bi, the last type in the list[.](#10.sentence-1)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
This means a specialization of disjunction does not necessarily inherit from
|
||||
either true_type or false_type[.](#10.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2716)
|
||||
|
||||
The member names of the base class,
|
||||
other than disjunction and operator=,
|
||||
shall not be hidden and shall be unambiguously available in disjunction[.](#11.sentence-1)
|
||||
|
||||
[ð](#lib:negation)
|
||||
|
||||
`template<class B> struct negation : see below { };
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2728)
|
||||
|
||||
The class template negation forms the logical negation of its template type argument[.](#12.sentence-1)
|
||||
|
||||
The type negation<B> is a [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") with a base characteristic of bool_constant<!bool(B::value)>[.](#12.sentence-2)
|
||||
61
cppdraft/meta/member.md
Normal file
61
cppdraft/meta/member.md
Normal file
@@ -0,0 +1,61 @@
|
||||
[meta.member]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.member)
|
||||
|
||||
### 21.3.11 Member relationships [meta.member]
|
||||
|
||||
[ð](#lib:is_pointer_interconvertible_with_class)
|
||||
|
||||
`template<class S, class M>
|
||||
constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2744)
|
||||
|
||||
*Mandates*: S is a complete type[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2748)
|
||||
|
||||
*Returns*: true if and only if S is a standard-layout type, M is an object type, m is not null,
|
||||
and each object s of type S is pointer-interconvertible ([[basic.compound]](basic.compound "6.9.4 Compound types"))
|
||||
with its subobject s.*m[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:is_corresponding_member)
|
||||
|
||||
`template<class S1, class S2, class M1, class M2>
|
||||
constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2766)
|
||||
|
||||
*Mandates*: S1 and S2 are complete types[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2770)
|
||||
|
||||
*Returns*: true if and only if S1 and S2 are standard-layout struct ([[class.prop]](class.prop "11.2 Properties of classes")) types, M1 and M2 are object types, m1 and m2 are not null,
|
||||
and m1 and m2 point to corresponding members of
|
||||
the common initial sequence ([[class.mem]](class.mem "11.4 Class members")) of S1 and S2[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2780)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The type of a pointer-to-member expression &C::b is not always a pointer to member of C,
|
||||
leading to potentially surprising results
|
||||
when using these functions in conjunction with inheritance[.](#5.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*: struct A { int a; }; // a standard-layout classstruct B { int b; }; // a standard-layout classstruct C: public A, public B { }; // not a standard-layout classstatic_assert( is_pointer_interconvertible_with_class( &C::b ) ); // Succeeds because, despite its appearance, &C::b has type// âpointer to member of B of type int''.static_assert( is_pointer_interconvertible_with_class<C>( &C::b ) ); // Forces the use of class C, and fails.static_assert( is_corresponding_member( &C::a, &C::b ) ); // Succeeds because, despite its appearance, &C::a and &C::b have types// âpointer to member of A of type int'' and// âpointer to member of B of type int'', respectively.static_assert( is_corresponding_member<C, C>( &C::a, &C::b ) ); // Forces the use of class C, and fails. â *end example*]
|
||||
|
||||
â *end note*]
|
||||
3708
cppdraft/meta/reflection.md
Normal file
3708
cppdraft/meta/reflection.md
Normal file
File diff suppressed because one or more lines are too long
218
cppdraft/meta/reflection/access/context.md
Normal file
218
cppdraft/meta/reflection/access/context.md
Normal file
@@ -0,0 +1,218 @@
|
||||
[meta.reflection.access.context]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#access.context)
|
||||
|
||||
### 21.4.8 Access control context [meta.reflection.access.context]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L4997)
|
||||
|
||||
The access_context class is a non-aggregate type
|
||||
that represents a namespace, class, or function
|
||||
from which queries pertaining to access rules may be performed,
|
||||
as well as the designating class ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members")), if any[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5004)
|
||||
|
||||
An access_context has an associated scope and designating class[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:access_context_)
|
||||
|
||||
namespace std::meta {struct access_context { access_context() = delete; consteval info scope() const; consteval info designating_class() const; static consteval access_context current() noexcept; static consteval access_context unprivileged() noexcept; static consteval access_context unchecked() noexcept; consteval access_context via(info cls) const; };}
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5024)
|
||||
|
||||
access_context is a structural type[.](#3.sentence-1)
|
||||
|
||||
Two values ac1 and ac2 of type access_context are template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence"))
|
||||
if ac1.scope() and ac2.scope() are template-argument-equivalent
|
||||
and ac1.designating_class() and ac2.designating_class() are template-argument-equivalent[.](#3.sentence-2)
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`consteval info [scope](#lib:access_context,scope "21.4.8 Access control context [meta.reflection.access.context]")() const;
|
||||
consteval info [designating_class](#lib:access_context,designating_class "21.4.8 Access control context [meta.reflection.access.context]")() const;
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5039)
|
||||
|
||||
*Returns*: The access_context's associated scope
|
||||
and designating class, respectively[.](#4.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`static consteval access_context [current](#lib:access_context,current "21.4.8 Access control context [meta.reflection.access.context]")() noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5050)
|
||||
|
||||
Given a program point P,
|
||||
let *eval-point*(P) be the following program point:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If a potentially-evaluated subexpression ([[intro.execution]](intro.execution "6.10.1 Sequential execution"))
|
||||
of a default member initializer I for a member of class C ([[class.mem.general]](class.mem.general "11.4.1 General"))
|
||||
appears at P,
|
||||
then a point determined as follows:
|
||||
* [(5.1.1)](#5.1.1)
|
||||
|
||||
If an aggregate initialization is using I, *eval-point*(Q),
|
||||
where Q is the point at which that aggregate initialization appears[.](#5.1.1.sentence-1)
|
||||
|
||||
* [(5.1.2)](#5.1.2)
|
||||
|
||||
Otherwise, if an initialization
|
||||
by an inherited constructor ([[class.inhctor.init]](class.inhctor.init "11.9.4 Initialization by inherited constructor")) is using I,
|
||||
a point whose immediate scope is the class scope corresponding to C[.](#5.1.2.sentence-1)
|
||||
|
||||
* [(5.1.3)](#5.1.3)
|
||||
|
||||
Otherwise, a point whose immediate scope
|
||||
is the function parameter scope
|
||||
corresponding to the constructor definition that is using I[.](#5.1.3.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
Otherwise, if a potentially-evaluated subexpression
|
||||
of a default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")) appears at P, *eval-point*(Q),
|
||||
where Q is the point at which the invocation of the function ([[expr.call]](expr.call "7.6.1.3 Function call"))
|
||||
using that default argument appears[.](#5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
Otherwise, if the immediate scope of P is a function parameter scope introduced by a declaration D,
|
||||
and P appears either before the locus of D or within the trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of D,
|
||||
a point whose immediate scope is the innermost scope enclosing the locus of D that is not a template parameter scope[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
Otherwise, if the immediate scope of P is a function parameter scope
|
||||
introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") L whose [*lambda-introducer*](expr.prim.lambda.general#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") appears at point Q,
|
||||
and P appears either within the [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") or the trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of L, *eval-point*(Q)[.](#5.4.sentence-1)
|
||||
|
||||
- [(5.5)](#5.5)
|
||||
|
||||
Otherwise, if the innermost non-block scope enclosing P is the function parameter scope
|
||||
introduced by a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")),
|
||||
a point whose immediate scope is that inhabited
|
||||
by the outermost [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]") D containing P such that each scope (if any) that intervenes between P and the function parameter scope introduced by D is either
|
||||
* [(5.5.1)](#5.5.1)
|
||||
|
||||
a block scope or
|
||||
|
||||
* [(5.5.2)](#5.5.2)
|
||||
|
||||
a function parameter scope or lambda scope
|
||||
introduced by a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]")[.](#5.5.sentence-1)
|
||||
|
||||
- [(5.6)](#5.6)
|
||||
|
||||
Otherwise, P[.](#5.6.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5114)
|
||||
|
||||
Given a scope S,
|
||||
let *ctx-scope*(S) be the following scope:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If S is a class scope or namespace scope, S[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
Otherwise, if S is a function parameter scope
|
||||
introduced by the declaration of a function, S[.](#6.2.sentence-1)
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
Otherwise, if S is a lambda scope
|
||||
introduced by a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") L,
|
||||
the function parameter scope
|
||||
corresponding to the call operator of the closure type of L[.](#6.3.sentence-1)
|
||||
|
||||
- [(6.4)](#6.4)
|
||||
|
||||
Otherwise, *ctx-scope*(Sâ²),
|
||||
where Sâ² is the parent scope of S[.](#6.4.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5135)
|
||||
|
||||
*Returns*: An access_context whose designating class is the null reflection
|
||||
and whose scope represents the function, class, or namespace
|
||||
whose corresponding function parameter scope, class scope, or namespace scope, respectively,
|
||||
is *ctx-scope*(S),
|
||||
where S is the immediate scope of *eval-point*(P) and P is the point at which the invocation of current lexically appears[.](#7.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*: struct A {int a = 0; consteval A(int p) : a(p) {}};struct B : A {using A::A; consteval B(int p, int q) : A(p * q) {} info s = access_context::current().scope();};struct C : B { using B::B; };
|
||||
|
||||
struct Agg {consteval bool eq(info rhs = access_context::current().scope()) {return s == rhs; } info s = access_context::current().scope();};
|
||||
|
||||
namespace NS {static_assert(Agg{}.s == access_context::current().scope()); // OKstatic_assert(Agg{}.eq()); // OKstatic_assert(B(1).s == ^^B); // OKstatic_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B); // OKstatic_assert(is_constructor(C{1, 2}.s) && parent_of(C{1, 2}.s) == ^^B); // OKauto fn() -> [:is_namespace(access_context::current().scope()) ? ^^int : ^^bool:]; static_assert(type_of(^^fn) == ^^auto()->int); // OKtemplate<auto R>struct TCls {consteval bool fn()requires (is_type(access_context::current().scope())) {return true; // OK, scope is TCls<R>.}}; static_assert(TCls<0>{}.fn()); // OK} â *end example*]
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5185)
|
||||
|
||||
*Remarks*: current is not an addressable function ([[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"))[.](#8.sentence-1)
|
||||
|
||||
An invocation of current that appears at a program point P is value-dependent ([[temp.dep.constexpr]](temp.dep.constexpr "13.8.3.4 Value-dependent expressions"))
|
||||
if *eval-point*(P) is enclosed by a scope
|
||||
corresponding to a templated entity[.](#8.sentence-2)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`static consteval access_context [unprivileged](#lib:access_context,unprivileged "21.4.8 Access control context [meta.reflection.access.context]")() noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5199)
|
||||
|
||||
*Returns*: An access_context whose designating class is the null reflection
|
||||
and whose scope is the global namespace[.](#9.sentence-1)
|
||||
|
||||
[ð](#itemdecl:4)
|
||||
|
||||
`static consteval access_context [unchecked](#lib:access_context,unchecked "21.4.8 Access control context [meta.reflection.access.context]")() noexcept;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5210)
|
||||
|
||||
*Returns*: An access_context whose designating class and scope
|
||||
are both the null reflection[.](#10.sentence-1)
|
||||
|
||||
[ð](#itemdecl:5)
|
||||
|
||||
`static consteval access_context [via](#lib:access_context,via "21.4.8 Access control context [meta.reflection.access.context]")(info cls) const;
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5221)
|
||||
|
||||
*Returns*: An access_context whose scope is this->scope() and whose designating class is cls[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5226)
|
||||
|
||||
*Throws*: meta::exception unlesscls is either the null reflection
|
||||
or a reflection of a complete class type[.](#12.sentence-1)
|
||||
182
cppdraft/meta/reflection/access/queries.md
Normal file
182
cppdraft/meta/reflection/access/queries.md
Normal file
@@ -0,0 +1,182 @@
|
||||
[meta.reflection.access.queries]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#access.queries)
|
||||
|
||||
### 21.4.9 Member accessibility queries [meta.reflection.access.queries]
|
||||
|
||||
[ð](#lib:is_accessible)
|
||||
|
||||
`consteval bool is_accessible(info r, access_context ctx);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5241)
|
||||
|
||||
Let *PARENT-CLS*(r) be:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
If parent_of(r) represents a class C, then C[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
Otherwise, *PARENT-CLS*(parent_of(r))[.](#1.2.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5248)
|
||||
|
||||
Let *DESIGNATING-CLS*(r, ctx) be:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
If ctx.designating_class() represents a class C, then C[.](#2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
Otherwise, *PARENT-CLS*(r)[.](#2.2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5255)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
If r represents an unnamed bit-field F,
|
||||
then is_accessible(rH, ctx),
|
||||
where rH represents a hypothetical non-static data member
|
||||
of the class represented by *PARENT-CLS*(r) with the same access as F[.](#3.1.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
Unnamed bit-fields are treated as class members
|
||||
for the purpose of is_accessible[.](#3.1.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
Otherwise, if r does not represent a class member
|
||||
or a direct base class relationship,
|
||||
then true[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
Otherwise, if r represents
|
||||
* [(3.3.1)](#3.3.1)
|
||||
|
||||
a class member that is not a (possibly indirect or variant)
|
||||
member of *DESIGNATING-CLS*(r, ctx) or
|
||||
|
||||
* [(3.3.2)](#3.3.2)
|
||||
|
||||
a direct base class relationship such that parent_of(r) does not represent *DESIGNATING-CLS*(r, ctx) or a (direct or indirect) base class thereof,
|
||||
|
||||
then false[.](#3.3.sentence-1)
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
Otherwise, if ctx.scope() is the null reflection,
|
||||
then true[.](#3.4.sentence-1)
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
Otherwise, letting P be a program point whose immediate scope is the
|
||||
function parameter scope, class scope, or namespace scope
|
||||
corresponding to the
|
||||
function, class, or namespace
|
||||
represented by ctx.scope():
|
||||
* [(3.5.1)](#3.5.1)
|
||||
|
||||
If r represents a direct base class relationship (D,B),
|
||||
then true if base class B of *DESIGNATING-CLS*(r, ctx) is accessible at P ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members"));
|
||||
otherwise false[.](#3.5.1.sentence-1)
|
||||
|
||||
* [(3.5.2)](#3.5.2)
|
||||
|
||||
Otherwise, r represents a class member M; true if M would be accessible at P with the designating class ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members")) as *DESIGNATING-CLS*(r, ctx) if the effect of any [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]")*s* ([[namespace.udecl]](namespace.udecl "9.10 The using declaration")) were ignored[.](#3.5.2.sentence-1)
|
||||
Otherwise, false[.](#3.5.2.sentence-2)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The definitions of when a class member or base class is accessible from a point P do not consider whether a declaration of that entity is reachable from P[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [1](#example-1)*: consteval access_context fn() {return access_context::current();}class Cls {int mem; friend consteval access_context fn();public:static constexpr auto r = ^^mem;};
|
||||
|
||||
static_assert(is_accessible(Cls::r, fn())); // OKstatic_assert(!is_accessible(Cls::r, access_context::current())); // OKstatic_assert(is_accessible(Cls::r, access_context::unchecked())); // OK â *end example*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5330)
|
||||
|
||||
*Throws*: meta::exception if
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
r represents a class member
|
||||
for which *PARENT-CLS*(r) is an incomplete class or
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
r represents a direct base class relationship (D,B) for which D is incomplete[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:has_inaccessible_nonstatic_data_members)
|
||||
|
||||
`consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5349)
|
||||
|
||||
*Returns*: true if is_accessible(R, ctx) is false for any R in nonstatic_data_members_of(r, access_context::unchecked())[.](#5.sentence-1)
|
||||
|
||||
Otherwise, false[.](#5.sentence-2)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5355)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
nonstatic_data_members_of(r, access_context::unchecked()) is a constant subexpression and
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
r does not represent a closure type[.](#6.sentence-1)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`consteval bool has_inaccessible_bases(info r, access_context ctx);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5372)
|
||||
|
||||
*Returns*: true if is_accessible(R, ctx) is false for any R in bases_of(r, access_context::unchecked())[.](#7.sentence-1)
|
||||
|
||||
Otherwise, false[.](#7.sentence-2)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5378)
|
||||
|
||||
*Throws*: meta::exception unlessbases_of(r, access_context::unchecked()) is a constant subexpression[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:has_inaccessible_subobjects)
|
||||
|
||||
`consteval bool has_inaccessible_subobjects(info r, access_context ctx);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5391)
|
||||
|
||||
*Effects*: Equivalent to:return has_inaccessible_bases(r, ctx) || has_inaccessible_nonstatic_data_members(r, ctx);
|
||||
103
cppdraft/meta/reflection/annotation.md
Normal file
103
cppdraft/meta/reflection/annotation.md
Normal file
@@ -0,0 +1,103 @@
|
||||
[meta.reflection.annotation]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#annotation)
|
||||
|
||||
### 21.4.18 Annotation reflection [meta.reflection.annotation]
|
||||
|
||||
[ð](#lib:annotations_of)
|
||||
|
||||
`consteval vector<info> annotations_of(info item);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6930)
|
||||
|
||||
Let E be
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
the corresponding [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]") if item represents a direct base class relationship,
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise, the entity represented by item[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6940)
|
||||
|
||||
*Returns*: A vector containing all of the reflections R representing each annotation applying to each declaration of E that precedes either
|
||||
some point in the evaluation context ([[expr.const]](expr.const "7.7 Constant expressions")) or
|
||||
a point immediately following the [*class-specifier*](class.pre#nt:class-specifier "11.1 Preamble [class.pre]") of the outermost class for which such a point is in a complete-class context[.](#2.sentence-1)
|
||||
|
||||
For any two reflections R1 and R2 in the returned vector,
|
||||
if the annotation represented by R1 precedes the annotation represented by R2,
|
||||
then R1 appears before R2[.](#2.sentence-2)
|
||||
|
||||
If R1 and R2 represent annotations from the same translation unit T,
|
||||
any element in the returned vector between R1 and R2 represents an annotation from T[.](#2.sentence-3)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The order in which two annotations appear is otherwise unspecified[.](#2.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [1](#example-1)*: [[=1]] void f();[[=2, =3]] void g();void g [[=4]] ();
|
||||
|
||||
static_assert(annotations_of(^^f).size() == 1);static_assert(annotations_of(^^g).size() == 3);static_assert([: constant_of(annotations_of(^^g)[0]) :] == 2);static_assert(extract<int>(annotations_of(^^g)[1]) == 3);static_assert(extract<int>(annotations_of(^^g)[2]) == 4);
|
||||
|
||||
struct Option { bool value; };
|
||||
|
||||
struct C {[[=Option{true}]] int a; [[=Option{false}]] int b;};
|
||||
|
||||
static_assert(extract<Option>(annotations_of(^^C::a)[0]).value);static_assert(!extract<Option>(annotations_of(^^C::b)[0]).value);
|
||||
|
||||
template<class T>struct [[=42]] D { };
|
||||
|
||||
constexpr std::meta::info a1 = annotations_of(^^D<int>)[0];constexpr std::meta::info a2 = annotations_of(^^D<char>)[0];static_assert(a1 != a2);static_assert(constant_of(a1) == constant_of(a2));
|
||||
|
||||
[[=1]] int x, y;static_assert(annotations_of(^^x)[0] == annotations_of(^^y)[0]); â *end example*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6991)
|
||||
|
||||
*Throws*: meta::exception unlessitem represents a
|
||||
type,
|
||||
type alias,
|
||||
variable,
|
||||
function,
|
||||
namespace,
|
||||
enumerator,
|
||||
direct base class relationship, or
|
||||
non-static data member[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:annotations_of_with_type)
|
||||
|
||||
`consteval vector<info> annotations_of_with_type(info item, info type);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L7011)
|
||||
|
||||
*Returns*: A vector containing each element e of annotations_of(item) whereremove_const(type_of(e)) == remove_const(type) is true, preserving their order[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L7020)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
annotations_of(item) is a constant expression and
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
dealias(type) represents a type that is complete
|
||||
from some point in the evaluation context[.](#5.sentence-1)
|
||||
128
cppdraft/meta/reflection/array.md
Normal file
128
cppdraft/meta/reflection/array.md
Normal file
@@ -0,0 +1,128 @@
|
||||
[meta.reflection.array]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#array)
|
||||
|
||||
### 21.4.15 Promoting to static storage arrays [meta.reflection.array]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6201)
|
||||
|
||||
The functions in this subclause promote compile-time storage into static storage[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:reflect_constant_string)
|
||||
|
||||
`template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||||
consteval info reflect_constant_string(R&& r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6211)
|
||||
|
||||
Let CharT be ranges::range_value_t<R>[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6214)
|
||||
|
||||
*Mandates*: CharT is one ofchar,wchar_t,char8_t,char16_t,char32_t[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6223)
|
||||
|
||||
Let V be the pack of values of type CharT whose elements are the corresponding elements of r,
|
||||
except that if r refers to a string literal object,
|
||||
then V does not include the trailing null terminator of r[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6229)
|
||||
|
||||
Let P be the template parameter object ([[temp.param]](temp.param "13.2 Template parameters"))
|
||||
of type const CharT[sizeof...(V) + 1] initialized with {V..., CharT()}[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6234)
|
||||
|
||||
*Returns*: ^^P[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6238)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
P is a potentially non-unique object ([[intro.object]](intro.object "6.8.2 Object model"))[.](#7.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:reflect_constant_array)
|
||||
|
||||
`template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R>
|
||||
consteval info reflect_constant_array(R&& r);
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6251)
|
||||
|
||||
Let T be ranges::range_value_t<R>[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6254)
|
||||
|
||||
*Mandates*: T is a structural type ([[temp.param]](temp.param "13.2 Template parameters")),is_constructible_v<T, ranges::range_reference_t<R>> is true, andis_copy_constructible_v<T> is true[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6260)
|
||||
|
||||
Let V be the pack of values of type info of the same size as r,
|
||||
where the ith element is reflect_constant(ei),
|
||||
where ei is the ith element of r[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6266)
|
||||
|
||||
Let P be
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
If sizeof...(V) > 0 is true,
|
||||
then the template parameter object ([[temp.param]](temp.param "13.2 Template parameters"))
|
||||
of type const T[sizeof...(V)] initialized with {[:V:]...}[.](#11.1.sentence-1)
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
Otherwise, the template parameter object
|
||||
of type array<T, 0> initialized with {}[.](#11.2.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6280)
|
||||
|
||||
*Returns*: ^^P[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6284)
|
||||
|
||||
*Throws*: meta::exception unlessreflect_constant(e) is a constant subexpression
|
||||
for every element e of r[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6290)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
P is a potentially non-unique object ([[intro.object]](intro.object "6.8.2 Object model"))[.](#14.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
302
cppdraft/meta/reflection/define/aggregate.md
Normal file
302
cppdraft/meta/reflection/define/aggregate.md
Normal file
@@ -0,0 +1,302 @@
|
||||
[meta.reflection.define.aggregate]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#define.aggregate)
|
||||
|
||||
### 21.4.16 Reflection class definition generation [meta.reflection.define.aggregate]
|
||||
|
||||
[ð](#lib:data_member_options)
|
||||
|
||||
namespace std::meta {struct data_member_options {struct *name-type* { // *exposition only*template<class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<u8string, T>consteval *name-type*(T&&); template<class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<string, T>consteval *name-type*(T&&); private: variant<u8string, string> *contents*; // *exposition only*};
|
||||
|
||||
optional<*name-type*> name;
|
||||
optional<int> alignment;
|
||||
optional<int> bit_width; bool no_unique_address = false; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6323)
|
||||
|
||||
The classes data_member_options and data_member_options::*name-type* are consteval-only types ([[basic.types.general]](basic.types.general "6.9.1 General")),
|
||||
and are not structural types ([[temp.param]](temp.param "13.2 Template parameters"))[.](#1.sentence-1)
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`template<class T>
|
||||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<u8string, T>
|
||||
consteval name-type(T&& value);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6336)
|
||||
|
||||
*Effects*: Initializes *contents* with u8string(std::forward<T>(value))[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`template<class T>
|
||||
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<string, T>
|
||||
consteval name-type(T&& value);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6349)
|
||||
|
||||
*Effects*: Initializes *contents* with string(std::forward<T>(value))[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The class *name-type* allows
|
||||
the function data_member_spec to accept
|
||||
an ordinary string literal (or string_view, string, etc[.](#3.sentence-2))
|
||||
|
||||
or a UTF-8 string literal (or u8string_view, u8string, etc[.](#3.sentence-3))
|
||||
|
||||
equally well[.](#3.sentence-4)
|
||||
|
||||
[*Example [1](#example-1)*: consteval void fn() { data_member_options o1 = {.name = "ordinary_literal_encoding"};
|
||||
data_member_options o2 = {.name = u8"utf8_encoding"};} â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:data_member_spec)
|
||||
|
||||
`consteval info data_member_spec(info type, data_member_options options);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6376)
|
||||
|
||||
*Returns*: A reflection of a data member description(T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")) where
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
T is the type represented by dealias(type),
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
N is either the identifier encoded by options.name or ⥠if options.name does not contain a value,
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
A is either the alignment value held by options.alignment or ⥠if options.alignment does not contain a value,
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
W is either the value held by options.bit_width or ⥠if options.bit_width does not contain a value, and
|
||||
|
||||
- [(4.5)](#4.5)
|
||||
|
||||
NUA is the value held by options.no_unique_address[.](#4.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The returned reflection value is primarily useful
|
||||
in conjunction with define_aggregate;
|
||||
it can also be queried by certain other functions in std::meta (e.g., type_of, identifier_of)[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6402)
|
||||
|
||||
*Throws*: meta::exception unless the following conditions are met:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
dealias(type) represents either an object type or a reference type;
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
if options.name contains a value, then:
|
||||
* [(5.2.1)](#5.2.1)
|
||||
|
||||
holds_alternative<u8string>(options.name->*contents*) is true and get<u8string>(options.name->*contents*) contains a valid identifier ([[lex.name]](lex.name "5.11 Identifiers"))
|
||||
that is not a keyword ([[lex.key]](lex.key "5.12 Keywords"))
|
||||
when interpreted with UTF-8, or
|
||||
|
||||
* [(5.2.2)](#5.2.2)
|
||||
|
||||
holds_alternative<string>(options.name->*contents*) is true and get<string>(options.name->*contents*) contains a valid identifier ([[lex.name]](lex.name "5.11 Identifiers"))
|
||||
that is not a keyword ([[lex.key]](lex.key "5.12 Keywords"))
|
||||
when interpreted with the ordinary literal encoding;
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
The name corresponds to the spelling of an identifier token
|
||||
after phase 6 of translation ([[lex.phases]](lex.phases "5.2 Phases of translation"))[.](#5.2.sentence-1)
|
||||
Lexical constructs like [*universal-character-name*](lex.universal.char#nt:universal-character-name "5.3.2 Universal character names [lex.universal.char]")*s* ([[lex.universal.char]](lex.universal.char "5.3.2 Universal character names")) are not processed
|
||||
and will cause evaluation to fail[.](#5.2.sentence-2)
|
||||
For example, R"(\u03B1)" is an invalid identifier
|
||||
and is not interpreted as "α"[.](#5.2.sentence-3)
|
||||
â *end note*]
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
if options.name does not contain a value,
|
||||
then options.bit_width contains a value;
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
if options.bit_width contains a value V, then
|
||||
* [(5.4.1)](#5.4.1)
|
||||
|
||||
is_integral_type(type) || is_enum_type(type) is true,
|
||||
|
||||
* [(5.4.2)](#5.4.2)
|
||||
|
||||
options.alignment does not contain a value,
|
||||
|
||||
* [(5.4.3)](#5.4.3)
|
||||
|
||||
options.no_unique_address is false, and
|
||||
|
||||
* [(5.4.4)](#5.4.4)
|
||||
|
||||
if V equals 0,
|
||||
then options.name does not contain a value; and
|
||||
|
||||
- [(5.5)](#5.5)
|
||||
|
||||
if options.alignment contains a value,
|
||||
it is an alignment value ([[basic.align]](basic.align "6.8.3 Alignment"))
|
||||
not less than alignment_of(type)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:is_data_member_spec)
|
||||
|
||||
`consteval bool is_data_member_spec(info r);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6462)
|
||||
|
||||
*Returns*: true if r represents a data member description[.](#6.sentence-1)
|
||||
|
||||
Otherwise, false[.](#6.sentence-2)
|
||||
|
||||
[ð](#lib:define_aggregate)
|
||||
|
||||
`template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>
|
||||
consteval info define_aggregate(info class_type, R&& mdescrs);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6475)
|
||||
|
||||
Let C be the class represented by class_type and rK be the Kth reflection value in mdescrs[.](#7.sentence-1)
|
||||
|
||||
For every rK in mdescrs,
|
||||
let (TK,NK,AK,WK,NUAK) be
|
||||
the corresponding data member description represented by rK[.](#7.sentence-2)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6482)
|
||||
|
||||
*Constant When*:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
C is incomplete from every point in the evaluation context;
|
||||
[*Note [4](#note-4)*:
|
||||
C can be a class template specialization
|
||||
for which there is a reachable definition of the class template[.](#8.1.sentence-1)
|
||||
In this case,
|
||||
the injected declaration is an explicit specialization[.](#8.1.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
is_data_member_spec(rK) is true for every rK;
|
||||
|
||||
- [(8.3)](#8.3)
|
||||
|
||||
is_complete_type(TK) is true for every rK; and
|
||||
|
||||
- [(8.4)](#8.4)
|
||||
|
||||
for every pair (rK,rL) where K<L,
|
||||
if NK is not ⥠and NL is not â¥,
|
||||
then either:
|
||||
* [(8.4.1)](#8.4.1)
|
||||
|
||||
NK != NL is true or
|
||||
|
||||
* [(8.4.2)](#8.4.2)
|
||||
|
||||
NK == u8"_" is true[.](#8.sentence-1)
|
||||
[*Note [5](#note-5)*:
|
||||
Every provided identifier is unique or "_"[.](#8.4.2.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6512)
|
||||
|
||||
*Effects*: Produces an injected declaration D ([[expr.const]](expr.const "7.7 Constant expressions"))
|
||||
that defines C and has properties as follows:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
The target scope of D is the scope to which C belongs ([[basic.scope.scope]](basic.scope.scope "6.4.1 General"))[.](#9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
The locus of D follows immediately after the core constant expression
|
||||
currently under evaluation[.](#9.2.sentence-1)
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
The characteristic sequence of D ([[expr.const]](expr.const "7.7 Constant expressions"))
|
||||
is the sequence of reflection values rK[.](#9.3.sentence-1)
|
||||
|
||||
- [(9.4)](#9.4)
|
||||
|
||||
If C is a specialization of a templated class T,
|
||||
and C is not a local class,
|
||||
then D is an explicit specialization of T[.](#9.4.sentence-1)
|
||||
|
||||
- [(9.5)](#9.5)
|
||||
|
||||
For each rK,
|
||||
there is a corresponding entity MK belonging to the class scope of D with the following properties:
|
||||
* [(9.5.1)](#9.5.1)
|
||||
|
||||
If NK is â¥, MK is an unnamed bit-field[.](#9.5.1.sentence-1)
|
||||
Otherwise, MK is a non-static data member whose name is the identifier
|
||||
determined by the character sequence encoded by NK in UTF-8[.](#9.5.1.sentence-2)
|
||||
|
||||
* [(9.5.2)](#9.5.2)
|
||||
|
||||
The type of MK is TK[.](#9.5.2.sentence-1)
|
||||
|
||||
* [(9.5.3)](#9.5.3)
|
||||
|
||||
MK is declared with the attribute [[no_unique_address]] if and only if NUAK is true[.](#9.5.3.sentence-1)
|
||||
|
||||
* [(9.5.4)](#9.5.4)
|
||||
|
||||
If WK is not â¥, MK is a bit-field whose width is that value[.](#9.5.4.sentence-1)
|
||||
Otherwise, MK is not a bit-field[.](#9.5.4.sentence-2)
|
||||
|
||||
* [(9.5.5)](#9.5.5)
|
||||
|
||||
If AK is not â¥, MK has the [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") alignas(AK)[.](#9.5.5.sentence-1)
|
||||
Otherwise, MK has no [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#9.5.5.sentence-2)
|
||||
|
||||
- [(9.6)](#9.6)
|
||||
|
||||
For every rL in mdescrs such that K<L,
|
||||
the declaration corresponding to rK precedes the declaration corresponding to rL[.](#9.6.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6562)
|
||||
|
||||
*Returns*: class_type[.](#10.sentence-1)
|
||||
114
cppdraft/meta/reflection/exception.md
Normal file
114
cppdraft/meta/reflection/exception.md
Normal file
@@ -0,0 +1,114 @@
|
||||
[meta.reflection.exception]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#exception)
|
||||
|
||||
### 21.4.4 Class exception [meta.reflection.exception]
|
||||
|
||||
[ð](#lib:exception)
|
||||
|
||||
namespace std::meta {class exception : public std::exception {private: optional<string> *what_*; // *exposition only* u8string *u8what_*; // *exposition only* info *from_*; // *exposition only* source_location *where_*; // *exposition only*public:consteval exception(u8string_view what, info from,
|
||||
source_location where = source_location::current()) noexcept; consteval exception(string_view what, info from,
|
||||
source_location where = source_location::current()) noexcept;
|
||||
|
||||
exception(const exception&) = default;
|
||||
exception(exception&&) = default;
|
||||
|
||||
exception& operator=(const exception&) = default;
|
||||
exception& operator=(exception&&) = default; constexpr const char* what() const noexcept override; consteval u8string_view u8what() const noexcept; consteval info from() const noexcept; consteval source_location where() const noexcept; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3467)
|
||||
|
||||
Reflection functions throw exceptions of type meta::exception to signal an error[.](#1.sentence-1)
|
||||
|
||||
meta::exception is a consteval-only type[.](#1.sentence-2)
|
||||
|
||||
[ð](#lib:exception,constructor)
|
||||
|
||||
`consteval exception(u8string_view what, info from,
|
||||
source_location where = source_location::current()) noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3478)
|
||||
|
||||
*Effects*: Initializes*u8what_* with what,*from_* with from, and*where_* with where[.](#2.sentence-1)
|
||||
|
||||
If what can be represented in the ordinary literal encoding,
|
||||
initializes *what_* with what,
|
||||
transcoded from UTF-8 to the ordinary literal encoding[.](#2.sentence-2)
|
||||
|
||||
Otherwise, *what_* is value-initialized[.](#2.sentence-3)
|
||||
|
||||
[ð](#lib:exception,constructor_)
|
||||
|
||||
`consteval exception(string_view what, info from,
|
||||
source_location where = source_location::current()) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3496)
|
||||
|
||||
*Constant When*: what designates a sequence of characters
|
||||
that can be encoded in UTF-8[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3501)
|
||||
|
||||
*Effects*: Initializes*what_* with what,*u8what_* with what transcoded from the ordinary literal encoding to UTF-8,*from_* with from and*where_* with where[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:what,exception)
|
||||
|
||||
`constexpr const char* what() const noexcept override;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3517)
|
||||
|
||||
*Constant When*: *what_*.has_value() is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3521)
|
||||
|
||||
*Returns*: *what_*->c_str()[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:u8what,exception)
|
||||
|
||||
`consteval u8string_view u8what() const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3531)
|
||||
|
||||
*Returns*: *u8what_*[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:from,exception)
|
||||
|
||||
`consteval info from() const noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3541)
|
||||
|
||||
*Returns*: *from_*[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:where,exception)
|
||||
|
||||
`consteval source_location where() const noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3551)
|
||||
|
||||
*Returns*: *where_*[.](#9.sentence-1)
|
||||
182
cppdraft/meta/reflection/extract.md
Normal file
182
cppdraft/meta/reflection/extract.md
Normal file
@@ -0,0 +1,182 @@
|
||||
[meta.reflection.extract]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#extract)
|
||||
|
||||
### 21.4.12 Value extraction [meta.reflection.extract]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5837)
|
||||
|
||||
The extract function template may be used
|
||||
to extract a value out of a reflection when its type is known[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5841)
|
||||
|
||||
The following are defined for exposition only
|
||||
to aid in the specification of extract[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`template<class T>
|
||||
consteval T extract-ref(info r); // exposition only
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5851)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
T is a reference type[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5856)
|
||||
|
||||
*Returns*: If r represents an object O,
|
||||
then a reference to O[.](#4.sentence-1)
|
||||
|
||||
Otherwise, a reference to the object declared, or referred to,
|
||||
by the variable represented by r[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5863)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
r represents a variable or object of type U,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]> is true,
|
||||
and
|
||||
[*Note [2](#note-2)*:
|
||||
The intent is to allow only qualification conversion from U to T[.](#5.2.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
If r represents a variable,
|
||||
then either that variable is usable in constant expressions
|
||||
or its lifetime began within the core constant expression currently under evaluation[.](#5.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`template<class T>
|
||||
consteval T extract-member-or-function(info r); // exposition only
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5888)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If T is a pointer type,
|
||||
then a pointer value pointing to the function represented by r[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
Otherwise, a pointer-to-member value
|
||||
designating the non-static data member or function represented by r[.](#6.2.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5899)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
r represents a non-static data member with type X,
|
||||
that is not a bit-field,
|
||||
that is a direct member of class C, T and X C::* are similar types ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")), and is_convertible_v<X C::*, T> is true;
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
r represents an implicit object member function
|
||||
with type F or F noexcept that is a direct member of a class C,
|
||||
and T is F C::*; or
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
r represents a non-member function,
|
||||
static member function, or
|
||||
explicit object member function
|
||||
of function type F or F noexcept,
|
||||
and T is F*[.](#7.sentence-1)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`template<class T>
|
||||
consteval T extract-value(info r); // exposition only
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5929)
|
||||
|
||||
Let U be the type of the value or object that r represents[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5932)
|
||||
|
||||
*Returns*: static_cast<T>([:R:]),
|
||||
where R is a constant expression of type info such that R == r is true[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5938)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
U is a pointer type, T and U are either similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions"))
|
||||
or both function pointer types, and is_convertible_v<U, T> is true,
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
U is not a pointer type
|
||||
and the cv-unqualified types of T and U are the same,
|
||||
|
||||
- [(10.3)](#10.3)
|
||||
|
||||
U is an array type, T is a pointer type, and
|
||||
the value r represents is convertible to T, or
|
||||
|
||||
- [(10.4)](#10.4)
|
||||
|
||||
U is a closure type, T is a function pointer type, and
|
||||
the value that r represents is convertible to T[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:extract)
|
||||
|
||||
`template<class T>
|
||||
consteval T extract(info r);
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5968)
|
||||
|
||||
Let U be remove_cv_t<T>[.](#11.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5971)
|
||||
|
||||
*Effects*: Equivalent to:if constexpr (is_reference_type(^^T)) {return *extract-ref*<T>(r);} else if constexpr (is_nonstatic_data_member(r) || is_function(r)) {return *extract-member-or-function*<U>(r);} else {return *extract-value*<U>(constant_of(r));}
|
||||
229
cppdraft/meta/reflection/layout.md
Normal file
229
cppdraft/meta/reflection/layout.md
Normal file
@@ -0,0 +1,229 @@
|
||||
[meta.reflection.layout]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#layout)
|
||||
|
||||
### 21.4.11 Reflection layout queries [meta.reflection.layout]
|
||||
|
||||
[ð](#lib:member_offset)
|
||||
|
||||
`struct member_offset {
|
||||
ptrdiff_t bytes;
|
||||
ptrdiff_t bits;
|
||||
constexpr ptrdiff_t total_bits() const;
|
||||
auto operator<=>(const member_offset&) const = default;
|
||||
};
|
||||
|
||||
constexpr ptrdiff_t member_offset::total_bits() const;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5663)
|
||||
|
||||
*Returns*: bytes * CHAR_BIT + bits[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:offset_of)
|
||||
|
||||
`consteval member_offset offset_of(info r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5674)
|
||||
|
||||
Let V be the offset in bits from the beginning of a complete object
|
||||
of the type represented by parent_of(r) to the subobject associated with the entity represented by r[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5679)
|
||||
|
||||
*Returns*: {V / CHAR_BIT, V % CHAR_BIT}[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5683)
|
||||
|
||||
*Throws*: meta::exception unlessr represents a non-static data member,
|
||||
unnamed bit-field, or
|
||||
direct base class relationship (D,B) for which either B is not a virtual base class
|
||||
or D is not an abstract class[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:size_of)
|
||||
|
||||
`consteval size_t size_of(info r);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5699)
|
||||
|
||||
*Returns*: If r represents
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
a non-static data member of type T,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
a data member description (T,N,A,W,NUA), or
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
dealias(r) represents a type T,
|
||||
|
||||
then sizeof(T) if T is not a reference type
|
||||
and size_of(add_pointer(^^T)) otherwise[.](#5.sentence-1)
|
||||
|
||||
Otherwise, size_of(type_of(r))[.](#5.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
It is possible that while sizeof(char) == size_of(^^char) is true,
|
||||
that sizeof(char&) == size_of(^^char&) is false[.](#5.sentence-3)
|
||||
|
||||
If b represents a direct base class relationship of an empty base class,
|
||||
then size_of(b) > 0 is true[.](#5.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5719)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
all of the following conditions are met:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
dealias(r) is a reflection of a
|
||||
type,
|
||||
object,
|
||||
value,
|
||||
variable of non-reference type,
|
||||
non-static data member that is not a bit-field,
|
||||
direct base class relationship, or
|
||||
data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"))
|
||||
where W is not â¥[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
If dealias(r) represents a type,
|
||||
then is_complete_type(r) is true[.](#6.2.sentence-1)
|
||||
|
||||
[ð](#lib:alignment_of)
|
||||
|
||||
`consteval size_t alignment_of(info r);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5746)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
If dealias(r) represents a type T,
|
||||
then alignment_of(add_pointer(r)) if T is a reference type
|
||||
and the alignment requirement of T otherwise[.](#7.1.sentence-1)
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
Otherwise, if dealias(r) represents a variable or object,
|
||||
then the alignment requirement of the variable or object[.](#7.2.sentence-1)
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
Otherwise, if r represents a direct base class relationship,
|
||||
then alignment_of(type_of(r))[.](#7.3.sentence-1)
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
Otherwise, if r represents a non-static data member M of a class C,
|
||||
then the alignment of the direct member subobject
|
||||
corresponding to M of a complete object of type C[.](#7.4.sentence-1)
|
||||
|
||||
- [(7.5)](#7.5)
|
||||
|
||||
Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"))[.](#7.5.sentence-1)
|
||||
If A is not â¥,
|
||||
then the value A[.](#7.5.sentence-2)
|
||||
Otherwise, alignment_of(^^T)[.](#7.5.sentence-3)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5771)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
all of the following conditions are met:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
dealias(r) is a reflection of a
|
||||
type,
|
||||
object,
|
||||
variable of non-reference type,
|
||||
non-static data member that is not a bit-field,
|
||||
direct base class relationship, or
|
||||
data member description[.](#8.1.sentence-1)
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
If dealias(r) represents a type,
|
||||
then is_complete_type(r) is true[.](#8.2.sentence-1)
|
||||
|
||||
[ð](#lib:bit_size_of)
|
||||
|
||||
`consteval size_t bit_size_of(info r);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5796)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
If r represents
|
||||
an unnamed bit-field
|
||||
or a non-static data member that is a bit-field
|
||||
with width W,
|
||||
then W[.](#9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
Otherwise, if r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"))
|
||||
and W is not â¥,
|
||||
then W[.](#9.2.sentence-1)
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
Otherwise, CHAR_BIT * size_of(r)[.](#9.3.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5814)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
all of the following conditions are met:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
dealias(r) is a reflection of a
|
||||
type,
|
||||
object,
|
||||
value,
|
||||
variable of non-reference type,
|
||||
non-static data member,
|
||||
unnamed bit-field,
|
||||
direct base class relationship, or
|
||||
data member description[.](#10.1.sentence-1)
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
If dealias(r) represents a type T,
|
||||
there is a point within the evaluation context from which T is not incomplete[.](#10.2.sentence-1)
|
||||
268
cppdraft/meta/reflection/member/queries.md
Normal file
268
cppdraft/meta/reflection/member/queries.md
Normal file
@@ -0,0 +1,268 @@
|
||||
[meta.reflection.member.queries]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#member.queries)
|
||||
|
||||
### 21.4.10 Reflection member queries [meta.reflection.member.queries]
|
||||
|
||||
[ð](#lib:members_of)
|
||||
|
||||
`consteval vector<info> members_of(info r, access_context ctx);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5407)
|
||||
|
||||
A declaration D [*members-of-precedes*](#def:members-of-precedes) a point P if D precedes either P or the point immediately following the [*class-specifier*](class.pre#nt:class-specifier "11.1 Preamble [class.pre]") of the outermost class for which P is in a complete-class context[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5413)
|
||||
|
||||
A declaration D of a member M of a class or namespace Q is[*Q-members-of-eligible*](#def:Q-members-of-eligible) if
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
the host scope of D ([[basic.scope.scope]](basic.scope.scope "6.4.1 General"))
|
||||
is the class scope or namespace scope associated with Q,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
D is not a friend declaration,
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
M is not a closure type ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2 Closure types")),
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
M is not a specialization of a template ([[temp.pre]](temp.pre "13.1 Preamble")),
|
||||
|
||||
- [(2.5)](#2.5)
|
||||
|
||||
if Q is a class that is not a closure type,
|
||||
then M is a direct member of Q ([[class.mem.general]](class.mem.general "11.4.1 General"))
|
||||
that is not a variant member of a
|
||||
nested anonymous union of Q ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions")), and
|
||||
|
||||
- [(2.6)](#2.6)
|
||||
|
||||
if Q is a closure type,
|
||||
then M is a function call operator or function call operator template[.](#2.sentence-1)
|
||||
|
||||
It is implementation-defined
|
||||
whether declarations of other members of a closure type Q are Q-members-of-eligible[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5440)
|
||||
|
||||
A member M of a class or namespace Q is[*Q-members-of-representable*](#def:Q-members-of-representable) from a point P if a Q-members-of-eligible declaration of M members-of-precedes P,
|
||||
and M is
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
a class or enumeration type
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
a type alias
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
a class template, function template,
|
||||
variable template, alias template, or concept,
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
a variable or reference V for which the type of V does not contain an undeduced placeholder type,
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
a function F for which
|
||||
* [(3.5.1)](#3.5.1)
|
||||
|
||||
the type of F does not contain an undeduced placeholder type,
|
||||
|
||||
* [(3.5.2)](#3.5.2)
|
||||
|
||||
the constraints (if any) of F are satisfied, and
|
||||
|
||||
* [(3.5.3)](#3.5.3)
|
||||
|
||||
if F is a prospective destructor, F is the selected destructor ([[class.dtor]](class.dtor "11.4.7 Destructors")),
|
||||
|
||||
- [(3.6)](#3.6)
|
||||
|
||||
a non-static data member,
|
||||
|
||||
- [(3.7)](#3.7)
|
||||
|
||||
a namespace, or
|
||||
|
||||
- [(3.8)](#3.8)
|
||||
|
||||
a namespace alias[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Examples of direct members that are not Q-members-of-representable
|
||||
for any entity Q include:
|
||||
unscoped enumerators ([[enum]](enum "9.8 Enumerations")),
|
||||
partial specializations of templates ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")), and
|
||||
closure types ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2 Closure types"))[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5482)
|
||||
|
||||
*Returns*: A vector containing reflections of all members M of the entity Q represented by dealias(r) for which
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
M is Q-members-of-representable
|
||||
from some point in the evaluation context and
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
is_accessible(^^M, ctx) is true[.](#4.sentence-1)
|
||||
|
||||
If dealias(r) represents a class C,
|
||||
then the vector also contains reflections
|
||||
representing all unnamed bit-fields B whose declarations inhabit the class scope corresponding to C for which is_accessible(^^B, ctx) is true[.](#4.sentence-2)
|
||||
|
||||
Reflections of class members and unnamed bit-fields that are declared
|
||||
appear in the order in which they are declared[.](#4.sentence-3)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
Base classes are not members[.](#4.sentence-4)
|
||||
|
||||
Implicitly-declared special members
|
||||
appear after any user-declared members ([[special]](special "11.4.4 Special member functions"))[.](#4.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [1](#example-1)*: // TU1export module M;namespace NS {export int m; static int l;}static_assert(members_of(^^NS, access_context::current()).size() == 2);
|
||||
|
||||
// TU2import M;
|
||||
|
||||
static_assert( // NS::l does not precede members_of(^^NS, access_context::current()).size() == 1); // the constant-expression ([[basic.lookup]](basic.lookup "6.5 Name lookup"))class B {};
|
||||
|
||||
struct S : B {private:class I;public:int m;};
|
||||
|
||||
static_assert( // 6 special members, members_of(^^S, access_context::current()).size() == 7); // 1 public member,// does not include basestatic_assert( // all of the above, members_of(^^S, access_context::unchecked()).size() == 8); // as well as a reflection// representing S::I â *end example*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5540)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(r) is a reflection representing either
|
||||
a class type that is complete from some point in the evaluation context
|
||||
or a namespace[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:bases_of)
|
||||
|
||||
`consteval vector<info> bases_of(info type, access_context ctx);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5554)
|
||||
|
||||
*Returns*: Let C be the class represented by dealias(type)[.](#6.sentence-1)
|
||||
|
||||
A vector containing the reflections
|
||||
of all the direct base class relationships B, if any,
|
||||
of C such that is_accessible(^^B, ctx) is true[.](#6.sentence-2)
|
||||
|
||||
The direct base class relationships appear in the order in which
|
||||
the corresponding base classes appear in the [*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]") of C[.](#6.sentence-3)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5563)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(type) represents a class type
|
||||
that is complete from some point in the evaluation context[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:static_data_members_of)
|
||||
|
||||
`consteval vector<info> static_data_members_of(info type, access_context ctx);
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5576)
|
||||
|
||||
*Returns*: A vector containing each element e of members_of(type, ctx) such that is_variable(e) is true,
|
||||
preserving their order[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5582)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(type) represents a class type
|
||||
that is complete from some point in the evaluation context[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:nonstatic_data_members_of)
|
||||
|
||||
`consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5596)
|
||||
|
||||
*Returns*: A vector containing each element e of members_of(type, ctx) such that is_nonstatic_data_member(e) is true,
|
||||
preserving their order[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5602)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(type) represents a class type
|
||||
that is complete from some point in the evaluation context[.](#11.sentence-1)
|
||||
|
||||
[ð](#lib:subobjects_of)
|
||||
|
||||
`consteval vector<info> subobjects_of(info type, access_context ctx);
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5615)
|
||||
|
||||
*Returns*: A vector containing each element of bases_of(type, ctx) followed by each element of nonstatic_data_members_of(type, ctx),
|
||||
preserving their order[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5621)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(type) represents a class type
|
||||
that is complete from some point in the evaluation context[.](#13.sentence-1)
|
||||
|
||||
[ð](#lib:enumerators_of)
|
||||
|
||||
`consteval vector<info> enumerators_of(info type_enum);
|
||||
`
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5634)
|
||||
|
||||
*Returns*: A vector containing the reflections of each enumerator
|
||||
of the enumeration represented by dealias(type_enum),
|
||||
in the order in which they are declared[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5640)
|
||||
|
||||
*Throws*: meta::exception unlessdealias(type_enum) represents an enumeration type,
|
||||
and is_enumerable_type(type_enum) is true[.](#15.sentence-1)
|
||||
230
cppdraft/meta/reflection/names.md
Normal file
230
cppdraft/meta/reflection/names.md
Normal file
@@ -0,0 +1,230 @@
|
||||
[meta.reflection.names]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#names)
|
||||
|
||||
### 21.4.6 Reflection names and locations [meta.reflection.names]
|
||||
|
||||
[ð](#lib:has_identifier)
|
||||
|
||||
`consteval bool has_identifier(info r);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3673)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
If r represents an entity
|
||||
that has a typedef name for linkage purposes ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")),
|
||||
then true[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
Otherwise, if r represents an unnamed entity,
|
||||
then false[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
Otherwise, if r represents a class type,
|
||||
then !has_template_arguments(r)[.](#1.3.sentence-1)
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
Otherwise, if r represents a function,
|
||||
then true if has_template_arguments(r) is false and the function is not a
|
||||
constructor,
|
||||
destructor,
|
||||
operator function, or
|
||||
conversion function[.](#1.4.sentence-1)
|
||||
Otherwise, false[.](#1.4.sentence-2)
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
Otherwise, if r represents a template,
|
||||
then true if r does not represent a
|
||||
constructor template,
|
||||
operator function template,
|
||||
or conversion function template[.](#1.5.sentence-1)
|
||||
Otherwise, false[.](#1.5.sentence-2)
|
||||
|
||||
- [(1.6)](#1.6)
|
||||
|
||||
Otherwise, if r represents the ith parameter of a function F that is an (implicit or explicit) specialization of a templated function T and the ith parameter of the instantiated declaration of T whose template arguments are those of F would be instantiated from a pack,
|
||||
then false[.](#1.6.sentence-1)
|
||||
|
||||
- [(1.7)](#1.7)
|
||||
|
||||
Otherwise, if r represents the parameter P of a function F,
|
||||
then let S be the set of declarations,
|
||||
ignoring any explicit instantiations,
|
||||
that precede some point in the evaluation context
|
||||
and that declare either F or a templated function
|
||||
of which F is a specialization; true if
|
||||
* [(1.7.1)](#1.7.1)
|
||||
|
||||
there is a declaration D in S that introduces a name N for either P or the parameter corresponding to P in the templated function that D declares and
|
||||
|
||||
* [(1.7.2)](#1.7.2)
|
||||
|
||||
no declaration in S does so using any name other than N[.](#1.7.sentence-1)
|
||||
|
||||
Otherwise, false[.](#1.7.sentence-2)
|
||||
[*Example [1](#example-1)*: void fun(int);constexpr std::meta::info r = parameters_of(^^fun)[0];static_assert(!has_identifier(r));
|
||||
|
||||
void fun(int x);static_assert(has_identifier(r));
|
||||
|
||||
void fun(int x);static_assert(has_identifier(r));
|
||||
|
||||
void poison() {void fun(int y);}static_assert(!has_identifier(r)); â *end example*]
|
||||
|
||||
- [(1.8)](#1.8)
|
||||
|
||||
Otherwise, if r represents a variable,
|
||||
then false if the declaration of that variable
|
||||
was instantiated from a function parameter pack[.](#1.8.sentence-1)
|
||||
Otherwise, !has_template_arguments(r)[.](#1.8.sentence-2)
|
||||
|
||||
- [(1.9)](#1.9)
|
||||
|
||||
Otherwise, if r represents a structured binding,
|
||||
then false if the declaration of that structured binding
|
||||
was instantiated from a structured binding pack[.](#1.9.sentence-1)
|
||||
Otherwise, true[.](#1.9.sentence-2)
|
||||
|
||||
- [(1.10)](#1.10)
|
||||
|
||||
Otherwise, if r represents a type alias,
|
||||
then !has_template_arguments(r)[.](#1.10.sentence-1)
|
||||
|
||||
- [(1.11)](#1.11)
|
||||
|
||||
Otherwise, if r represents an
|
||||
enumerator,
|
||||
non-static-data member,
|
||||
namespace, or
|
||||
namespace alias,
|
||||
then true[.](#1.11.sentence-1)
|
||||
|
||||
- [(1.12)](#1.12)
|
||||
|
||||
Otherwise, if r represents a direct base class relationship,
|
||||
then has_identifier(type_of(r))[.](#1.12.sentence-1)
|
||||
|
||||
- [(1.13)](#1.13)
|
||||
|
||||
Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General")); true if N is not â¥[.](#1.13.sentence-1)
|
||||
Otherwise, false[.](#1.13.sentence-2)
|
||||
|
||||
[ð](#lib:identifier_of)
|
||||
|
||||
`consteval string_view identifier_of(info r);
|
||||
consteval u8string_view u8identifier_of(info r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3782)
|
||||
|
||||
Let E be UTF-8 for u8identifier_of,
|
||||
and otherwise the ordinary literal encoding[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3786)
|
||||
|
||||
*Returns*: An ntmbs, encoded with E,
|
||||
determined as follows:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
If r represents an entity with a typedef name for linkage purposes,
|
||||
then that name[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
Otherwise, if r represents a literal operator or literal operator template,
|
||||
then the [*ud-suffix*](lex.ext#nt:ud-suffix "5.13.9 User-defined literals [lex.ext]") of the operator or operator template[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
Otherwise, if r represents the parameter P of a function F,
|
||||
then let S be the set of declarations,
|
||||
ignoring any explicit instantiations,
|
||||
that precede some point in the evaluation context
|
||||
and that declare either F or a templated function of which F is a specialization;
|
||||
the name that was introduced by a declaration in S for the parameter corresponding to P[.](#3.3.sentence-1)
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
Otherwise, if r represents an entity,
|
||||
then the identifier introduced by the declaration of that entity[.](#3.4.sentence-1)
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
Otherwise, if r represents a direct base class relationship,
|
||||
then identifier_of(type_of(r)) or u8identifier_of(type_of(r)),
|
||||
respectively[.](#3.5.sentence-1)
|
||||
|
||||
- [(3.6)](#3.6)
|
||||
|
||||
Otherwise, r represents a data member description (T,N,A,W,NUA) ([[class.mem.general]](class.mem.general "11.4.1 General"));
|
||||
a string_view or u8string_view, respectively,
|
||||
containing the identifier N[.](#3.6.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3820)
|
||||
|
||||
*Throws*: meta::exception unlesshas_identifier(r) is true and the identifier that would be returned (see above)
|
||||
is representable by E[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:display_string_of)
|
||||
|
||||
`consteval string_view display_string_of(info r);
|
||||
consteval u8string_view u8display_string_of(info r);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3836)
|
||||
|
||||
*Returns*: Animplementation-definedstring_view or u8string_view, respectively[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3842)
|
||||
|
||||
*Recommended practice*: Where possible,
|
||||
implementations should return a string
|
||||
suitable for identifying the represented construct[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:source_location_of)
|
||||
|
||||
`consteval source_location source_location_of(info r);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3855)
|
||||
|
||||
*Returns*: If r represents
|
||||
a value,
|
||||
a type other than a class type or an enumeration type,
|
||||
the global namespace, or
|
||||
a data member description,
|
||||
then source_location{}[.](#7.sentence-1)
|
||||
|
||||
Otherwise, animplementation-definedsource_location value[.](#7.sentence-2)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3867)
|
||||
|
||||
*Recommended practice*: If r represents an entity with a definition
|
||||
that is reachable from the evaluation context,
|
||||
a value corresponding to a definition should be returned[.](#8.sentence-1)
|
||||
111
cppdraft/meta/reflection/operators.md
Normal file
111
cppdraft/meta/reflection/operators.md
Normal file
@@ -0,0 +1,111 @@
|
||||
[meta.reflection.operators]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#operators)
|
||||
|
||||
### 21.4.5 Operator representations [meta.reflection.operators]
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`enum class [operators](#lib:operators "21.4.5 Operator representations [meta.reflection.operators]") {
|
||||
see below;
|
||||
};
|
||||
using enum operators;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3566)
|
||||
|
||||
The enumeration type operators specifies
|
||||
constants used to identify operators that can be overloaded,
|
||||
with the meanings listed in Table [63](#tab:meta.reflection.operators "Table 63: Enum class operators")[.](#1.sentence-1)
|
||||
|
||||
The values of the constants are distinct[.](#1.sentence-2)
|
||||
|
||||
Table [63](#tab:meta.reflection.operators) — Enum class operators [[tab:meta.reflection.operators]](./tab:meta.reflection.operators)
|
||||
|
||||
| [ð](#tab:meta.reflection.operators-row-1)<br>**Constant** | **Corresponding [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]")** | **Operator symbol name** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.reflection.operators-row-2)<br>op_new | operator new | new |
|
||||
| [ð](#tab:meta.reflection.operators-row-3)<br>op_delete | operator delete | delete |
|
||||
| [ð](#tab:meta.reflection.operators-row-4)<br>op_array_new | operator new[] | new[] |
|
||||
| [ð](#tab:meta.reflection.operators-row-5)<br>op_array_delete | operator delete[] | delete[] |
|
||||
| [ð](#tab:meta.reflection.operators-row-6)<br>op_co_await | operator co_await | co_await |
|
||||
| [ð](#tab:meta.reflection.operators-row-7)<br>op_parentheses | operator() | () |
|
||||
| [ð](#tab:meta.reflection.operators-row-8)<br>op_square_brackets | operator[] | [] |
|
||||
| [ð](#tab:meta.reflection.operators-row-9)<br>op_arrow | operator-> | -> |
|
||||
| [ð](#tab:meta.reflection.operators-row-10)<br>op_arrow_star | operator->* | ->* |
|
||||
| [ð](#tab:meta.reflection.operators-row-11)<br>op_tilde | operator~ | ~ |
|
||||
| [ð](#tab:meta.reflection.operators-row-12)<br>op_exclamation | operator! | ! |
|
||||
| [ð](#tab:meta.reflection.operators-row-13)<br>op_plus | operator+ | + |
|
||||
| [ð](#tab:meta.reflection.operators-row-14)<br>op_minus | operator- | - |
|
||||
| [ð](#tab:meta.reflection.operators-row-15)<br>op_star | operator* | * |
|
||||
| [ð](#tab:meta.reflection.operators-row-16)<br>op_slash | operator/ | / |
|
||||
| [ð](#tab:meta.reflection.operators-row-17)<br>op_percent | operator% | % |
|
||||
| [ð](#tab:meta.reflection.operators-row-18)<br>op_caret | operator^ | ^ |
|
||||
| [ð](#tab:meta.reflection.operators-row-19)<br>op_ampersand | operator& | & |
|
||||
| [ð](#tab:meta.reflection.operators-row-20)<br>op_equals | operator= | = |
|
||||
| [ð](#tab:meta.reflection.operators-row-21)<br>op_pipe | operator| | | |
|
||||
| [ð](#tab:meta.reflection.operators-row-22)<br>op_plus_equals | operator+= | += |
|
||||
| [ð](#tab:meta.reflection.operators-row-23)<br>op_minus_equals | operator-= | -= |
|
||||
| [ð](#tab:meta.reflection.operators-row-24)<br>op_star_equals | operator*= | *= |
|
||||
| [ð](#tab:meta.reflection.operators-row-25)<br>op_slash_equals | operator/= | /= |
|
||||
| [ð](#tab:meta.reflection.operators-row-26)<br>op_percent_equals | operator%= | %= |
|
||||
| [ð](#tab:meta.reflection.operators-row-27)<br>op_caret_equals | operator^= | ^= |
|
||||
| [ð](#tab:meta.reflection.operators-row-28)<br>op_ampersand_equals | operator&= | &= |
|
||||
| [ð](#tab:meta.reflection.operators-row-29)<br>op_pipe_equals | operator|= | |= |
|
||||
| [ð](#tab:meta.reflection.operators-row-30)<br>op_equals_equals | operator== | == |
|
||||
| [ð](#tab:meta.reflection.operators-row-31)<br>op_exclamation_equals | operator!= | != |
|
||||
| [ð](#tab:meta.reflection.operators-row-32)<br>op_less | operator< | < |
|
||||
| [ð](#tab:meta.reflection.operators-row-33)<br>op_greater | operator> | > |
|
||||
| [ð](#tab:meta.reflection.operators-row-34)<br>op_less_equals | operator<= | <= |
|
||||
| [ð](#tab:meta.reflection.operators-row-35)<br>op_greater_equals | operator>= | >= |
|
||||
| [ð](#tab:meta.reflection.operators-row-36)<br>op_spaceship | operator<=> | <=> |
|
||||
| [ð](#tab:meta.reflection.operators-row-37)<br>op_ampersand_ampersand | operator&& | && |
|
||||
| [ð](#tab:meta.reflection.operators-row-38)<br>op_pipe_pipe | operator|| | || |
|
||||
| [ð](#tab:meta.reflection.operators-row-39)<br>op_less_less | operator<< | << |
|
||||
| [ð](#tab:meta.reflection.operators-row-40)<br>op_greater_greater | operator>> | >> |
|
||||
| [ð](#tab:meta.reflection.operators-row-41)<br>op_less_less_equals | operator<<= | <<= |
|
||||
| [ð](#tab:meta.reflection.operators-row-42)<br>op_greater_greater_equals | operator>>= | >>= |
|
||||
| [ð](#tab:meta.reflection.operators-row-43)<br>op_plus_plus | operator++ | ++ |
|
||||
| [ð](#tab:meta.reflection.operators-row-44)<br>op_minus_minus | operator-- | -- |
|
||||
| [ð](#tab:meta.reflection.operators-row-45)<br>op_comma | operator, | , |
|
||||
|
||||
[ð](#lib:operator_of)
|
||||
|
||||
`consteval operators operator_of(info r);
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3633)
|
||||
|
||||
*Returns*: The value of the enumerator from operators whose corresponding [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]") is the unqualified name of the entity represented by r[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3639)
|
||||
|
||||
*Throws*: meta::exception unlessr represents an operator function or operator function template[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:symbol_of)
|
||||
|
||||
`consteval string_view symbol_of(operators op);
|
||||
consteval u8string_view u8symbol_of(operators op);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3653)
|
||||
|
||||
*Returns*: A string_view or u8string_view containing the characters of the operator symbol name corresponding to op,
|
||||
respectively encoded with the ordinary literal encoding or with UTF-8[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3659)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
the value of op corresponds to one of the enumerators in operators[.](#5.sentence-1)
|
||||
1111
cppdraft/meta/reflection/queries.md
Normal file
1111
cppdraft/meta/reflection/queries.md
Normal file
File diff suppressed because it is too large
Load Diff
121
cppdraft/meta/reflection/result.md
Normal file
121
cppdraft/meta/reflection/result.md
Normal file
@@ -0,0 +1,121 @@
|
||||
[meta.reflection.result]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#result)
|
||||
|
||||
### 21.4.14 Expression result reflection [meta.reflection.result]
|
||||
|
||||
[ð](#lib:reflect_constant)
|
||||
|
||||
`template<class T>
|
||||
consteval info reflect_constant(T expr);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6097)
|
||||
|
||||
*Mandates*: is_copy_constructible_v<T> is true and T is a cv-unqualified structural type ([[temp.param]](temp.param "13.2 Template parameters"))
|
||||
that is not a reference type[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6103)
|
||||
|
||||
Let V be:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
if T is a class type,
|
||||
then an object that is template-argument-equivalent to the value of expr;
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
otherwise, the value of expr[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6113)
|
||||
|
||||
*Returns*: template_arguments_of(^^TCls<V>)[0],
|
||||
with TCls as defined below[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This is a reflection of an object for class types,
|
||||
and a reflection of a value otherwise[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6122)
|
||||
|
||||
*Throws*: meta::exception unless
|
||||
the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") TCls<V> would be valid
|
||||
given the invented templatetemplate<T P> struct TCls;
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6131)
|
||||
|
||||
[*Example [1](#example-1)*: template<auto D>struct A { };
|
||||
|
||||
struct N { int x; };struct K { char const* p; };
|
||||
|
||||
constexpr info r1 = reflect_constant(42);static_assert(is_value(r1));static_assert(r1 == template_arguments_of(^^A<42>)[0]);
|
||||
|
||||
constexpr info r2 = reflect_constant(N{42});static_assert(is_object(r2));static_assert(r2 == template_arguments_of(^^A<N{42}>)[0]);
|
||||
|
||||
constexpr info r3 = reflect_constant(K{nullptr}); // OKconstexpr info r4 = reflect_constant(K{"ebab"}); // error: constituent pointer// points to string literal â *end example*]
|
||||
|
||||
[ð](#lib:reflect_object)
|
||||
|
||||
`template<class T>
|
||||
consteval info reflect_object(T& expr);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6162)
|
||||
|
||||
*Mandates*: T is an object type[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6166)
|
||||
|
||||
*Returns*: A reflection of the object designated by expr[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6170)
|
||||
|
||||
*Throws*: meta::exception unlessexpr is suitable for use as a constant template argument
|
||||
for a constant template parameter of type T& ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:reflect_function)
|
||||
|
||||
`template<class T>
|
||||
consteval info reflect_function(T& fn);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6184)
|
||||
|
||||
*Mandates*: T is a function type[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6188)
|
||||
|
||||
*Returns*: A reflection of the function designated by fn[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6192)
|
||||
|
||||
*Throws*: meta::exception unlessfn is suitable for use as a constant template argument
|
||||
for a constant template parameter of type T& ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#11.sentence-1)
|
||||
108
cppdraft/meta/reflection/substitute.md
Normal file
108
cppdraft/meta/reflection/substitute.md
Normal file
@@ -0,0 +1,108 @@
|
||||
[meta.reflection.substitute]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#substitute)
|
||||
|
||||
### 21.4.13 Reflection substitution [meta.reflection.substitute]
|
||||
|
||||
[ð](#concept:reflection_range)
|
||||
|
||||
`template<class R>
|
||||
concept [reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") =
|
||||
ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")<R> &&
|
||||
[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<ranges::range_value_t<R>, info> &&
|
||||
[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<remove_cvref_t<ranges::range_reference_t<R>>, info>;
|
||||
|
||||
template<[reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>
|
||||
consteval bool [can_substitute](#lib:can_substitute "21.4.13 Reflection substitution [meta.reflection.substitute]")(info templ, R&& arguments);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L5999)
|
||||
|
||||
Let Z be the template represented by templ and let Args... be a sequence of prvalue constant expressions
|
||||
that compute the reflections held by the elements of arguments,
|
||||
in order[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6005)
|
||||
|
||||
*Returns*: true if Z<[:Args:]...> is a valid [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") ([[temp.names]](temp.names "13.3 Names of template specializations"))
|
||||
that does not name a function
|
||||
whose type contains an undeduced placeholder type[.](#2.sentence-1)
|
||||
|
||||
Otherwise, false[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6012)
|
||||
|
||||
*Throws*: meta::exception unlesstempl represents a template,
|
||||
and every reflection in arguments represents a construct
|
||||
usable as a template argument ([[temp.arg]](temp.arg "13.4 Template arguments"))[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6019)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
If forming Z<[:Args:]...> leads to a failure
|
||||
outside of the immediate context,
|
||||
the program is ill-formed[.](#4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:substitute)
|
||||
|
||||
`template<[reflection_range](#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>
|
||||
consteval info substitute(info templ, R&& arguments);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6034)
|
||||
|
||||
Let Z be the template represented by templ and let Args... be a sequence of prvalue constant expressions
|
||||
that compute the reflections held by the elements of arguments,
|
||||
in order[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6040)
|
||||
|
||||
*Returns*: ^^Z<[:Args:]...>[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6044)
|
||||
|
||||
*Throws*: meta::exception unlesscan_substitute(templ, arguments) is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6049)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
If forming Z<[:Args:]...> leads to a failure outside of the immediate context,
|
||||
the program is ill-formed[.](#8.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6055)
|
||||
|
||||
[*Example [1](#example-1)*: template<class T>auto fn1();
|
||||
|
||||
static_assert(!can_substitute(^^fn1, {^^int})); // OKconstexpr info r1 = substitute(^^fn1, {^^int}); // error: fn<int> contains an undeduced// placeholder type for its return typetemplate<class T>auto fn2() {static_assert(^^T != ^^int); // static assertion failed during instantiation of fn<int>return 0; }constexpr bool r2 = can_substitute(^^fn2, {^^int}); // error: instantiation of body of fn<int>// is needed to deduce return type â *end example*]
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6076)
|
||||
|
||||
[*Example [2](#example-2)*: consteval info to_integral_constant(unsigned i) {return substitute(^^integral_constant, {^^unsigned, reflect_constant(i)});}constexpr info r = to_integral_constant(2); // OK, r represents the type// integral_constant<unsigned, 2> â *end example*]
|
||||
222
cppdraft/meta/reflection/traits.md
Normal file
222
cppdraft/meta/reflection/traits.md
Normal file
@@ -0,0 +1,222 @@
|
||||
[meta.reflection.traits]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#traits)
|
||||
|
||||
### 21.4.17 Reflection type traits [meta.reflection.traits]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6569)
|
||||
|
||||
This subclause specifies consteval functions to
|
||||
query the properties of types ([[meta.unary]](meta.unary "21.3.6 Unary type traits")),
|
||||
query the relationships between types ([[meta.rel]](meta.rel "21.3.8 Relationships between types")), or
|
||||
transform types ([[meta.trans]](meta.trans "21.3.9 Transformations between types")),
|
||||
during program translation[.](#1.sentence-1)
|
||||
|
||||
Each consteval function declared in this class
|
||||
has an associated class template declared elsewhere in this document[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6578)
|
||||
|
||||
Every function and function template declared in this subclause
|
||||
throws an exception of type meta::exception unless the following conditions are met:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
For every parameter p of type info, is_type(p) is true[.](#2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
For every parameter r whose type is constrained on [reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]"), ranges::all_of(r, is_type) is true[.](#2.2.sentence-1)
|
||||
|
||||
// associated with [[meta.unary.cat]](meta.unary.cat "21.3.6.2 Primary type categories"), primary type categoriesconsteval bool [is_void_type](#lib:is_void_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_null_pointer_type](#lib:is_null_pointer_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_integral_type](#lib:is_integral_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_floating_point_type](#lib:is_floating_point_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_array_type](#lib:is_array_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_pointer_type](#lib:is_pointer_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_lvalue_reference_type](#lib:is_lvalue_reference_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_rvalue_reference_type](#lib:is_rvalue_reference_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_member_object_pointer_type](#lib:is_member_object_pointer_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_member_function_pointer_type](#lib:is_member_function_pointer_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_enum_type](#lib:is_enum_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_union_type](#lib:is_union_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_class_type](#lib:is_class_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_function_type](#lib:is_function_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_reflection_type](#lib:is_reflection_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.unary.comp]](meta.unary.comp "21.3.6.3 Composite type traits"), composite type categoriesconsteval bool [is_reference_type](#lib:is_reference_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_arithmetic_type](#lib:is_arithmetic_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_fundamental_type](#lib:is_fundamental_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_object_type](#lib:is_object_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_scalar_type](#lib:is_scalar_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_compound_type](#lib:is_compound_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_member_pointer_type](#lib:is_member_pointer_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.unary.prop]](meta.unary.prop "21.3.6.4 Type properties"), type propertiesconsteval bool [is_const_type](#lib:is_const_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_volatile_type](#lib:is_volatile_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_copyable_type](#lib:is_trivially_copyable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_relocatable_type](#lib:is_trivially_relocatable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_replaceable_type](#lib:is_replaceable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_standard_layout_type](#lib:is_standard_layout_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_empty_type](#lib:is_empty_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_polymorphic_type](#lib:is_polymorphic_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_abstract_type](#lib:is_abstract_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_final_type](#lib:is_final_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_aggregate_type](#lib:is_aggregate_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_consteval_only_type](#lib:is_consteval_only_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_signed_type](#lib:is_signed_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_unsigned_type](#lib:is_unsigned_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_bounded_array_type](#lib:is_bounded_array_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_unbounded_array_type](#lib:is_unbounded_array_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_scoped_enum_type](#lib:is_scoped_enum_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_constructible_type](#lib:is_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);consteval bool [is_default_constructible_type](#lib:is_default_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_copy_constructible_type](#lib:is_copy_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_move_constructible_type](#lib:is_move_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_assignable_type](#lib:is_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_dst, info type_src);consteval bool [is_copy_assignable_type](#lib:is_copy_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_move_assignable_type](#lib:is_move_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_swappable_with_type](#lib:is_swappable_with_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type1, info type2);consteval bool [is_swappable_type](#lib:is_swappable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_destructible_type](#lib:is_destructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_trivially_constructible_type](#lib:is_trivially_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);consteval bool [is_trivially_default_constructible_type](#lib:is_trivially_default_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_copy_constructible_type](#lib:is_trivially_copy_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_move_constructible_type](#lib:is_trivially_move_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_trivially_assignable_type](#lib:is_trivially_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_dst, info type_src);consteval bool [is_trivially_copy_assignable_type](#lib:is_trivially_copy_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_move_assignable_type](#lib:is_trivially_move_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_trivially_destructible_type](#lib:is_trivially_destructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_nothrow_constructible_type](#lib:is_nothrow_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);consteval bool [is_nothrow_default_constructible_type](#lib:is_nothrow_default_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_nothrow_copy_constructible_type](#lib:is_nothrow_copy_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_nothrow_move_constructible_type](#lib:is_nothrow_move_constructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_nothrow_assignable_type](#lib:is_nothrow_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_dst, info type_src);consteval bool [is_nothrow_copy_assignable_type](#lib:is_nothrow_copy_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_nothrow_move_assignable_type](#lib:is_nothrow_move_assignable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_nothrow_swappable_with_type](#lib:is_nothrow_swappable_with_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type1, info type2);consteval bool [is_nothrow_swappable_type](#lib:is_nothrow_swappable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_nothrow_destructible_type](#lib:is_nothrow_destructible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval bool [is_nothrow_relocatable_type](#lib:is_nothrow_relocatable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [is_implicit_lifetime_type](#lib:is_implicit_lifetime_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [has_virtual_destructor](#lib:has_virtual_destructor "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [has_unique_object_representations](#lib:has_unique_object_representations "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
consteval bool [reference_constructs_from_temporary](#lib:reference_constructs_from_temporary "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_dst, info type_src);consteval bool [reference_converts_from_temporary](#lib:reference_converts_from_temporary "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_dst, info type_src);
|
||||
|
||||
// associated with [[meta.rel]](meta.rel "21.3.8 Relationships between types"), type relationsconsteval bool [is_same_type](#lib:is_same_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type1, info type2);consteval bool [is_base_of_type](#lib:is_base_of_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_base, info type_derived);consteval bool [is_virtual_base_of_type](#lib:is_virtual_base_of_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_base, info type_derived);consteval bool [is_convertible_type](#lib:is_convertible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_src, info type_dst);consteval bool [is_nothrow_convertible_type](#lib:is_nothrow_convertible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_src, info type_dst);consteval bool [is_layout_compatible_type](#lib:is_layout_compatible_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type1, info type2);consteval bool [is_pointer_interconvertible_base_of_type](#lib:is_pointer_interconvertible_base_of_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_base, info type_derived);
|
||||
|
||||
template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_invocable_type](#lib:is_invocable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_invocable_r_type](#lib:is_invocable_r_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_result, info type, R&& type_args);
|
||||
|
||||
template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_nothrow_invocable_type](#lib:is_nothrow_invocable_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval bool [is_nothrow_invocable_r_type](#lib:is_nothrow_invocable_r_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type_result, info type, R&& type_args);
|
||||
|
||||
// associated with [[meta.trans.cv]](meta.trans.cv "21.3.9.2 Const-volatile modifications"), const-volatile modificationsconsteval info [remove_const](#lib:remove_const "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [remove_volatile](#lib:remove_volatile "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [remove_cv](#lib:remove_cv "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_const](#lib:add_const "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_volatile](#lib:add_volatile "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_cv](#lib:add_cv "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.trans.ref]](meta.trans.ref "21.3.9.3 Reference modifications"), reference modificationsconsteval info [remove_reference](#lib:remove_reference "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_lvalue_reference](#lib:add_lvalue_reference "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_rvalue_reference](#lib:add_rvalue_reference "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.trans.sign]](meta.trans.sign "21.3.9.4 Sign modifications"), sign modificationsconsteval info [make_signed](#lib:make_signed "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [make_unsigned](#lib:make_unsigned "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.trans.arr]](meta.trans.arr "21.3.9.5 Array modifications"), array modificationsconsteval info [remove_extent](#lib:remove_extent "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [remove_all_extents](#lib:remove_all_extents "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.trans.ptr]](meta.trans.ptr "21.3.9.6 Pointer modifications"), pointer modificationsconsteval info [remove_pointer](#lib:remove_pointer "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [add_pointer](#lib:add_pointer "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);
|
||||
|
||||
// associated with [[meta.trans.other]](meta.trans.other "21.3.9.7 Other transformations"), other transformationsconsteval info [remove_cvref](#lib:remove_cvref "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [decay](#lib:decay "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval info [common_type](time.traits.specializations#lib:common_type "30.4.3 Specializations of common_type [time.traits.specializations]")(R&& type_args);template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval info [common_reference](#lib:common_reference "21.4.17 Reflection type traits [meta.reflection.traits]")(R&& type_args);consteval info [underlying_type](#lib:underlying_type "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);template<[reflection_range](meta.reflection.substitute#concept:reflection_range "21.4.13 Reflection substitution [meta.reflection.substitute]") R = initializer_list<info>>consteval info [invoke_result](#lib:invoke_result "21.4.17 Reflection type traits [meta.reflection.traits]")(info type, R&& type_args);consteval info [unwrap_reference](#lib:unwrap_reference "21.4.17 Reflection type traits [meta.reflection.traits]")(info type);consteval info [unwrap_ref_decay](functional.syn#lib:unwrap_ref_decay "22.10.2 Header <functional> synopsis [functional.syn]")(info type);
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6747)
|
||||
|
||||
Each function or function template declared above has the following behavior
|
||||
based on the signature and return type of that function or function template[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The associated class template need not be instantiated[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Table [64](#tab:meta.reflection.traits) — Reflection type traits [[tab:meta.reflection.traits]](./tab:meta.reflection.traits)
|
||||
|
||||
| [ð](#tab:meta.reflection.traits-row-1)<br>**Signature and Return Type** | ***Returns*** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.reflection.traits-row-2)<br>bool meta::*UNARY*(info type); bool meta::*UNARY*_type(info type); | std::*UNARY*_v<T>, where T is the type or type alias represented by type |
|
||||
| [ð](#tab:meta.reflection.traits-row-3)<br>bool meta::*BINARY*(info t1, info t2); bool meta::*BINARY*_type(info t1, info t2); | std::*BINARY*_v<T1, T2>, where T1 and T2 are the types or type aliases represented by t1 and t2, respectively |
|
||||
| [ð](#tab:meta.reflection.traits-row-4)<br>template<reflection_range R> bool meta::*VARIADIC*_type(info type, R&& args); | std::*VARIADIC*_v<T, U...>, where T is the type or type alias represented by type and U... is the pack of types or type aliases whose elements are represented by the corresponding elements of args |
|
||||
| [ð](#tab:meta.reflection.traits-row-5)<br>template<reflection_range R> bool meta::*VARIADIC*_type(info t1, info t2, R&& args); | std::*VARIADIC*_v<T1, T2, U...>, where T1 and T2 are the types or type aliases represented by t1 and t2, respectively, and U... is the pack of types or type aliases whose elements are represented by the corresponding elements of args |
|
||||
| [ð](#tab:meta.reflection.traits-row-6)<br>info meta::*UNARY*(info type); | A reflection representing the type denoted by std::*UNARY*_t<T>, where T is the type or type alias represented by type |
|
||||
| [ð](#tab:meta.reflection.traits-row-7)<br>template<reflection_range R> info meta::*VARIADIC*(R&& args); | A reflection representing the type denoted by std::*VARIADIC*_t<T...>, where T... is the pack of types or type aliases whose elements are represented by the corresponding elements of args |
|
||||
| [ð](#tab:meta.reflection.traits-row-8)<br>template<reflection_range R> info meta::*VARIADIC*(info type, R&& args); | A reflection representing the type denoted by std::*VARIADIC*_t<T, U...>, where T is the type or type alias represented by type and U... is the pack of types or type aliases whose elements are represented by the corresponding elements of args |
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6817)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
For those functions or function templates which return a reflection,
|
||||
that reflection always represents a type and never a type alias[.](#4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6823)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
If t is a reflection of the type int and u is a reflection of an alias to the type int,
|
||||
then t == u is false but is_same_type(t, u) is true[.](#5.sentence-1)
|
||||
|
||||
Also, t == dealias(u) is true[.](#5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#lib:rank)
|
||||
|
||||
`consteval size_t rank(info type);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6838)
|
||||
|
||||
*Returns*: rank_v<T>,
|
||||
where T is the type represented by dealias(type)[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:extent)
|
||||
|
||||
`consteval size_t extent(info type, unsigned i = 0);
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6850)
|
||||
|
||||
*Returns*: extent_v<T, I>,
|
||||
where T is the type represented by dealias(type) and I is a constant equal to i[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:tuple_size)
|
||||
|
||||
`consteval size_t tuple_size(info type);
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6863)
|
||||
|
||||
*Returns*: tuple_size_v<T>,
|
||||
where T is the type represented by dealias(type)[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:tuple_element)
|
||||
|
||||
`consteval info tuple_element(size_t index, info type);
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6875)
|
||||
|
||||
*Returns*: A reflection representing
|
||||
the type denoted by tuple_element_t<I, T>,
|
||||
where T is the type represented by dealias(type) and I is a constant equal to index[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:variant_size)
|
||||
|
||||
`consteval size_t variant_size(info type);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6889)
|
||||
|
||||
*Returns*: variant_size_v<T>,
|
||||
where T is the type represented by dealias(type)[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:variant_alternative)
|
||||
|
||||
`consteval info variant_alternative(size_t index, info type);
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6901)
|
||||
|
||||
*Returns*: A reflection representing the type denoted byvariant_alternative_t<I, T>,
|
||||
where T is the type represented by dealias(type) and I is a constant equal to index[.](#11.sentence-1)
|
||||
|
||||
[ð](#lib:type_order)
|
||||
|
||||
`consteval strong_ordering type_order(info t1, info t2);
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L6915)
|
||||
|
||||
*Returns*: type_order_v<T1, T2>,
|
||||
where T1 and T2 are the types
|
||||
represented by dealias(t1) and dealias(t2), respectively[.](#12.sentence-1)
|
||||
95
cppdraft/meta/rel.md
Normal file
95
cppdraft/meta/rel.md
Normal file
@@ -0,0 +1,95 @@
|
||||
[meta.rel]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.rel)
|
||||
|
||||
### 21.3.8 Relationships between types [meta.rel]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1744)
|
||||
|
||||
The templates specified in Table [56](#tab:meta.rel "Table 56: Type relationship predicates") may be used to query relationships between types at compile time[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1748)
|
||||
|
||||
Each of these templates shall be a[*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))
|
||||
with a base characteristic oftrue_type if the corresponding condition is true, otherwisefalse_type[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1755)
|
||||
|
||||
Let *ELEMS-OF*(T) be the parameter packget<*N*>(declval<T>()), where *N* is the pack ofsize_t template arguments of the specialization ofindex_sequence denoted bymake_index_sequence<tuple_size_v<remove_reference_t<T>>>[.](#3.sentence-1)
|
||||
|
||||
Table [56](#tab:meta.rel) — Type relationship predicates [[tab:meta.rel]](./tab:meta.rel)
|
||||
|
||||
| [ð](#tab:meta.rel-row-1)<br>**Template** | **Condition** | **Comments** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.rel-row-2)<br>template<class T, class U> struct [is_same](#lib:is_same "21.3.8 Relationships between types [meta.rel]"); | T and U name the same type with the same cv-qualifications | |
|
||||
| [ð](#tab:meta.rel-row-3)<br>template<class Base, class Derived> struct is_base_of; | Base is a base class of Derived ([[class.derived]](class.derived "11.7 Derived classes")) without regard to cv-qualifiers or Base and Derived are not unions and name the same class type without regard to cv-qualifiers | If Base and Derived are non-union class types and are not (possibly cv-qualified versions of) the same type, Derived shall be a complete type[.](#tab:meta.rel-row-3-column-3-sentence-1)<br>[*Note [1](#tab:meta.rel-row-3-column-3-note-1)*:<br>Base classes that are private, protected, or ambiguous are, nonetheless, base classes[.](#tab:meta.rel-row-3-column-3-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.rel-row-4)<br>template<class Base, class Derived> struct is_virtual_base_of; | Base is a virtual base class of Derived ([[class.mi]](class.mi "11.7.2 Multiple base classes")) without regard to cv-qualifiers[.](#tab:meta.rel-row-4-column-2-sentence-1) | If Base and Derived are non-union class types, Derived shall be a complete type[.](#tab:meta.rel-row-4-column-3-sentence-1)<br>[*Note [2](#tab:meta.rel-row-4-column-3-note-2)*:<br>Virtual base classes that are private, protected, or ambiguous are, nonetheless, virtual base classes[.](#tab:meta.rel-row-4-column-3-sentence-2) â *end note*]<br>[*Note [3](#tab:meta.rel-row-4-column-3-note-3)*:<br>A class is never a virtual base class of itself[.](#tab:meta.rel-row-4-column-3-sentence-3) â *end note*] |
|
||||
| [ð](#tab:meta.rel-row-5)<br>template<class From, class To> struct is_convertible; | *see below* | From and To shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-5-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-6)<br>template<class From, class To> struct is_nothrow_convertible; | is_convertible_v<From, To> is true and the conversion, as defined by is_convertible, is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator")) | From and To shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-6-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-7)<br>template<class T, class U> struct is_layout_compatible; | T and U are layout-compatible ([[basic.types.general]](basic.types.general#term.layout.compatible.type "6.9.1 General")) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-7-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-8)<br>template<class Base, class Derived> struct is_pointer_interconvertible_base_of; | Derived is unambiguously derived from Base without regard to cv-qualifiers, and each object of type Derived is pointer-interconvertible ([[basic.compound]](basic.compound "6.9.4 Compound types")) with its Base subobject, or Base and Derived are not unions and name the same class type without regard to cv-qualifiers[.](#tab:meta.rel-row-8-column-2-sentence-1) | If Base and Derived are non-union class types and are not (possibly cv-qualified versions of) the same type, Derived shall be a complete type[.](#tab:meta.rel-row-8-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-9)<br>template<class Fn, class... ArgTypes> struct is_invocable; | The expression *INVOKE*(declval<Fn>(), declval<ArgTypes>()...) ([[func.require]](func.require "22.10.4 Requirements")) is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) | Fn and all types in the template parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-9-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-10)<br>template<class R, class Fn, class... ArgTypes> struct is_invocable_r; | The expression *INVOKE*<R>(declval<Fn>(), declval<ArgTypes>()...) is well-formed when treated as an unevaluated operand | Fn, R, and all types in the template parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-10-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-11)<br>template<class Fn, class... ArgTypes> struct is_nothrow_invocable; | is_invocable_v< Fn, ArgTypes...> is true and the expression *INVOKE*(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator")) | Fn and all types in the template parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-11-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-12)<br>template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r; | is_invocable_r_v< R, Fn, ArgTypes...> is true and the expression *INVOKE*<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator")) | Fn, R, and all types in the template parameter pack ArgTypes shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-12-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-13)<br>template<class Fn, class Tuple> struct is_applicable; | [*tuple-like*](tuple.like#concept:tuple-like "22.4.3 Concept tuple-like [tuple.like]")<Tuple> is true and the expression *INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...) is well-formed when treated as an unevaluated operand[.](#tab:meta.rel-row-13-column-2-sentence-1) | Fn and Tuple shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-13-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.rel-row-14)<br>template<class Fn, class Tuple> struct is_nothrow_applicable; | is_applicable_v< Fn, Tuple> is true and the expression *INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...) is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.rel-row-14-column-2-sentence-1) | Fn and Tuple shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.rel-row-14-column-3-sentence-1) |
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1908)
|
||||
|
||||
For the purpose of defining the templates in this subclause,
|
||||
a function call expression declval<T>() for any type T is considered to be a trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions")) function call
|
||||
that is not an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) of declval in the context of the corresponding definition
|
||||
notwithstanding the restrictions of [[declval]](declval "22.2.6 Function template declval")[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1916)
|
||||
|
||||
[*Example [1](#example-1)*: struct B {};struct B1 : B {};struct B2 : B {};struct D : private B1, private B2 {};
|
||||
|
||||
is_base_of_v<B, D> // true is_base_of_v<const B, D> // true is_base_of_v<B, const D> // true is_base_of_v<B, const B> // true is_base_of_v<D, B> // false is_base_of_v<B&, D&> // false is_base_of_v<B[3], D[3]> // false is_base_of_v<int, int> // false â *end example*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1936)
|
||||
|
||||
The predicate condition for a template specialization is_convertible<From, To> shall be satisfied if and only if the return expression in the following code would be
|
||||
well-formed, including any implicit conversions to the return type of the function:To test() {return declval<From>();}
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
This requirement gives well-defined results for reference types,
|
||||
array types, function types, and cv void[.](#6.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Access checking is performed
|
||||
in a context unrelated to To and From[.](#6.sentence-3)
|
||||
|
||||
Only the validity of
|
||||
the immediate context of the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") of the return statement ([[stmt.return]](stmt.return "8.8.4 The return statement"))
|
||||
(including initialization of the returned object or reference) is considered[.](#6.sentence-4)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
The
|
||||
initialization can result in side effects such as the
|
||||
instantiation of class template specializations and function template
|
||||
specializations, the generation of implicitly-defined functions, and so on[.](#6.sentence-5)
|
||||
|
||||
Such
|
||||
side effects are not in the âimmediate contextâ and can result in the program
|
||||
being ill-formed[.](#6.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
92
cppdraft/meta/rqmts.md
Normal file
92
cppdraft/meta/rqmts.md
Normal file
@@ -0,0 +1,92 @@
|
||||
[meta.rqmts]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.rqmts)
|
||||
|
||||
### 21.3.2 Requirements [meta.rqmts]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L94)
|
||||
|
||||
A *Cpp17UnaryTypeTrait* describes a property
|
||||
of a type[.](#1.sentence-1)
|
||||
|
||||
It shall be a class template that takes one template type
|
||||
argument and, optionally, additional arguments that help define the
|
||||
property being described[.](#1.sentence-2)
|
||||
|
||||
It shall be [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),
|
||||
and publicly and unambiguously derived, directly or indirectly, from
|
||||
its [*base characteristic*](#def:base_characteristic "21.3.2 Requirements [meta.rqmts]"), which is
|
||||
a specialization of the template[integral_constant](meta.help#lib:integral_constant "21.3.4 Helper classes [meta.help]"), with
|
||||
the arguments to the template integral_constant determined by the
|
||||
requirements for the particular property being described[.](#1.sentence-3)
|
||||
|
||||
The member names of the base characteristic shall not be hidden and shall be
|
||||
unambiguously available in the *Cpp17UnaryTypeTrait*[.](#1.sentence-4)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L109)
|
||||
|
||||
A *Cpp17BinaryTypeTrait* describes a
|
||||
relationship between two types[.](#2.sentence-1)
|
||||
|
||||
It shall be a class template that
|
||||
takes two template type arguments and, optionally, additional
|
||||
arguments that help define the relationship being described[.](#2.sentence-2)
|
||||
|
||||
It shall
|
||||
be [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"),
|
||||
and publicly and unambiguously derived, directly or
|
||||
indirectly, from
|
||||
its [*base characteristic*](#def:base_characteristic), which is a specialization
|
||||
of the template[integral_constant](meta.help#lib:integral_constant "21.3.4 Helper classes [meta.help]"), with
|
||||
the arguments to the template integral_constant determined by the
|
||||
requirements for the particular relationship being described[.](#2.sentence-3)
|
||||
|
||||
The member names of the base characteristic shall not be hidden and shall be
|
||||
unambiguously available in the *Cpp17BinaryTypeTrait*[.](#2.sentence-4)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L125)
|
||||
|
||||
A *Cpp17TransformationTrait* modifies a property
|
||||
of a type[.](#3.sentence-1)
|
||||
|
||||
It shall be a class template that takes one
|
||||
template type argument and, optionally, additional arguments that help
|
||||
define the modification[.](#3.sentence-2)
|
||||
|
||||
It shall define a publicly accessible nested type
|
||||
named type, which shall be a synonym for the modified type[.](#3.sentence-3)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L133)
|
||||
|
||||
Unless otherwise specified,
|
||||
the behavior of a program that adds specializations
|
||||
for any of the templates specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits") is undefined[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L139)
|
||||
|
||||
Unless otherwise specified, an incomplete type may be used
|
||||
to instantiate a template specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits")[.](#5.sentence-1)
|
||||
|
||||
The behavior of a program is undefined if
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
an instantiation of a template specified in [[type.traits]](type.traits "21.3 Metaprogramming and type traits") directly or indirectly depends on
|
||||
an incompletely-defined object type T, and
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
that instantiation could yield a different result
|
||||
were T hypothetically completed[.](#5.sentence-2)
|
||||
35
cppdraft/meta/string/literal.md
Normal file
35
cppdraft/meta/string/literal.md
Normal file
@@ -0,0 +1,35 @@
|
||||
[meta.string.literal]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.4 Reflection [[meta.reflection]](meta.reflection#meta.string.literal)
|
||||
|
||||
### 21.4.2 Checking string literals [meta.string.literal]
|
||||
|
||||
[ð](#lib:is_string_literal)
|
||||
|
||||
`consteval bool is_string_literal(const char* p);
|
||||
consteval bool is_string_literal(const wchar_t* p);
|
||||
consteval bool is_string_literal(const char8_t* p);
|
||||
consteval bool is_string_literal(const char16_t* p);
|
||||
consteval bool is_string_literal(const char32_t* p);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L3350)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
If p points to an unspecified object ([[expr.const]](expr.const "7.7 Constant expressions")), false[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
Otherwise, if p points to a subobject
|
||||
of a string literal object ([[lex.string]](lex.string "5.13.5 String literals")), true[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
Otherwise, false[.](#1.3.sentence-1)
|
||||
67
cppdraft/meta/syn.md
Normal file
67
cppdraft/meta/syn.md
Normal file
File diff suppressed because one or more lines are too long
395
cppdraft/meta/trans.md
Normal file
395
cppdraft/meta/trans.md
Normal file
@@ -0,0 +1,395 @@
|
||||
[meta.trans]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans)
|
||||
|
||||
### 21.3.9 Transformations between types [meta.trans]
|
||||
|
||||
#### [21.3.9.1](#general) General [[meta.trans.general]](meta.trans.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1966)
|
||||
|
||||
Subclause [meta.trans] contains templates that may be used to transform one
|
||||
type to another following some predefined rule[.](#general-1.sentence-1)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1970)
|
||||
|
||||
Each of the templates in [meta.trans] shall be a[*Cpp17TransformationTrait*](meta.rqmts#:Cpp17TransformationTrait "21.3.2 Requirements [meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#general-2.sentence-1)
|
||||
|
||||
#### [21.3.9.2](#cv) Const-volatile modifications [[meta.trans.cv]](meta.trans.cv)
|
||||
|
||||
[1](#cv-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1976)
|
||||
|
||||
The templates specified in Table [57](#tab:meta.trans.cv "Table 57: Const-volatile modifications") add or remove cv-qualifications ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers"))[.](#cv-1.sentence-1)
|
||||
|
||||
Table [57](#tab:meta.trans.cv) — Const-volatile modifications [[tab:meta.trans.cv]](./tab:meta.trans.cv)
|
||||
|
||||
| [ð](#tab:meta.trans.cv-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.cv-row-2)<br>template<class T> struct remove_const; | The member typedef type denotes the type formed by removing any top-level const-qualifier from T[.](#tab:meta.trans.cv-row-2-column-2-sentence-1)<br>[*Example [1](#tab:meta.trans.cv-row-2-column-2-example-1)*:<br>remove_const_t<const volatile int> evaluates to volatile int, whereas remove_const_t<const int*> evaluates to const int*[.](#tab:meta.trans.cv-row-2-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-3)<br>template<class T> struct remove_volatile; | The member typedef type denotes the type formed by removing any top-level volatile-qualifier from T[.](#tab:meta.trans.cv-row-3-column-2-sentence-1)<br>[*Example [2](#tab:meta.trans.cv-row-3-column-2-example-2)*:<br>remove_volatile_t<const volatile int> evaluates to const int, whereas remove_volatile_t<volatile int*> evaluates to volatile int*[.](#tab:meta.trans.cv-row-3-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-4)<br>template<class T> struct remove_cv; | The member typedef type denotes the type formed by removing any top-level cv-qualifiers from T[.](#tab:meta.trans.cv-row-4-column-2-sentence-1)<br>[*Example [3](#tab:meta.trans.cv-row-4-column-2-example-3)*:<br>remove_cv_t<const volatile int> evaluates to int, whereas remove_cv_t<const volatile int*> evaluates to const volatile int*[.](#tab:meta.trans.cv-row-4-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-5)<br>template<class T> struct add_const; | The member typedef type denotes const T[.](#tab:meta.trans.cv-row-5-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.cv-row-5-column-2-note-1)*:<br>const has no effect when T is a reference, function, or top-level const-qualified type[.](#tab:meta.trans.cv-row-5-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.cv-row-6)<br>template<class T> struct add_volatile; | The member typedef type denotes volatile T[.](#tab:meta.trans.cv-row-6-column-2-sentence-1)<br>[*Note [2](#tab:meta.trans.cv-row-6-column-2-note-2)*:<br>volatile has no effect when T is a reference, function, or top-level volatile-qualified type[.](#tab:meta.trans.cv-row-6-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.cv-row-7)<br>template<class T> struct add_cv; | The member typedef type denotes add_const_t<add_volatile_t<T>>[.](#tab:meta.trans.cv-row-7-column-2-sentence-1) |
|
||||
|
||||
#### [21.3.9.3](#ref) Reference modifications [[meta.trans.ref]](meta.trans.ref)
|
||||
|
||||
[1](#ref-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2054)
|
||||
|
||||
The templates specified in Table [58](#tab:meta.trans.ref "Table 58: Reference modifications") add or remove references[.](#ref-1.sentence-1)
|
||||
|
||||
Table [58](#tab:meta.trans.ref) — Reference modifications [[tab:meta.trans.ref]](./tab:meta.trans.ref)
|
||||
|
||||
| [ð](#tab:meta.trans.ref-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.ref-row-2)<br>template<class T> struct remove_reference; | If T has type âreference to T1â then the member typedef type denotes T1; otherwise, type denotes T[.](#tab:meta.trans.ref-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.ref-row-3)<br>template<class T> struct add_lvalue_reference; | If T is a referenceable type ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")) then the member typedef type denotes T&; otherwise, type denotes T[.](#tab:meta.trans.ref-row-3-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.ref-row-3-column-2-note-1)*:<br>This rule reflects the semantics of reference collapsing ([[dcl.ref]](dcl.ref "9.3.4.3 References"))[.](#tab:meta.trans.ref-row-3-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.ref-row-4)<br>template<class T> struct add_rvalue_reference; | If T is a referenceable type then the member typedef type denotes T&&; otherwise, type denotes T[.](#tab:meta.trans.ref-row-4-column-2-sentence-1)<br>[*Note [2](#tab:meta.trans.ref-row-4-column-2-note-2)*:<br>This rule reflects the semantics of reference collapsing ([[dcl.ref]](dcl.ref "9.3.4.3 References"))[.](#tab:meta.trans.ref-row-4-column-2-sentence-2)<br>For example, when a type T is a reference type T1&, the type add_rvalue_reference_t<T> is not an rvalue reference[.](#tab:meta.trans.ref-row-4-column-2-sentence-3) â *end note*] |
|
||||
|
||||
#### [21.3.9.4](#sign) Sign modifications [[meta.trans.sign]](meta.trans.sign)
|
||||
|
||||
[1](#sign-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2101)
|
||||
|
||||
The templates specified in Table [59](#tab:meta.trans.sign "Table 59: Sign modifications") convert an integer type to its corresponding signed or unsigned type[.](#sign-1.sentence-1)
|
||||
|
||||
Table [59](#tab:meta.trans.sign) — Sign modifications [[tab:meta.trans.sign]](./tab:meta.trans.sign)
|
||||
|
||||
| [ð](#tab:meta.trans.sign-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.sign-row-2)<br>template<class T> struct make_signed; | If T is a (possibly cv-qualified) signed integer type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) then the member typedef type denotes T; otherwise, if T is a (possibly cv-qualified) unsigned integer type then type denotes the corresponding signed integer type, with the same cv-qualifiers as T; otherwise, type denotes the signed integer type with smallest rank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T[.](#tab:meta.trans.sign-row-2-column-2-sentence-1)<br> *Mandates*: T is an integral or enumeration type other than cv bool[.](#tab:meta.trans.sign-row-2-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.sign-row-3)<br>template<class T> struct make_unsigned; | If T is a (possibly cv-qualified) unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) then the member typedef type denotes T; otherwise, if T is a (possibly cv-qualified) signed integer type then type denotes the corresponding unsigned integer type, with the same cv-qualifiers as T; otherwise, type denotes the unsigned integer type with smallest rank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T[.](#tab:meta.trans.sign-row-3-column-2-sentence-1)<br> *Mandates*: T is an integral or enumeration type other than cv bool[.](#tab:meta.trans.sign-row-3-column-2-sentence-2) |
|
||||
|
||||
#### [21.3.9.5](#arr) Array modifications [[meta.trans.arr]](meta.trans.arr)
|
||||
|
||||
[1](#arr-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2149)
|
||||
|
||||
The templates specified in Table [60](#tab:meta.trans.arr "Table 60: Array modifications") modify array types[.](#arr-1.sentence-1)
|
||||
|
||||
Table [60](#tab:meta.trans.arr) — Array modifications [[tab:meta.trans.arr]](./tab:meta.trans.arr)
|
||||
|
||||
| [ð](#tab:meta.trans.arr-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.arr-row-2)<br>template<class T> struct remove_extent; | If T is a type âarray of Uâ, the member typedef type denotes U, otherwise T[.](#tab:meta.trans.arr-row-2-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.arr-row-2-column-2-note-1)*:<br>For multidimensional arrays, only the first array dimension is removed[.](#tab:meta.trans.arr-row-2-column-2-sentence-2)<br>For a type âarray of const Uâ, the resulting type is const U[.](#tab:meta.trans.arr-row-2-column-2-sentence-3) â *end note*] |
|
||||
| [ð](#tab:meta.trans.arr-row-3)<br>template<class T> struct remove_all_extents; | If T is âmultidimensional array of Uâ, the resulting member typedef type denotes U, otherwise T[.](#tab:meta.trans.arr-row-3-column-2-sentence-1) |
|
||||
|
||||
[2](#arr-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2182)
|
||||
|
||||
[*Example [1](#arr-example-1)*: // the following assertions hold:static_assert(is_same_v<remove_extent_t<int>, int>);static_assert(is_same_v<remove_extent_t<int[2]>, int>);static_assert(is_same_v<remove_extent_t<int[2][3]>, int[3]>);static_assert(is_same_v<remove_extent_t<int[][3]>, int[3]>); â *end example*]
|
||||
|
||||
[3](#arr-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2193)
|
||||
|
||||
[*Example [2](#arr-example-2)*: // the following assertions hold:static_assert(is_same_v<remove_all_extents_t<int>, int>);static_assert(is_same_v<remove_all_extents_t<int[2]>, int>);static_assert(is_same_v<remove_all_extents_t<int[2][3]>, int>);static_assert(is_same_v<remove_all_extents_t<int[][3]>, int>); â *end example*]
|
||||
|
||||
#### [21.3.9.6](#ptr) Pointer modifications [[meta.trans.ptr]](meta.trans.ptr)
|
||||
|
||||
[1](#ptr-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2206)
|
||||
|
||||
The templates specified in Table [61](#tab:meta.trans.ptr "Table 61: Pointer modifications") add or remove pointers[.](#ptr-1.sentence-1)
|
||||
|
||||
Table [61](#tab:meta.trans.ptr) — Pointer modifications [[tab:meta.trans.ptr]](./tab:meta.trans.ptr)
|
||||
|
||||
| [ð](#tab:meta.trans.ptr-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.ptr-row-2)<br>template<class T> struct remove_pointer; | If T has type â(possibly cv-qualified) pointer to T1â then the member typedef type denotes T1; otherwise, it denotes T[.](#tab:meta.trans.ptr-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.ptr-row-3)<br>template<class T> struct add_pointer; | If T is a referenceable type ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")) or a cv void type then the member typedef type denotes remove_reference_t<T>*; otherwise, type denotes T[.](#tab:meta.trans.ptr-row-3-column-2-sentence-1) |
|
||||
|
||||
#### [21.3.9.7](#other) Other transformations [[meta.trans.other]](meta.trans.other)
|
||||
|
||||
[1](#other-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2238)
|
||||
|
||||
The templates specified in Table [62](#tab:meta.trans.other "Table 62: Other transformations") perform other modifications of a type[.](#other-1.sentence-1)
|
||||
|
||||
Table [62](#tab:meta.trans.other) — Other transformations [[tab:meta.trans.other]](./tab:meta.trans.other)
|
||||
|
||||
| [ð](#tab:meta.trans.other-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.other-row-2)<br>template<class T> struct [type_identity](#lib:type_identity "21.3.9.7 Other transformations [meta.trans.other]"); | The member typedef type denotes T[.](#tab:meta.trans.other-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-3)<br>template<class T> struct [remove_cvref](meta.reflection.traits#lib:remove_cvref "21.4.17 Reflection type traits [meta.reflection.traits]"); | The member typedef type denotes [remove_cv_t](meta.type.synop#lib:remove_cv_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<[remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>>[.](#tab:meta.trans.other-row-3-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-4)<br>template<class T> struct [decay](meta.reflection.traits#lib:decay "21.4.17 Reflection type traits [meta.reflection.traits]"); | Let U be [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>[.](#tab:meta.trans.other-row-4-column-2-sentence-1)<br>If [is_array_v](meta.type.synop#lib:is_array_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U> is true, the member typedef type denotes [remove_extent_t](meta.type.synop#lib:remove_extent_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>*[.](#tab:meta.trans.other-row-4-column-2-sentence-2)<br>If [is_function_v](meta.type.synop#lib:is_function_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U> is true, the member typedef type denotes [add_pointer_t](meta.type.synop#lib:add_pointer_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>[.](#tab:meta.trans.other-row-4-column-2-sentence-3)<br>Otherwise the member typedef type denotes [remove_cv_t](meta.type.synop#lib:remove_cv_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>[.](#tab:meta.trans.other-row-4-column-2-sentence-4)<br>[*Note [1](#tab:meta.trans.other-row-4-column-2-note-1)*:<br>This behavior is similar to the lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), array-to-pointer ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")), and function-to-pointer ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion")) conversions applied when an lvalue is used as an rvalue, but also strips cv-qualifiers from class types in order to more closely model by-value argument passing[.](#tab:meta.trans.other-row-4-column-2-sentence-5) â *end note*] |
|
||||
| [ð](#tab:meta.trans.other-row-5)<br>template<bool B, class T = void> struct [enable_if](#lib:enable_if "21.3.9.7 Other transformations [meta.trans.other]"); | If B is true, the member typedef type denotes T; otherwise, there shall be no member type[.](#tab:meta.trans.other-row-5-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-6)<br>template<bool B, class T,class F> struct [conditional](#lib:conditional "21.3.9.7 Other transformations [meta.trans.other]"); | If B is true, the member typedef type denotes T[.](#tab:meta.trans.other-row-6-column-2-sentence-1)<br>If B is false, the member typedef type denotes F[.](#tab:meta.trans.other-row-6-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-7)<br>template<class... T> struct common_type; | Unless this trait is specialized, the member type is defined or omitted as specified below[.](#tab:meta.trans.other-row-7-column-2-sentence-1)<br>If it is omitted, there shall be no member type[.](#tab:meta.trans.other-row-7-column-2-sentence-2)<br>Each type in the template parameter pack T shall be complete, cv void, or an array of unknown bound[.](#tab:meta.trans.other-row-7-column-2-sentence-3) |
|
||||
| [ð](#tab:meta.trans.other-row-8)<br>template<class, class,template<class> class,template<class> class>struct[basic_common_reference](refwrap.common.ref#lib:basic_common_reference "22.10.6.8 common_reference related specializations [refwrap.common.ref]"); | Unless this trait is specialized, there shall be no member type[.](#tab:meta.trans.other-row-8-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-9)<br>template<class... T> struct [common_reference](meta.reflection.traits#lib:common_reference "21.4.17 Reflection type traits [meta.reflection.traits]"); | The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type is defined or omitted as specified below[.](#tab:meta.trans.other-row-9-column-2-sentence-1)<br>Each type in the parameter pack T shall be complete or cv void[.](#tab:meta.trans.other-row-9-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-10)<br>template<class T> struct [underlying_type](meta.reflection.traits#lib:underlying_type "21.4.17 Reflection type traits [meta.reflection.traits]"); | If T is an enumeration type, the member typedef type denotes the underlying type of T ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")); otherwise, there is no member type[.](#tab:meta.trans.other-row-10-column-2-sentence-1)<br> *Mandates*: T is not an incomplete enumeration type[.](#tab:meta.trans.other-row-10-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-11)<br>template<class Fn, class... ArgTypes> struct [invoke_result](meta.reflection.traits#lib:invoke_result "21.4.17 Reflection type traits [meta.reflection.traits]"); | If the expression *INVOKE*(declval<Fn>(), declval<ArgTypes>()...) ([[func.require]](func.require "22.10.4 Requirements")) is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), the member typedef type denotes the type decltype(*INVOKE*(declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type[.](#tab:meta.trans.other-row-11-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to Fn and ArgTypes[.](#tab:meta.trans.other-row-11-column-2-sentence-2)<br>Only the validity of the immediate context of the expression is considered[.](#tab:meta.trans.other-row-11-column-2-sentence-3)<br>[*Note [2](#tab:meta.trans.other-row-11-column-2-note-2)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.trans.other-row-11-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.trans.other-row-11-column-2-sentence-5) â *end note*]<br>*Preconditions*: Fn and all types in the template parameter pack ArgTypes are complete types, cv void, or arrays of unknown bound[.](#tab:meta.trans.other-row-11-column-2-sentence-6) |
|
||||
| [ð](#tab:meta.trans.other-row-12)<br>template<class Fn, class Tuple> struct [apply_result](#lib:apply_result "21.3.9.7 Other transformations [meta.trans.other]"); | If [*tuple-like*](tuple.like#concept:tuple-like "22.4.3 Concept tuple-like [tuple.like]")<Tuple> is true and the expression *INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...) ([[func.require]](func.require "22.10.4 Requirements")) is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), the member typedef type denotes the type decltype(*INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...)); otherwise, there shall be no member type[.](#tab:meta.trans.other-row-12-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to Fn and Tuple[.](#tab:meta.trans.other-row-12-column-2-sentence-2)<br>Only the validity of the immediate context of the expression is considered[.](#tab:meta.trans.other-row-12-column-2-sentence-3)<br>[*Note [3](#tab:meta.trans.other-row-12-column-2-note-3)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.trans.other-row-12-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.trans.other-row-12-column-2-sentence-5) â *end note*]<br>*Preconditions*: Fn and Tuple are complete types, cv void, or arrays of unknown bound[.](#tab:meta.trans.other-row-12-column-2-sentence-6) |
|
||||
| [ð](#tab:meta.trans.other-row-13)<br>template<class T> struct [unwrap_reference](meta.reflection.traits#lib:unwrap_reference "21.4.17 Reflection type traits [meta.reflection.traits]"); | If T is a specialization [reference_wrapper](refwrap.general#lib:reference_wrapper "22.10.6.1 General [refwrap.general]")<X> for some type X, the member typedef type of unwrap_reference<T> denotes X&, otherwise type denotes T[.](#tab:meta.trans.other-row-13-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-14)<br>template<class T> [unwrap_ref_decay](functional.syn#lib:unwrap_ref_decay "22.10.2 Header <functional> synopsis [functional.syn]"); | The member typedef type of unwrap_ref_decay<T> denotes the type [unwrap_reference_t](meta.type.synop#lib:unwrap_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<[decay_t](meta.type.synop#lib:decay_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>>[.](#tab:meta.trans.other-row-14-column-2-sentence-1) |
|
||||
|
||||
[2](#other-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2385)
|
||||
|
||||
In addition to being available via inclusion
|
||||
of the <type_traits> header, the templatesunwrap_reference,unwrap_ref_decay,unwrap_reference_t, andunwrap_ref_decay_t are available
|
||||
when the header <functional> ([[functional.syn]](functional.syn "22.10.2 Header <functional> synopsis")) is included[.](#other-2.sentence-1)
|
||||
|
||||
[3](#other-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2396)
|
||||
|
||||
Let:
|
||||
|
||||
- [(3.1)](#other-3.1)
|
||||
|
||||
*CREF*(A) be [add_lvalue_reference_t](meta.type.synop#lib:add_lvalue_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<const [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A>>,
|
||||
|
||||
- [(3.2)](#other-3.2)
|
||||
|
||||
*XREF*(A) denote a unary alias template T such that T<U> denotes the same type as U with the addition
|
||||
of A's cv and reference qualifiers, for a non-reference cv-unqualified
|
||||
type U,
|
||||
|
||||
- [(3.3)](#other-3.3)
|
||||
|
||||
*COPYCV*(FROM, TO) be an alias for type TO with the addition of FROM's top-level cv-qualifiers,
|
||||
[*Example [1](#other-example-1)*:
|
||||
*COPYCV*(const int, volatile short) is an alias for const volatile short[.](#other-3.3.sentence-1)
|
||||
â *end example*]
|
||||
|
||||
- [(3.4)](#other-3.4)
|
||||
|
||||
*COND-RES*(X, Y) be decltype(false ? declval<X(&)()>()() : declval<Y(&)()>()())[.](#other-3.sentence-1)
|
||||
|
||||
Given types A and B,
|
||||
let X be remove_reference_t<A>,
|
||||
let Y be remove_reference_t<B>, and
|
||||
let *COMMON-REF*(A, B) be:
|
||||
|
||||
- [(3.5)](#other-3.5)
|
||||
|
||||
If A and B are both lvalue reference types, *COMMON-REF*(A, B) is *COND-RES*(*COPYCV*(X, Y) &, *COPYCV*(Y, X) &) if that type exists
|
||||
and is a reference type[.](#other-3.5.sentence-1)
|
||||
|
||||
- [(3.6)](#other-3.6)
|
||||
|
||||
Otherwise, let C be [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<*COMMON-REF*(X&, Y&)>&&[.](#other-3.6.sentence-1)
|
||||
If A and B are both rvalue reference types, C is well-formed, and [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A, C> && [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<B, C> is true,
|
||||
then *COMMON-REF*(A, B) is C[.](#other-3.6.sentence-2)
|
||||
|
||||
- [(3.7)](#other-3.7)
|
||||
|
||||
Otherwise, let D be *COMMON-REF*(const X&, Y&)[.](#other-3.7.sentence-1)
|
||||
If A is an rvalue
|
||||
reference and B is an lvalue reference and D is
|
||||
well-formed and [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A, D> is true, then *COMMON-REF*(A, B) is D[.](#other-3.7.sentence-2)
|
||||
|
||||
- [(3.8)](#other-3.8)
|
||||
|
||||
Otherwise, if A is an lvalue reference and B is an rvalue reference, then *COMMON-REF*(A, B) is *COMMON-REF*(B, A)[.](#other-3.8.sentence-1)
|
||||
|
||||
- [(3.9)](#other-3.9)
|
||||
|
||||
Otherwise, *COMMON-REF*(A, B) is ill-formed[.](#other-3.9.sentence-1)
|
||||
|
||||
If any of the types computed above is ill-formed, then*COMMON-REF*(A, B) is ill-formed[.](#other-3.sentence-3)
|
||||
|
||||
[4](#other-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2444)
|
||||
|
||||
For the common_type trait applied to a template parameter pack T of types,
|
||||
the member type shall be either defined or not present as follows:
|
||||
|
||||
- [(4.1)](#other-4.1)
|
||||
|
||||
If sizeof...(T) is zero, there shall be no member type[.](#other-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#other-4.2)
|
||||
|
||||
If sizeof...(T) is one, let T0 denote the sole type
|
||||
constituting the pack T[.](#other-4.2.sentence-1)
|
||||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote the same
|
||||
type, if any, as common_type_t<T0, T0>;
|
||||
otherwise there shall be no member type[.](#other-4.2.sentence-2)
|
||||
|
||||
- [(4.3)](#other-4.3)
|
||||
|
||||
If sizeof...(T) is two,
|
||||
let the first and second types constituting T be denoted
|
||||
by T1 and T2, respectively, and
|
||||
let D1 and D2 denote
|
||||
the same types as decay_t<T1> and decay_t<T2>, respectively[.](#other-4.3.sentence-1)
|
||||
|
||||
* [(4.3.1)](#other-4.3.1)
|
||||
|
||||
If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false,
|
||||
let C denote the same type, if any,
|
||||
as common_type_t<D1, D2>[.](#other-4.3.1.sentence-1)
|
||||
|
||||
* [(4.3.2)](#other-4.3.2)
|
||||
|
||||
[*Note [4](#other-note-4)*:
|
||||
None of the following will apply if there is a specialization common_type<D1, D2>[.](#other-4.3.2.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
* [(4.3.3)](#other-4.3.3)
|
||||
|
||||
Otherwise, ifdecay_t<decltype(false ? declval<D1>() : declval<D2>())> denotes a valid type, let C denote that type[.](#other-4.3.3.sentence-1)
|
||||
|
||||
* [(4.3.4)](#other-4.3.4)
|
||||
|
||||
Otherwise, if *COND-RES*(*CREF*(D1), *CREF*(D2)) denotes a type, let C denote the type decay_t<*COND-RES*(*CREF*(D1), *CREF*(D2))>[.](#other-4.3.4.sentence-1)
|
||||
|
||||
In either case, the member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote
|
||||
the same type, if any, as C[.](#other-4.3.sentence-2)
|
||||
Otherwise, there shall be no member type[.](#other-4.3.sentence-3)
|
||||
|
||||
- [(4.4)](#other-4.4)
|
||||
|
||||
If sizeof...(T) is greater than two,
|
||||
let T1, T2, and R, respectively,
|
||||
denote the first, second, and (pack of) remaining types constituting T[.](#other-4.4.sentence-1)
|
||||
Let C denote the same type, if any, as common_type_t<T1, T2>[.](#other-4.4.sentence-2)
|
||||
If there is such a type C, the member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote the same type, if any, as common_type_t<C, R...>[.](#other-4.4.sentence-3)
|
||||
Otherwise, there shall be no member type[.](#other-4.4.sentence-4)
|
||||
|
||||
[5](#other-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2496)
|
||||
|
||||
Notwithstanding the provisions of [[meta.rqmts]](meta.rqmts "21.3.2 Requirements"), and
|
||||
pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"),
|
||||
a program may specialize common_type<T1, T2> for types T1 and T2 such thatis_same_v<T1, decay_t<T1>> andis_same_v<T2, decay_t<T2>> are each true[.](#other-5.sentence-1)
|
||||
|
||||
[*Note [5](#other-note-5)*:
|
||||
|
||||
Such specializations are needed when only explicit conversions
|
||||
are desired between the template arguments[.](#other-5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Such a specialization need not have a member named type,
|
||||
but if it does,
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") common_type<T1, T2>::type shall denote
|
||||
a cv-unqualified non-reference type
|
||||
to which each of the types T1 and T2 is explicitly convertible[.](#other-5.sentence-3)
|
||||
|
||||
Moreover, common_type_t<T1, T2> shall denote
|
||||
the same type, if any, as does common_type_t<T2, T1>[.](#other-5.sentence-4)
|
||||
|
||||
No diagnostic is required for a violation of this Note's rules[.](#other-5.sentence-5)
|
||||
|
||||
[6](#other-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2516)
|
||||
|
||||
For the common_reference trait applied to a parameter packT of types, the member type shall be either defined or not
|
||||
present as follows:
|
||||
|
||||
- [(6.1)](#other-6.1)
|
||||
|
||||
If sizeof...(T) is zero, there shall be no member type[.](#other-6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#other-6.2)
|
||||
|
||||
Otherwise, if sizeof...(T) is one, let T0 denote the sole
|
||||
type in the pack T[.](#other-6.2.sentence-1)
|
||||
The member typedef type shall denote the
|
||||
same type as T0[.](#other-6.2.sentence-2)
|
||||
|
||||
- [(6.3)](#other-6.3)
|
||||
|
||||
Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in the pack T[.](#other-6.3.sentence-1)
|
||||
Then
|
||||
* [(6.3.1)](#other-6.3.1)
|
||||
|
||||
Let R be *COMMON-REF*(T1, T2)[.](#other-6.3.1.sentence-1)
|
||||
If T1 and T2 are reference types, R is well-formed, and is_convertible_v<add_pointer_t<T1>, add_pointer_t<R>> && is_convertible_v<add_pointer_t<T2>, add_pointer_t<R>> is true,
|
||||
then the member typedef type denotes R[.](#other-6.3.1.sentence-2)
|
||||
|
||||
* [(6.3.2)](#other-6.3.2)
|
||||
|
||||
Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
|
||||
*XREF*(T1), *XREF*(T2)>::type is well-formed, then the member typedef type denotes that type[.](#other-6.3.2.sentence-1)
|
||||
|
||||
* [(6.3.3)](#other-6.3.3)
|
||||
|
||||
Otherwise, if *COND-RES*(T1, T2) is well-formed,
|
||||
then the member typedef type denotes that type[.](#other-6.3.3.sentence-1)
|
||||
|
||||
* [(6.3.4)](#other-6.3.4)
|
||||
|
||||
Otherwise, if common_type_t<T1, T2> is well-formed, then the
|
||||
member typedef type denotes that type[.](#other-6.3.4.sentence-1)
|
||||
|
||||
* [(6.3.5)](#other-6.3.5)
|
||||
|
||||
Otherwise, there shall be no member type[.](#other-6.3.5.sentence-1)
|
||||
|
||||
- [(6.4)](#other-6.4)
|
||||
|
||||
Otherwise, if sizeof...(T) is greater than two, let T1, T2, and Rest, respectively, denote the first, second, and
|
||||
(pack of) remaining types comprising T[.](#other-6.4.sentence-1)
|
||||
Let C be the type common_reference_t<T1, T2>[.](#other-6.4.sentence-2)
|
||||
Then:
|
||||
* [(6.4.1)](#other-6.4.1)
|
||||
|
||||
If there is such a type C, the member typedef type shall
|
||||
denote the same type, if any, as common_reference_t<C, Rest...>[.](#other-6.4.1.sentence-1)
|
||||
|
||||
* [(6.4.2)](#other-6.4.2)
|
||||
|
||||
Otherwise, there shall be no member type[.](#other-6.4.2.sentence-1)
|
||||
|
||||
[7](#other-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2562)
|
||||
|
||||
Notwithstanding the provisions of [[meta.rqmts]](meta.rqmts "21.3.2 Requirements"), and
|
||||
pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"), a program may partially specializebasic_common_reference<T, U, TQual, UQual> for types T and U such thatis_same_v<T, decay_t<T>> andis_same_v<U, decay_t<U>> are each true[.](#other-7.sentence-1)
|
||||
|
||||
[*Note [6](#other-note-6)*:
|
||||
|
||||
Such specializations
|
||||
can be used to influence the result of common_reference, and
|
||||
are needed when only explicit conversions are desired
|
||||
between the template arguments[.](#other-7.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Such a specialization need not have a member named type, but if it does,
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")basic_common_reference<T, U, TQual, UQual>::type shall denote a type
|
||||
to which each of the types TQual<T> andUQual<U> is convertible[.](#other-7.sentence-3)
|
||||
|
||||
Moreover, basic_common_reference<T, U, TQual, UQual>::type shall denote
|
||||
the same type, if any, as doesbasic_common_reference<U, T, UQual, TQual>::type[.](#other-7.sentence-4)
|
||||
|
||||
No diagnostic is required for a violation of these rules[.](#other-7.sentence-5)
|
||||
|
||||
[8](#other-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2586)
|
||||
|
||||
[*Example [2](#other-example-2)*:
|
||||
|
||||
Given these definitions:using PF1 = bool (&)();using PF2 = short (*)(long);
|
||||
|
||||
struct S {operator PF2() const; double operator()(char, int&); void fn(long) const; char data;};
|
||||
|
||||
using PMF = void (S::*)(long) const;using PMD = char S::*; the following assertions will hold:static_assert(is_same_v<invoke_result_t<S, int>, short>);static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);static_assert(is_same_v<invoke_result_t<PF1>, bool>);static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
|
||||
|
||||
â *end example*]
|
||||
34
cppdraft/meta/trans/arr.md
Normal file
34
cppdraft/meta/trans/arr.md
Normal file
@@ -0,0 +1,34 @@
|
||||
[meta.trans.arr]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.arr)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#arr)
|
||||
|
||||
#### 21.3.9.5 Array modifications [meta.trans.arr]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2149)
|
||||
|
||||
The templates specified in Table [60](#tab:meta.trans.arr "Table 60: Array modifications") modify array types[.](#1.sentence-1)
|
||||
|
||||
Table [60](#tab:meta.trans.arr) — Array modifications [[tab:meta.trans.arr]](./tab:meta.trans.arr)
|
||||
|
||||
| [ð](#tab:meta.trans.arr-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.arr-row-2)<br>template<class T> struct remove_extent; | If T is a type âarray of Uâ, the member typedef type denotes U, otherwise T[.](#tab:meta.trans.arr-row-2-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.arr-row-2-column-2-note-1)*:<br>For multidimensional arrays, only the first array dimension is removed[.](#tab:meta.trans.arr-row-2-column-2-sentence-2)<br>For a type âarray of const Uâ, the resulting type is const U[.](#tab:meta.trans.arr-row-2-column-2-sentence-3) â *end note*] |
|
||||
| [ð](#tab:meta.trans.arr-row-3)<br>template<class T> struct remove_all_extents; | If T is âmultidimensional array of Uâ, the resulting member typedef type denotes U, otherwise T[.](#tab:meta.trans.arr-row-3-column-2-sentence-1) |
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2182)
|
||||
|
||||
[*Example [1](#example-1)*: // the following assertions hold:static_assert(is_same_v<remove_extent_t<int>, int>);static_assert(is_same_v<remove_extent_t<int[2]>, int>);static_assert(is_same_v<remove_extent_t<int[2][3]>, int[3]>);static_assert(is_same_v<remove_extent_t<int[][3]>, int[3]>); â *end example*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2193)
|
||||
|
||||
[*Example [2](#example-2)*: // the following assertions hold:static_assert(is_same_v<remove_all_extents_t<int>, int>);static_assert(is_same_v<remove_all_extents_t<int[2]>, int>);static_assert(is_same_v<remove_all_extents_t<int[2][3]>, int>);static_assert(is_same_v<remove_all_extents_t<int[][3]>, int>); â *end example*]
|
||||
26
cppdraft/meta/trans/cv.md
Normal file
26
cppdraft/meta/trans/cv.md
Normal file
@@ -0,0 +1,26 @@
|
||||
[meta.trans.cv]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.cv)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#cv)
|
||||
|
||||
#### 21.3.9.2 Const-volatile modifications [meta.trans.cv]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1976)
|
||||
|
||||
The templates specified in Table [57](#tab:meta.trans.cv "Table 57: Const-volatile modifications") add or remove cv-qualifications ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers"))[.](#1.sentence-1)
|
||||
|
||||
Table [57](#tab:meta.trans.cv) — Const-volatile modifications [[tab:meta.trans.cv]](./tab:meta.trans.cv)
|
||||
|
||||
| [ð](#tab:meta.trans.cv-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.cv-row-2)<br>template<class T> struct remove_const; | The member typedef type denotes the type formed by removing any top-level const-qualifier from T[.](#tab:meta.trans.cv-row-2-column-2-sentence-1)<br>[*Example [1](#tab:meta.trans.cv-row-2-column-2-example-1)*:<br>remove_const_t<const volatile int> evaluates to volatile int, whereas remove_const_t<const int*> evaluates to const int*[.](#tab:meta.trans.cv-row-2-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-3)<br>template<class T> struct remove_volatile; | The member typedef type denotes the type formed by removing any top-level volatile-qualifier from T[.](#tab:meta.trans.cv-row-3-column-2-sentence-1)<br>[*Example [2](#tab:meta.trans.cv-row-3-column-2-example-2)*:<br>remove_volatile_t<const volatile int> evaluates to const int, whereas remove_volatile_t<volatile int*> evaluates to volatile int*[.](#tab:meta.trans.cv-row-3-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-4)<br>template<class T> struct remove_cv; | The member typedef type denotes the type formed by removing any top-level cv-qualifiers from T[.](#tab:meta.trans.cv-row-4-column-2-sentence-1)<br>[*Example [3](#tab:meta.trans.cv-row-4-column-2-example-3)*:<br>remove_cv_t<const volatile int> evaluates to int, whereas remove_cv_t<const volatile int*> evaluates to const volatile int*[.](#tab:meta.trans.cv-row-4-column-2-sentence-2) â *end example*] |
|
||||
| [ð](#tab:meta.trans.cv-row-5)<br>template<class T> struct add_const; | The member typedef type denotes const T[.](#tab:meta.trans.cv-row-5-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.cv-row-5-column-2-note-1)*:<br>const has no effect when T is a reference, function, or top-level const-qualified type[.](#tab:meta.trans.cv-row-5-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.cv-row-6)<br>template<class T> struct add_volatile; | The member typedef type denotes volatile T[.](#tab:meta.trans.cv-row-6-column-2-sentence-1)<br>[*Note [2](#tab:meta.trans.cv-row-6-column-2-note-2)*:<br>volatile has no effect when T is a reference, function, or top-level volatile-qualified type[.](#tab:meta.trans.cv-row-6-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.cv-row-7)<br>template<class T> struct add_cv; | The member typedef type denotes add_const_t<add_volatile_t<T>>[.](#tab:meta.trans.cv-row-7-column-2-sentence-1) |
|
||||
22
cppdraft/meta/trans/general.md
Normal file
22
cppdraft/meta/trans/general.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[meta.trans.general]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.general)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#general)
|
||||
|
||||
#### 21.3.9.1 General [meta.trans.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1966)
|
||||
|
||||
Subclause [[meta.trans]](meta.trans "21.3.9 Transformations between types") contains templates that may be used to transform one
|
||||
type to another following some predefined rule[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1970)
|
||||
|
||||
Each of the templates in [[meta.trans]](meta.trans "21.3.9 Transformations between types") shall be a[*Cpp17TransformationTrait*](meta.rqmts#:Cpp17TransformationTrait "21.3.2 Requirements [meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#2.sentence-1)
|
||||
288
cppdraft/meta/trans/other.md
Normal file
288
cppdraft/meta/trans/other.md
Normal file
@@ -0,0 +1,288 @@
|
||||
[meta.trans.other]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.other)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#other)
|
||||
|
||||
#### 21.3.9.7 Other transformations [meta.trans.other]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2238)
|
||||
|
||||
The templates specified in Table [62](#tab:meta.trans.other "Table 62: Other transformations") perform other modifications of a type[.](#1.sentence-1)
|
||||
|
||||
Table [62](#tab:meta.trans.other) — Other transformations [[tab:meta.trans.other]](./tab:meta.trans.other)
|
||||
|
||||
| [ð](#tab:meta.trans.other-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.other-row-2)<br>template<class T> struct [type_identity](#lib:type_identity "21.3.9.7 Other transformations [meta.trans.other]"); | The member typedef type denotes T[.](#tab:meta.trans.other-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-3)<br>template<class T> struct [remove_cvref](meta.reflection.traits#lib:remove_cvref "21.4.17 Reflection type traits [meta.reflection.traits]"); | The member typedef type denotes [remove_cv_t](meta.type.synop#lib:remove_cv_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<[remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>>[.](#tab:meta.trans.other-row-3-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-4)<br>template<class T> struct [decay](meta.reflection.traits#lib:decay "21.4.17 Reflection type traits [meta.reflection.traits]"); | Let U be [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>[.](#tab:meta.trans.other-row-4-column-2-sentence-1)<br>If [is_array_v](meta.type.synop#lib:is_array_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U> is true, the member typedef type denotes [remove_extent_t](meta.type.synop#lib:remove_extent_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>*[.](#tab:meta.trans.other-row-4-column-2-sentence-2)<br>If [is_function_v](meta.type.synop#lib:is_function_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U> is true, the member typedef type denotes [add_pointer_t](meta.type.synop#lib:add_pointer_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>[.](#tab:meta.trans.other-row-4-column-2-sentence-3)<br>Otherwise the member typedef type denotes [remove_cv_t](meta.type.synop#lib:remove_cv_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<U>[.](#tab:meta.trans.other-row-4-column-2-sentence-4)<br>[*Note [1](#tab:meta.trans.other-row-4-column-2-note-1)*:<br>This behavior is similar to the lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion")), array-to-pointer ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")), and function-to-pointer ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion")) conversions applied when an lvalue is used as an rvalue, but also strips cv-qualifiers from class types in order to more closely model by-value argument passing[.](#tab:meta.trans.other-row-4-column-2-sentence-5) â *end note*] |
|
||||
| [ð](#tab:meta.trans.other-row-5)<br>template<bool B, class T = void> struct [enable_if](#lib:enable_if "21.3.9.7 Other transformations [meta.trans.other]"); | If B is true, the member typedef type denotes T; otherwise, there shall be no member type[.](#tab:meta.trans.other-row-5-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-6)<br>template<bool B, class T,class F> struct [conditional](#lib:conditional "21.3.9.7 Other transformations [meta.trans.other]"); | If B is true, the member typedef type denotes T[.](#tab:meta.trans.other-row-6-column-2-sentence-1)<br>If B is false, the member typedef type denotes F[.](#tab:meta.trans.other-row-6-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-7)<br>template<class... T> struct common_type; | Unless this trait is specialized, the member type is defined or omitted as specified below[.](#tab:meta.trans.other-row-7-column-2-sentence-1)<br>If it is omitted, there shall be no member type[.](#tab:meta.trans.other-row-7-column-2-sentence-2)<br>Each type in the template parameter pack T shall be complete, cv void, or an array of unknown bound[.](#tab:meta.trans.other-row-7-column-2-sentence-3) |
|
||||
| [ð](#tab:meta.trans.other-row-8)<br>template<class, class,template<class> class,template<class> class>struct[basic_common_reference](refwrap.common.ref#lib:basic_common_reference "22.10.6.8 common_reference related specializations [refwrap.common.ref]"); | Unless this trait is specialized, there shall be no member type[.](#tab:meta.trans.other-row-8-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-9)<br>template<class... T> struct [common_reference](meta.reflection.traits#lib:common_reference "21.4.17 Reflection type traits [meta.reflection.traits]"); | The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type is defined or omitted as specified below[.](#tab:meta.trans.other-row-9-column-2-sentence-1)<br>Each type in the parameter pack T shall be complete or cv void[.](#tab:meta.trans.other-row-9-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-10)<br>template<class T> struct [underlying_type](meta.reflection.traits#lib:underlying_type "21.4.17 Reflection type traits [meta.reflection.traits]"); | If T is an enumeration type, the member typedef type denotes the underlying type of T ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")); otherwise, there is no member type[.](#tab:meta.trans.other-row-10-column-2-sentence-1)<br> *Mandates*: T is not an incomplete enumeration type[.](#tab:meta.trans.other-row-10-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.other-row-11)<br>template<class Fn, class... ArgTypes> struct [invoke_result](meta.reflection.traits#lib:invoke_result "21.4.17 Reflection type traits [meta.reflection.traits]"); | If the expression *INVOKE*(declval<Fn>(), declval<ArgTypes>()...) ([[func.require]](func.require "22.10.4 Requirements")) is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), the member typedef type denotes the type decltype(*INVOKE*(declval<Fn>(), declval<ArgTypes>()...)); otherwise, there shall be no member type[.](#tab:meta.trans.other-row-11-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to Fn and ArgTypes[.](#tab:meta.trans.other-row-11-column-2-sentence-2)<br>Only the validity of the immediate context of the expression is considered[.](#tab:meta.trans.other-row-11-column-2-sentence-3)<br>[*Note [2](#tab:meta.trans.other-row-11-column-2-note-2)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.trans.other-row-11-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.trans.other-row-11-column-2-sentence-5) â *end note*]<br>*Preconditions*: Fn and all types in the template parameter pack ArgTypes are complete types, cv void, or arrays of unknown bound[.](#tab:meta.trans.other-row-11-column-2-sentence-6) |
|
||||
| [ð](#tab:meta.trans.other-row-12)<br>template<class Fn, class Tuple> struct [apply_result](#lib:apply_result "21.3.9.7 Other transformations [meta.trans.other]"); | If [*tuple-like*](tuple.like#concept:tuple-like "22.4.3 Concept tuple-like [tuple.like]")<Tuple> is true and the expression *INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...) ([[func.require]](func.require "22.10.4 Requirements")) is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), the member typedef type denotes the type decltype(*INVOKE*(declval<Fn>(), *ELEMS-OF*(Tuple)...)); otherwise, there shall be no member type[.](#tab:meta.trans.other-row-12-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to Fn and Tuple[.](#tab:meta.trans.other-row-12-column-2-sentence-2)<br>Only the validity of the immediate context of the expression is considered[.](#tab:meta.trans.other-row-12-column-2-sentence-3)<br>[*Note [3](#tab:meta.trans.other-row-12-column-2-note-3)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.trans.other-row-12-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.trans.other-row-12-column-2-sentence-5) â *end note*]<br>*Preconditions*: Fn and Tuple are complete types, cv void, or arrays of unknown bound[.](#tab:meta.trans.other-row-12-column-2-sentence-6) |
|
||||
| [ð](#tab:meta.trans.other-row-13)<br>template<class T> struct [unwrap_reference](meta.reflection.traits#lib:unwrap_reference "21.4.17 Reflection type traits [meta.reflection.traits]"); | If T is a specialization [reference_wrapper](refwrap.general#lib:reference_wrapper "22.10.6.1 General [refwrap.general]")<X> for some type X, the member typedef type of unwrap_reference<T> denotes X&, otherwise type denotes T[.](#tab:meta.trans.other-row-13-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.other-row-14)<br>template<class T> [unwrap_ref_decay](functional.syn#lib:unwrap_ref_decay "22.10.2 Header <functional> synopsis [functional.syn]"); | The member typedef type of unwrap_ref_decay<T> denotes the type [unwrap_reference_t](meta.type.synop#lib:unwrap_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<[decay_t](meta.type.synop#lib:decay_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<T>>[.](#tab:meta.trans.other-row-14-column-2-sentence-1) |
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2385)
|
||||
|
||||
In addition to being available via inclusion
|
||||
of the <type_traits> header, the templatesunwrap_reference,unwrap_ref_decay,unwrap_reference_t, andunwrap_ref_decay_t are available
|
||||
when the header <functional> ([[functional.syn]](functional.syn "22.10.2 Header <functional> synopsis")) is included[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2396)
|
||||
|
||||
Let:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
*CREF*(A) be [add_lvalue_reference_t](meta.type.synop#lib:add_lvalue_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<const [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A>>,
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
*XREF*(A) denote a unary alias template T such that T<U> denotes the same type as U with the addition
|
||||
of A's cv and reference qualifiers, for a non-reference cv-unqualified
|
||||
type U,
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
*COPYCV*(FROM, TO) be an alias for type TO with the addition of FROM's top-level cv-qualifiers,
|
||||
[*Example [1](#example-1)*:
|
||||
*COPYCV*(const int, volatile short) is an alias for const volatile short[.](#3.3.sentence-1)
|
||||
â *end example*]
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
*COND-RES*(X, Y) be decltype(false ? declval<X(&)()>()() : declval<Y(&)()>()())[.](#3.sentence-1)
|
||||
|
||||
Given types A and B,
|
||||
let X be remove_reference_t<A>,
|
||||
let Y be remove_reference_t<B>, and
|
||||
let *COMMON-REF*(A, B) be:
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
If A and B are both lvalue reference types, *COMMON-REF*(A, B) is *COND-RES*(*COPYCV*(X, Y) &, *COPYCV*(Y, X) &) if that type exists
|
||||
and is a reference type[.](#3.5.sentence-1)
|
||||
|
||||
- [(3.6)](#3.6)
|
||||
|
||||
Otherwise, let C be [remove_reference_t](meta.type.synop#lib:remove_reference_t "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<*COMMON-REF*(X&, Y&)>&&[.](#3.6.sentence-1)
|
||||
If A and B are both rvalue reference types, C is well-formed, and [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A, C> && [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<B, C> is true,
|
||||
then *COMMON-REF*(A, B) is C[.](#3.6.sentence-2)
|
||||
|
||||
- [(3.7)](#3.7)
|
||||
|
||||
Otherwise, let D be *COMMON-REF*(const X&, Y&)[.](#3.7.sentence-1)
|
||||
If A is an rvalue
|
||||
reference and B is an lvalue reference and D is
|
||||
well-formed and [is_convertible_v](meta.type.synop#lib:is_convertible_v "21.3.3 Header <type_traits> synopsis [meta.type.synop]")<A, D> is true, then *COMMON-REF*(A, B) is D[.](#3.7.sentence-2)
|
||||
|
||||
- [(3.8)](#3.8)
|
||||
|
||||
Otherwise, if A is an lvalue reference and B is an rvalue reference, then *COMMON-REF*(A, B) is *COMMON-REF*(B, A)[.](#3.8.sentence-1)
|
||||
|
||||
- [(3.9)](#3.9)
|
||||
|
||||
Otherwise, *COMMON-REF*(A, B) is ill-formed[.](#3.9.sentence-1)
|
||||
|
||||
If any of the types computed above is ill-formed, then*COMMON-REF*(A, B) is ill-formed[.](#3.sentence-3)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2444)
|
||||
|
||||
For the common_type trait applied to a template parameter pack T of types,
|
||||
the member type shall be either defined or not present as follows:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
If sizeof...(T) is zero, there shall be no member type[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
If sizeof...(T) is one, let T0 denote the sole type
|
||||
constituting the pack T[.](#4.2.sentence-1)
|
||||
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote the same
|
||||
type, if any, as common_type_t<T0, T0>;
|
||||
otherwise there shall be no member type[.](#4.2.sentence-2)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
If sizeof...(T) is two,
|
||||
let the first and second types constituting T be denoted
|
||||
by T1 and T2, respectively, and
|
||||
let D1 and D2 denote
|
||||
the same types as decay_t<T1> and decay_t<T2>, respectively[.](#4.3.sentence-1)
|
||||
|
||||
* [(4.3.1)](#4.3.1)
|
||||
|
||||
If is_same_v<T1, D1> is false or is_same_v<T2, D2> is false,
|
||||
let C denote the same type, if any,
|
||||
as common_type_t<D1, D2>[.](#4.3.1.sentence-1)
|
||||
|
||||
* [(4.3.2)](#4.3.2)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
None of the following will apply if there is a specialization common_type<D1, D2>[.](#4.3.2.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
* [(4.3.3)](#4.3.3)
|
||||
|
||||
Otherwise, ifdecay_t<decltype(false ? declval<D1>() : declval<D2>())> denotes a valid type, let C denote that type[.](#4.3.3.sentence-1)
|
||||
|
||||
* [(4.3.4)](#4.3.4)
|
||||
|
||||
Otherwise, if *COND-RES*(*CREF*(D1), *CREF*(D2)) denotes a type, let C denote the type decay_t<*COND-RES*(*CREF*(D1), *CREF*(D2))>[.](#4.3.4.sentence-1)
|
||||
|
||||
In either case, the member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote
|
||||
the same type, if any, as C[.](#4.3.sentence-2)
|
||||
Otherwise, there shall be no member type[.](#4.3.sentence-3)
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
If sizeof...(T) is greater than two,
|
||||
let T1, T2, and R, respectively,
|
||||
denote the first, second, and (pack of) remaining types constituting T[.](#4.4.sentence-1)
|
||||
Let C denote the same type, if any, as common_type_t<T1, T2>[.](#4.4.sentence-2)
|
||||
If there is such a type C, the member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") type shall denote the same type, if any, as common_type_t<C, R...>[.](#4.4.sentence-3)
|
||||
Otherwise, there shall be no member type[.](#4.4.sentence-4)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2496)
|
||||
|
||||
Notwithstanding the provisions of [[meta.rqmts]](meta.rqmts "21.3.2 Requirements"), and
|
||||
pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"),
|
||||
a program may specialize common_type<T1, T2> for types T1 and T2 such thatis_same_v<T1, decay_t<T1>> andis_same_v<T2, decay_t<T2>> are each true[.](#5.sentence-1)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
Such specializations are needed when only explicit conversions
|
||||
are desired between the template arguments[.](#5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Such a specialization need not have a member named type,
|
||||
but if it does,
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") common_type<T1, T2>::type shall denote
|
||||
a cv-unqualified non-reference type
|
||||
to which each of the types T1 and T2 is explicitly convertible[.](#5.sentence-3)
|
||||
|
||||
Moreover, common_type_t<T1, T2> shall denote
|
||||
the same type, if any, as does common_type_t<T2, T1>[.](#5.sentence-4)
|
||||
|
||||
No diagnostic is required for a violation of this Note's rules[.](#5.sentence-5)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2516)
|
||||
|
||||
For the common_reference trait applied to a parameter packT of types, the member type shall be either defined or not
|
||||
present as follows:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If sizeof...(T) is zero, there shall be no member type[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
Otherwise, if sizeof...(T) is one, let T0 denote the sole
|
||||
type in the pack T[.](#6.2.sentence-1)
|
||||
The member typedef type shall denote the
|
||||
same type as T0[.](#6.2.sentence-2)
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
Otherwise, if sizeof...(T) is two, let T1 and T2 denote the two types in the pack T[.](#6.3.sentence-1)
|
||||
Then
|
||||
* [(6.3.1)](#6.3.1)
|
||||
|
||||
Let R be *COMMON-REF*(T1, T2)[.](#6.3.1.sentence-1)
|
||||
If T1 and T2 are reference types, R is well-formed, and is_convertible_v<add_pointer_t<T1>, add_pointer_t<R>> && is_convertible_v<add_pointer_t<T2>, add_pointer_t<R>> is true,
|
||||
then the member typedef type denotes R[.](#6.3.1.sentence-2)
|
||||
|
||||
* [(6.3.2)](#6.3.2)
|
||||
|
||||
Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
|
||||
*XREF*(T1), *XREF*(T2)>::type is well-formed, then the member typedef type denotes that type[.](#6.3.2.sentence-1)
|
||||
|
||||
* [(6.3.3)](#6.3.3)
|
||||
|
||||
Otherwise, if *COND-RES*(T1, T2) is well-formed,
|
||||
then the member typedef type denotes that type[.](#6.3.3.sentence-1)
|
||||
|
||||
* [(6.3.4)](#6.3.4)
|
||||
|
||||
Otherwise, if common_type_t<T1, T2> is well-formed, then the
|
||||
member typedef type denotes that type[.](#6.3.4.sentence-1)
|
||||
|
||||
* [(6.3.5)](#6.3.5)
|
||||
|
||||
Otherwise, there shall be no member type[.](#6.3.5.sentence-1)
|
||||
|
||||
- [(6.4)](#6.4)
|
||||
|
||||
Otherwise, if sizeof...(T) is greater than two, let T1, T2, and Rest, respectively, denote the first, second, and
|
||||
(pack of) remaining types comprising T[.](#6.4.sentence-1)
|
||||
Let C be the type common_reference_t<T1, T2>[.](#6.4.sentence-2)
|
||||
Then:
|
||||
* [(6.4.1)](#6.4.1)
|
||||
|
||||
If there is such a type C, the member typedef type shall
|
||||
denote the same type, if any, as common_reference_t<C, Rest...>[.](#6.4.1.sentence-1)
|
||||
|
||||
* [(6.4.2)](#6.4.2)
|
||||
|
||||
Otherwise, there shall be no member type[.](#6.4.2.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2562)
|
||||
|
||||
Notwithstanding the provisions of [[meta.rqmts]](meta.rqmts "21.3.2 Requirements"), and
|
||||
pursuant to [[namespace.std]](namespace.std "16.4.5.2.1 Namespace std"), a program may partially specializebasic_common_reference<T, U, TQual, UQual> for types T and U such thatis_same_v<T, decay_t<T>> andis_same_v<U, decay_t<U>> are each true[.](#7.sentence-1)
|
||||
|
||||
[*Note [6](#note-6)*:
|
||||
|
||||
Such specializations
|
||||
can be used to influence the result of common_reference, and
|
||||
are needed when only explicit conversions are desired
|
||||
between the template arguments[.](#7.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Such a specialization need not have a member named type, but if it does,
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")basic_common_reference<T, U, TQual, UQual>::type shall denote a type
|
||||
to which each of the types TQual<T> andUQual<U> is convertible[.](#7.sentence-3)
|
||||
|
||||
Moreover, basic_common_reference<T, U, TQual, UQual>::type shall denote
|
||||
the same type, if any, as doesbasic_common_reference<U, T, UQual, TQual>::type[.](#7.sentence-4)
|
||||
|
||||
No diagnostic is required for a violation of these rules[.](#7.sentence-5)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2586)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
Given these definitions:using PF1 = bool (&)();using PF2 = short (*)(long);
|
||||
|
||||
struct S {operator PF2() const; double operator()(char, int&); void fn(long) const; char data;};
|
||||
|
||||
using PMF = void (S::*)(long) const;using PMD = char S::*; the following assertions will hold:static_assert(is_same_v<invoke_result_t<S, int>, short>);static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);static_assert(is_same_v<invoke_result_t<PF1>, bool>);static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
|
||||
|
||||
â *end example*]
|
||||
22
cppdraft/meta/trans/ptr.md
Normal file
22
cppdraft/meta/trans/ptr.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[meta.trans.ptr]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.ptr)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#ptr)
|
||||
|
||||
#### 21.3.9.6 Pointer modifications [meta.trans.ptr]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2206)
|
||||
|
||||
The templates specified in Table [61](#tab:meta.trans.ptr "Table 61: Pointer modifications") add or remove pointers[.](#1.sentence-1)
|
||||
|
||||
Table [61](#tab:meta.trans.ptr) — Pointer modifications [[tab:meta.trans.ptr]](./tab:meta.trans.ptr)
|
||||
|
||||
| [ð](#tab:meta.trans.ptr-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.ptr-row-2)<br>template<class T> struct remove_pointer; | If T has type â(possibly cv-qualified) pointer to T1â then the member typedef type denotes T1; otherwise, it denotes T[.](#tab:meta.trans.ptr-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.ptr-row-3)<br>template<class T> struct add_pointer; | If T is a referenceable type ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")) or a cv void type then the member typedef type denotes remove_reference_t<T>*; otherwise, type denotes T[.](#tab:meta.trans.ptr-row-3-column-2-sentence-1) |
|
||||
23
cppdraft/meta/trans/ref.md
Normal file
23
cppdraft/meta/trans/ref.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[meta.trans.ref]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.ref)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#ref)
|
||||
|
||||
#### 21.3.9.3 Reference modifications [meta.trans.ref]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2054)
|
||||
|
||||
The templates specified in Table [58](#tab:meta.trans.ref "Table 58: Reference modifications") add or remove references[.](#1.sentence-1)
|
||||
|
||||
Table [58](#tab:meta.trans.ref) — Reference modifications [[tab:meta.trans.ref]](./tab:meta.trans.ref)
|
||||
|
||||
| [ð](#tab:meta.trans.ref-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.ref-row-2)<br>template<class T> struct remove_reference; | If T has type âreference to T1â then the member typedef type denotes T1; otherwise, type denotes T[.](#tab:meta.trans.ref-row-2-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.trans.ref-row-3)<br>template<class T> struct add_lvalue_reference; | If T is a referenceable type ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")) then the member typedef type denotes T&; otherwise, type denotes T[.](#tab:meta.trans.ref-row-3-column-2-sentence-1)<br>[*Note [1](#tab:meta.trans.ref-row-3-column-2-note-1)*:<br>This rule reflects the semantics of reference collapsing ([[dcl.ref]](dcl.ref "9.3.4.3 References"))[.](#tab:meta.trans.ref-row-3-column-2-sentence-2) â *end note*] |
|
||||
| [ð](#tab:meta.trans.ref-row-4)<br>template<class T> struct add_rvalue_reference; | If T is a referenceable type then the member typedef type denotes T&&; otherwise, type denotes T[.](#tab:meta.trans.ref-row-4-column-2-sentence-1)<br>[*Note [2](#tab:meta.trans.ref-row-4-column-2-note-2)*:<br>This rule reflects the semantics of reference collapsing ([[dcl.ref]](dcl.ref "9.3.4.3 References"))[.](#tab:meta.trans.ref-row-4-column-2-sentence-2)<br>For example, when a type T is a reference type T1&, the type add_rvalue_reference_t<T> is not an rvalue reference[.](#tab:meta.trans.ref-row-4-column-2-sentence-3) â *end note*] |
|
||||
22
cppdraft/meta/trans/sign.md
Normal file
22
cppdraft/meta/trans/sign.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[meta.trans.sign]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.trans.sign)
|
||||
|
||||
### 21.3.9 Transformations between types [[meta.trans]](meta.trans#sign)
|
||||
|
||||
#### 21.3.9.4 Sign modifications [meta.trans.sign]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L2101)
|
||||
|
||||
The templates specified in Table [59](#tab:meta.trans.sign "Table 59: Sign modifications") convert an integer type to its corresponding signed or unsigned type[.](#1.sentence-1)
|
||||
|
||||
Table [59](#tab:meta.trans.sign) — Sign modifications [[tab:meta.trans.sign]](./tab:meta.trans.sign)
|
||||
|
||||
| [ð](#tab:meta.trans.sign-row-1)<br>**Template** | **Comments** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.trans.sign-row-2)<br>template<class T> struct make_signed; | If T is a (possibly cv-qualified) signed integer type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) then the member typedef type denotes T; otherwise, if T is a (possibly cv-qualified) unsigned integer type then type denotes the corresponding signed integer type, with the same cv-qualifiers as T; otherwise, type denotes the signed integer type with smallest rank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T[.](#tab:meta.trans.sign-row-2-column-2-sentence-1)<br> *Mandates*: T is an integral or enumeration type other than cv bool[.](#tab:meta.trans.sign-row-2-column-2-sentence-2) |
|
||||
| [ð](#tab:meta.trans.sign-row-3)<br>template<class T> struct make_unsigned; | If T is a (possibly cv-qualified) unsigned integer type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) then the member typedef type denotes T; otherwise, if T is a (possibly cv-qualified) signed integer type then type denotes the corresponding unsigned integer type, with the same cv-qualifiers as T; otherwise, type denotes the unsigned integer type with smallest rank ([[conv.rank]](conv.rank "6.9.6 Conversion ranks")) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T[.](#tab:meta.trans.sign-row-3-column-2-sentence-1)<br> *Mandates*: T is an integral or enumeration type other than cv bool[.](#tab:meta.trans.sign-row-3-column-2-sentence-2) |
|
||||
9
cppdraft/meta/type/synop.md
Normal file
9
cppdraft/meta/type/synop.md
Normal file
File diff suppressed because one or more lines are too long
292
cppdraft/meta/unary.md
Normal file
292
cppdraft/meta/unary.md
Normal file
@@ -0,0 +1,292 @@
|
||||
[meta.unary]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary)
|
||||
|
||||
### 21.3.6 Unary type traits [meta.unary]
|
||||
|
||||
#### [21.3.6.1](#general) General [[meta.unary.general]](meta.unary.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L913)
|
||||
|
||||
Subclause [meta.unary] contains templates that may be used to query the
|
||||
properties of a type at compile time[.](#general-1.sentence-1)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L917)
|
||||
|
||||
Each of these templates shall be a[*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") with a base characteristic oftrue_type if the corresponding condition is true, otherwisefalse_type[.](#general-2.sentence-1)
|
||||
|
||||
#### [21.3.6.2](#cat) Primary type categories [[meta.unary.cat]](meta.unary.cat)
|
||||
|
||||
[1](#cat-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L926)
|
||||
|
||||
The primary type categories specified in Table [52](#tab:meta.unary.cat "Table 52: Primary type category predicates") correspond to the descriptions given in
|
||||
subclause [[basic.types]](basic.types "6.9 Types") of the C++ standard[.](#cat-1.sentence-1)
|
||||
|
||||
[2](#cat-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L931)
|
||||
|
||||
For any given type T, the result of applying one of these templates toT and to cv T shall yield the same result[.](#cat-2.sentence-1)
|
||||
|
||||
[3](#cat-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L935)
|
||||
|
||||
[*Note [1](#cat-note-1)*:
|
||||
|
||||
For any given type T, exactly one of the primary type categories
|
||||
has a value member that evaluates to true[.](#cat-3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Table [52](#tab:meta.unary.cat) — Primary type category predicates [[tab:meta.unary.cat]](./tab:meta.unary.cat)
|
||||
|
||||
| [ð](#tab:meta.unary.cat-row-1)<br>**Template** | **Condition** | **Comments** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.cat-row-2)<br>template<class T> struct [is_void](#lib:is_void "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is void | |
|
||||
| [ð](#tab:meta.unary.cat-row-3)<br>template<class T> struct [is_null_pointer](#lib:is_null_pointer "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is nullptr_t ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-4)<br>template<class T> struct [is_integral](#lib:is_integral "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is an integral type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-5)<br>template<class T> struct is_floating_point; | T is a floating-point type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-6)<br>template<class T> struct is_array; | T is an array type ([[basic.compound]](basic.compound "6.9.4 Compound types")) of known or unknown extent | Class template array ([[array]](array "23.3.3 Class template array")) is not an array type[.](#tab:meta.unary.cat-row-6-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.cat-row-7)<br>template<class T> struct is_pointer; | T is a pointer type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | Includes pointers to functions but not pointers to non-static members[.](#tab:meta.unary.cat-row-7-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.cat-row-8)<br>template<class T> struct is_lvalue_reference; | T is an lvalue reference type ([[dcl.ref]](dcl.ref "9.3.4.3 References")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-9)<br>template<class T> struct is_rvalue_reference; | T is an rvalue reference type ([[dcl.ref]](dcl.ref "9.3.4.3 References")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-10)<br>template<class T> struct is_member_object_pointer; | T is a pointer to data member | |
|
||||
| [ð](#tab:meta.unary.cat-row-11)<br>template<class T> struct is_member_function_pointer; | T is a pointer to member function | |
|
||||
| [ð](#tab:meta.unary.cat-row-12)<br>template<class T> struct is_enum; | T is an enumeration type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-13)<br>template<class T> struct is_union; | T is a union type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-14)<br>template<class T> struct is_class; | T is a non-union class type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-15)<br>template<class T> struct is_function; | T is a function type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-16)<br>template<class T> struct is_reflection; | T is std::meta::info ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
|
||||
#### [21.3.6.3](#comp) Composite type traits [[meta.unary.comp]](meta.unary.comp)
|
||||
|
||||
[1](#comp-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1014)
|
||||
|
||||
The templates specified in Table [53](#tab:meta.unary.comp "Table 53: Composite type category predicates") provide convenient compositions of the primary type categories,
|
||||
corresponding to the descriptions given in subclause [[basic.types]](basic.types "6.9 Types")[.](#comp-1.sentence-1)
|
||||
|
||||
[2](#comp-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1019)
|
||||
|
||||
For any given type T, the result of applying one of these templates toT and to cv T shall yield the same result[.](#comp-2.sentence-1)
|
||||
|
||||
Table [53](#tab:meta.unary.comp) — Composite type category predicates [[tab:meta.unary.comp]](./tab:meta.unary.comp)
|
||||
|
||||
| [ð](#tab:meta.unary.comp-row-1)<br>**Template** | **Condition** | **Comments** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.comp-row-2)<br>template<class T> struct is_reference; | T is an lvalue reference or an rvalue reference | |
|
||||
| [ð](#tab:meta.unary.comp-row-3)<br>template<class T> struct is_arithmetic; | T is an arithmetic type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-4)<br>template<class T> struct is_fundamental; | T is a fundamental type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-5)<br>template<class T> struct is_object; | T is an object type ([[basic.types.general]](basic.types.general#term.object.type "6.9.1 General")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-6)<br>template<class T> struct is_scalar; | T is a scalar type ([[basic.types.general]](basic.types.general#term.scalar.type "6.9.1 General")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-7)<br>template<class T> struct is_compound; | T is a compound type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-8)<br>template<class T> struct is_member_pointer; | T is a pointer-to-member type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
|
||||
#### [21.3.6.4](#prop) Type properties [[meta.unary.prop]](meta.unary.prop)
|
||||
|
||||
[1](#prop-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1063)
|
||||
|
||||
The templates specified in Table [54](#tab:meta.unary.prop "Table 54: Type property predicates") provide access to some of the more important properties of types[.](#prop-1.sentence-1)
|
||||
|
||||
[2](#prop-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1067)
|
||||
|
||||
It is unspecified whether the library defines any full or partial
|
||||
specializations of any of these templates[.](#prop-2.sentence-1)
|
||||
|
||||
[3](#prop-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1071)
|
||||
|
||||
For all of the class templates X declared in this subclause,
|
||||
instantiating that template with a template-argument that is a class
|
||||
template specialization may result in the implicit instantiation of
|
||||
the template argument if and only if the semantics of X require that
|
||||
the argument is a complete type[.](#prop-3.sentence-1)
|
||||
|
||||
[4](#prop-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1078)
|
||||
|
||||
For the purpose of defining the templates in this subclause,
|
||||
a function call expression declval<T>() for any type T is considered to be a trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions")) function call
|
||||
that is not an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) of declval in the context of the corresponding definition
|
||||
notwithstanding the restrictions of [[declval]](declval "22.2.6 Function template declval")[.](#prop-4.sentence-1)
|
||||
|
||||
[5](#prop-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1086)
|
||||
|
||||
For the purpose of defining the templates in this subclause,
|
||||
let *VAL*<T> for some type T be
|
||||
an expression defined as follows:
|
||||
|
||||
- [(5.1)](#prop-5.1)
|
||||
|
||||
If T is a reference or function type,*VAL*<T> is an expression
|
||||
with the same type and value category as declval<T>()[.](#prop-5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#prop-5.2)
|
||||
|
||||
Otherwise, *VAL*<T> is a prvalue
|
||||
that initially has type T[.](#prop-5.2.sentence-1)
|
||||
[*Note [1](#prop-note-1)*:
|
||||
If T is cv-qualified,
|
||||
the cv-qualification is subject to adjustment ([[expr.type]](expr.type "7.2.2 Type"))[.](#prop-5.2.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
Table [54](#tab:meta.unary.prop) — Type property predicates [[tab:meta.unary.prop]](./tab:meta.unary.prop)
|
||||
|
||||
| [ð](#tab:meta.unary.prop-row-1)<br>**Template** | **Condition** | **Preconditions** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.prop-row-2)<br>template<class T> struct is_const; | T is const-qualified ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-3)<br>template<class T> struct is_volatile; | T is volatile-qualified ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-4)<br>template<class T> struct is_trivially_copyable; | T is a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-4-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-5)<br>template<class T> struct is_trivially_relocatable; | T is a trivially relocatable type ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-5-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-6)<br>template<class T> struct is_replaceable; | T is a replaceable type ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-6-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-7)<br>template<class T> struct is_standard_layout; | T is a standard-layout type ([[basic.types.general]](basic.types.general#term.standard.layout.type "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-7-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-8)<br>template<class T> struct is_empty; | T is a class type, but not a union type, with no non-static data members other than subobjects of zero size, no virtual member functions, no virtual base classes, and no base class B for which is_empty_v<B> is false[.](#tab:meta.unary.prop-row-8-column-2-sentence-1) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-8-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-9)<br>template<class T> struct is_polymorphic; | T is a polymorphic class ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-9-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-10)<br>template<class T> struct is_abstract; | T is an abstract class ([[class.abstract]](class.abstract "11.7.4 Abstract classes")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-10-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-11)<br>template<class T> struct is_final; | T is a class type marked with the [*class-property-specifier*](class.pre#nt:class-property-specifier "11.1 Preamble [class.pre]")final ([[class.pre]](class.pre "11.1 Preamble"))[.](#tab:meta.unary.prop-row-11-column-2-sentence-1)<br>[*Note [2](#tab:meta.unary.prop-row-11-column-2-note-2)*:<br>A union is a class type that can be marked with final[.](#tab:meta.unary.prop-row-11-column-2-sentence-2) â *end note*] | If T is a class type, T shall be a complete type[.](#tab:meta.unary.prop-row-11-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-12)<br>template<class T> struct [is_aggregate](#lib:is_aggregate "21.3.6.4 Type properties [meta.unary.prop]"); | T is an aggregate type ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")) | T shall be an array type, a complete type, or cv void[.](#tab:meta.unary.prop-row-12-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-13)<br>template<class T> struct is_consteval_only; | T is consteval-only ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-13-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-14)<br>template<class T> struct is_signed; | If is_arithmetic_v<T> is true, the same result as T(-1) < T(0); otherwise, false | |
|
||||
| [ð](#tab:meta.unary.prop-row-15)<br>template<class T> struct [is_unsigned](#lib:is_unsigned "21.3.6.4 Type properties [meta.unary.prop]"); | If is_arithmetic_v<T> is true, the same result as T(0) < T(-1); otherwise, false | |
|
||||
| [ð](#tab:meta.unary.prop-row-16)<br>template<class T> struct [is_bounded_array](#lib:is_bounded_array "21.3.6.4 Type properties [meta.unary.prop]"); | T is an array type of known bound ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-17)<br>template<class T> struct is_unbounded_array; | T is an array type of unknown bound ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-18)<br>template<class T> struct is_scoped_enum; | T is a scoped enumeration ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-19)<br>template<class T, class... Args> struct is_constructible; | For a function type T or for a cv void type T, is_constructible_v<T, Args...> is false, otherwise *see below* | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-19-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-20)<br>template<class T> struct is_default_constructible; | is_constructible_v<T> is true[.](#tab:meta.unary.prop-row-20-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-20-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-21)<br>template<class T> struct is_copy_constructible; | For a referenceable type T ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")), the same result as is_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-21-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-21-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-22)<br>template<class T> struct is_move_constructible; | For a referenceable type T, the same result as is_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-22-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-22-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-23)<br>template<class T, class U> struct is_assignable; | The expression declval<T>() = declval<U>() is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence"))[.](#tab:meta.unary.prop-row-23-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-23-column-2-sentence-2)<br>Only the validity of the immediate context of the assignment expression is considered[.](#tab:meta.unary.prop-row-23-column-2-sentence-3)<br>[*Note [3](#tab:meta.unary.prop-row-23-column-2-note-3)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-23-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-23-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-23-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-24)<br>template<class T> struct is_copy_assignable; | For a referenceable type T, the same result as is_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-24-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-24-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-25)<br>template<class T> struct is_move_assignable; | For a referenceable type T, the same result as is_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-25-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-25-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-26)<br>template<class T, class U> struct is_swappable_with; | The expressions swap(declval<T>(), declval<U>()) and swap(declval<U>(), declval<T>()) are each well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) in an overload-resolution context for swappable values ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements"))[.](#tab:meta.unary.prop-row-26-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-26-column-2-sentence-2)<br>Only the validity of the immediate context of the swap expressions is considered[.](#tab:meta.unary.prop-row-26-column-2-sentence-3)<br>[*Note [4](#tab:meta.unary.prop-row-26-column-2-note-4)*:<br>The compilation of the expressions can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-26-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-26-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-26-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-27)<br>template<class T> struct is_swappable; | For a referenceable type T, the same result as is_swappable_with_v<T&, T&>, otherwise false[.](#tab:meta.unary.prop-row-27-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-27-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-28)<br>template<class T> struct is_destructible; | Either T is a reference type, or T is a complete object type for which the expression declval<U&>().~U() is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), where U is remove_all_extents_t<T>[.](#tab:meta.unary.prop-row-28-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-28-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-29)<br>template<class T, class... Args> struct is_trivially_constructible; | is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known to call no operation that is not trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions"))[.](#tab:meta.unary.prop-row-29-column-2-sentence-1) | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-29-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-30)<br>template<class T> struct is_trivially_default_constructible; | is_trivially_constructible_v<T> is true[.](#tab:meta.unary.prop-row-30-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-30-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-31)<br>template<class T> struct is_trivially_copy_constructible; | For a referenceable type T, the same result as is_trivially_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-31-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-31-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-32)<br>template<class T> struct is_trivially_move_constructible; | For a referenceable type T, the same result as is_trivially_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-32-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-32-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-33)<br>template<class T, class U> struct is_trivially_assignable; | is_assignable_v<T, U> is true and the assignment, as defined by is_assignable, is known to call no operation that is not trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions"))[.](#tab:meta.unary.prop-row-33-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-33-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-34)<br>template<class T> struct is_trivially_copy_assignable; | For a referenceable type T, the same result as is_trivially_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-34-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-34-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-35)<br>template<class T> struct is_trivially_move_assignable; | For a referenceable type T, the same result as is_trivially_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-35-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-35-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-36)<br>template<class T> struct is_trivially_destructible; | is_destructible_v<T> is true and remove_all_extents_t<T> is either a non-class type or a class type with a trivial destructor[.](#tab:meta.unary.prop-row-36-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-36-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-37)<br>template<class T, class... Args> struct is_nothrow_constructible; | is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-37-column-2-sentence-1) | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-37-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-38)<br>template<class T> struct is_nothrow_default_constructible; | is_nothrow_constructible_v<T> is true[.](#tab:meta.unary.prop-row-38-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-38-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-39)<br>template<class T> struct is_nothrow_copy_constructible; | For a referenceable type T, the same result as is_nothrow_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-39-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-39-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-40)<br>template<class T> struct is_nothrow_move_constructible; | For a referenceable type T, the same result as is_nothrow_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-40-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-40-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-41)<br>template<class T, class U> struct is_nothrow_assignable; | is_assignable_v<T, U> is true and the assignment is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-41-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-41-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-42)<br>template<class T> struct is_nothrow_copy_assignable; | For a referenceable type T, the same result as is_nothrow_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-42-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-42-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-43)<br>template<class T> struct is_nothrow_move_assignable; | For a referenceable type T, the same result as is_nothrow_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-43-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-43-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-44)<br>template<class T, class U> struct is_nothrow_swappable_with; | is_swappable_with_v<T, U> is true and each swap expression of the definition of is_swappable_with<T, U> is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-44-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-44-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-45)<br>template<class T> struct is_nothrow_swappable; | For a referenceable type T, the same result as is_nothrow_swappable_with_v<T&, T&>, otherwise false[.](#tab:meta.unary.prop-row-45-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-45-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-46)<br>template<class T> struct is_nothrow_destructible; | is_destructible_v<T> is true and the indicated destructor is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-46-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-46-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-47)<br>template<class T> struct is_nothrow_relocatable; | is_trivially_relocatable_v<T> ||(is_nothrow_move_constructible_v<remove_all_extents_t<T>> && is_nothrow_destructible_v<remove_all_extents_t<T>>) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-47-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-48)<br>template<class T> struct is_implicit_lifetime; | T is an implicit-lifetime type ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1 General"))[.](#tab:meta.unary.prop-row-48-column-2-sentence-1) | T shall be an array type, a complete type, or cv void[.](#tab:meta.unary.prop-row-48-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-49)<br>template<class T> struct has_virtual_destructor; | T has a virtual destructor ([[class.dtor]](class.dtor "11.4.7 Destructors")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-49-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-50)<br>template<class T> struct has_unique_object_representations; | For an array type T, the same result as has_unique_object_representations_v<remove_all_extents_t<T>>, otherwise *see below*[.](#tab:meta.unary.prop-row-50-column-2-sentence-1) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-50-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-51)<br>template<class T, class U> struct reference_constructs_from_temporary; | T is a reference type, and the initialization T t(*VAL*<U>); is well-formed and binds t to a temporary object whose lifetime is extended ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#tab:meta.unary.prop-row-51-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-51-column-2-sentence-2)<br>Only the validity of the immediate context of the variable initialization is considered[.](#tab:meta.unary.prop-row-51-column-2-sentence-3)<br>[*Note [5](#tab:meta.unary.prop-row-51-column-2-note-5)*:<br>The initialization can result in effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-51-column-2-sentence-4)<br>Such effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-51-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-51-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-52)<br>template<class T, class U> struct reference_converts_from_temporary; | T is a reference type, and the initialization T t = *VAL*<U>; is well-formed and binds t to a temporary object whose lifetime is extended ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#tab:meta.unary.prop-row-52-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-52-column-2-sentence-2)<br>Only the validity of the immediate context of the variable initialization is considered[.](#tab:meta.unary.prop-row-52-column-2-sentence-3)<br>[*Note [6](#tab:meta.unary.prop-row-52-column-2-note-6)*:<br>The initialization can result in effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-52-column-2-sentence-4)<br>Such effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-52-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-52-column-3-sentence-1) |
|
||||
|
||||
[6](#prop-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1590)
|
||||
|
||||
[*Example [1](#prop-example-1)*: is_const_v<const volatile int> // true is_const_v<const int*> // false is_const_v<const int&> // false is_const_v<int[3]> // false is_const_v<const int[3]> // true â *end example*]
|
||||
|
||||
[7](#prop-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1601)
|
||||
|
||||
[*Example [2](#prop-example-2)*: remove_const_t<const volatile int> // volatile int remove_const_t<const int* const> // const int* remove_const_t<const int&> // const int& remove_const_t<const int[3]> // int[3] â *end example*]
|
||||
|
||||
[8](#prop-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1611)
|
||||
|
||||
[*Example [3](#prop-example-3)*: // Given:struct P final { };union U1 { };union U2 final { };
|
||||
|
||||
// the following assertions hold:static_assert(!is_final_v<int>);static_assert(is_final_v<P>);static_assert(!is_final_v<U1>);static_assert(is_final_v<U2>); â *end example*]
|
||||
|
||||
[9](#prop-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1628)
|
||||
|
||||
The predicate condition for a template specializationis_constructible<T, Args...> shall be satisfied if and only if the
|
||||
following variable definition would be well-formed for some invented variable t:
|
||||
|
||||
T t(declval<Args>()...);
|
||||
|
||||
[*Note [7](#prop-note-7)*:
|
||||
|
||||
These tokens are never interpreted as a function declaration[.](#prop-9.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Access checking is performed as if in a context unrelated to T and any of the Args[.](#prop-9.sentence-3)
|
||||
|
||||
Only the validity of the immediate context of the
|
||||
variable initialization is considered[.](#prop-9.sentence-4)
|
||||
|
||||
[*Note [8](#prop-note-8)*:
|
||||
|
||||
The evaluation of the
|
||||
initialization can result in side effects such as the instantiation of class
|
||||
template specializations and function template specializations, the generation
|
||||
of implicitly-defined functions, and so on[.](#prop-9.sentence-5)
|
||||
|
||||
Such side effects are not in the
|
||||
âimmediate contextâ and can result in the program being ill-formed[.](#prop-9.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[10](#prop-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1652)
|
||||
|
||||
The predicate condition for a template specializationhas_unique_object_representations<T> shall be satisfied if and only if
|
||||
|
||||
- [(10.1)](#prop-10.1)
|
||||
|
||||
T is trivially copyable, and
|
||||
|
||||
- [(10.2)](#prop-10.2)
|
||||
|
||||
any two objects of type T with the same value
|
||||
have the same object representation, where
|
||||
* [(10.2.1)](#prop-10.2.1)
|
||||
|
||||
two objects of array or non-union class type are considered to have the same value
|
||||
if their respective sequences of direct subobjects have the same values, and
|
||||
|
||||
* [(10.2.2)](#prop-10.2.2)
|
||||
|
||||
two objects of union type are considered to have the same value
|
||||
if they have the same active member and the corresponding members have the same value[.](#prop-10.sentence-1)
|
||||
|
||||
The set of scalar types for which this condition holds isimplementation-defined[.](#prop-10.sentence-2)
|
||||
|
||||
[*Note [9](#prop-note-9)*:
|
||||
|
||||
If a type has padding bits, the condition does not hold;
|
||||
otherwise, the condition holds true for integral types[.](#prop-10.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
53
cppdraft/meta/unary/cat.md
Normal file
53
cppdraft/meta/unary/cat.md
Normal file
@@ -0,0 +1,53 @@
|
||||
[meta.unary.cat]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary.cat)
|
||||
|
||||
### 21.3.6 Unary type traits [[meta.unary]](meta.unary#cat)
|
||||
|
||||
#### 21.3.6.2 Primary type categories [meta.unary.cat]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L926)
|
||||
|
||||
The primary type categories specified in Table [52](#tab:meta.unary.cat "Table 52: Primary type category predicates") correspond to the descriptions given in
|
||||
subclause [[basic.types]](basic.types "6.9 Types") of the C++ standard[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L931)
|
||||
|
||||
For any given type T, the result of applying one of these templates toT and to cv T shall yield the same result[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L935)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
For any given type T, exactly one of the primary type categories
|
||||
has a value member that evaluates to true[.](#3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Table [52](#tab:meta.unary.cat) — Primary type category predicates [[tab:meta.unary.cat]](./tab:meta.unary.cat)
|
||||
|
||||
| [ð](#tab:meta.unary.cat-row-1)<br>**Template** | **Condition** | **Comments** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.cat-row-2)<br>template<class T> struct [is_void](#lib:is_void "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is void | |
|
||||
| [ð](#tab:meta.unary.cat-row-3)<br>template<class T> struct [is_null_pointer](#lib:is_null_pointer "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is nullptr_t ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-4)<br>template<class T> struct [is_integral](#lib:is_integral "21.3.6.2 Primary type categories [meta.unary.cat]"); | T is an integral type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-5)<br>template<class T> struct is_floating_point; | T is a floating-point type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-6)<br>template<class T> struct is_array; | T is an array type ([[basic.compound]](basic.compound "6.9.4 Compound types")) of known or unknown extent | Class template array ([[array]](array "23.3.3 Class template array")) is not an array type[.](#tab:meta.unary.cat-row-6-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.cat-row-7)<br>template<class T> struct is_pointer; | T is a pointer type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | Includes pointers to functions but not pointers to non-static members[.](#tab:meta.unary.cat-row-7-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.cat-row-8)<br>template<class T> struct is_lvalue_reference; | T is an lvalue reference type ([[dcl.ref]](dcl.ref "9.3.4.3 References")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-9)<br>template<class T> struct is_rvalue_reference; | T is an rvalue reference type ([[dcl.ref]](dcl.ref "9.3.4.3 References")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-10)<br>template<class T> struct is_member_object_pointer; | T is a pointer to data member | |
|
||||
| [ð](#tab:meta.unary.cat-row-11)<br>template<class T> struct is_member_function_pointer; | T is a pointer to member function | |
|
||||
| [ð](#tab:meta.unary.cat-row-12)<br>template<class T> struct is_enum; | T is an enumeration type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-13)<br>template<class T> struct is_union; | T is a union type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-14)<br>template<class T> struct is_class; | T is a non-union class type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-15)<br>template<class T> struct is_function; | T is a function type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.cat-row-16)<br>template<class T> struct is_reflection; | T is std::meta::info ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
34
cppdraft/meta/unary/comp.md
Normal file
34
cppdraft/meta/unary/comp.md
Normal file
@@ -0,0 +1,34 @@
|
||||
[meta.unary.comp]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary.comp)
|
||||
|
||||
### 21.3.6 Unary type traits [[meta.unary]](meta.unary#comp)
|
||||
|
||||
#### 21.3.6.3 Composite type traits [meta.unary.comp]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1014)
|
||||
|
||||
The templates specified in Table [53](#tab:meta.unary.comp "Table 53: Composite type category predicates") provide convenient compositions of the primary type categories,
|
||||
corresponding to the descriptions given in subclause [[basic.types]](basic.types "6.9 Types")[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1019)
|
||||
|
||||
For any given type T, the result of applying one of these templates toT and to cv T shall yield the same result[.](#2.sentence-1)
|
||||
|
||||
Table [53](#tab:meta.unary.comp) — Composite type category predicates [[tab:meta.unary.comp]](./tab:meta.unary.comp)
|
||||
|
||||
| [ð](#tab:meta.unary.comp-row-1)<br>**Template** | **Condition** | **Comments** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.comp-row-2)<br>template<class T> struct is_reference; | T is an lvalue reference or an rvalue reference | |
|
||||
| [ð](#tab:meta.unary.comp-row-3)<br>template<class T> struct is_arithmetic; | T is an arithmetic type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-4)<br>template<class T> struct is_fundamental; | T is a fundamental type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-5)<br>template<class T> struct is_object; | T is an object type ([[basic.types.general]](basic.types.general#term.object.type "6.9.1 General")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-6)<br>template<class T> struct is_scalar; | T is a scalar type ([[basic.types.general]](basic.types.general#term.scalar.type "6.9.1 General")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-7)<br>template<class T> struct is_compound; | T is a compound type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
| [ð](#tab:meta.unary.comp-row-8)<br>template<class T> struct is_member_pointer; | T is a pointer-to-member type ([[basic.compound]](basic.compound "6.9.4 Compound types")) | |
|
||||
22
cppdraft/meta/unary/general.md
Normal file
22
cppdraft/meta/unary/general.md
Normal file
@@ -0,0 +1,22 @@
|
||||
[meta.unary.general]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary.general)
|
||||
|
||||
### 21.3.6 Unary type traits [[meta.unary]](meta.unary#general)
|
||||
|
||||
#### 21.3.6.1 General [meta.unary.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L913)
|
||||
|
||||
Subclause [[meta.unary]](meta.unary "21.3.6 Unary type traits") contains templates that may be used to query the
|
||||
properties of a type at compile time[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L917)
|
||||
|
||||
Each of these templates shall be a[*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") with a base characteristic oftrue_type if the corresponding condition is true, otherwisefalse_type[.](#2.sentence-1)
|
||||
204
cppdraft/meta/unary/prop.md
Normal file
204
cppdraft/meta/unary/prop.md
Normal file
@@ -0,0 +1,204 @@
|
||||
[meta.unary.prop]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary.prop)
|
||||
|
||||
### 21.3.6 Unary type traits [[meta.unary]](meta.unary#prop)
|
||||
|
||||
#### 21.3.6.4 Type properties [meta.unary.prop]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1063)
|
||||
|
||||
The templates specified in Table [54](#tab:meta.unary.prop "Table 54: Type property predicates") provide access to some of the more important properties of types[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1067)
|
||||
|
||||
It is unspecified whether the library defines any full or partial
|
||||
specializations of any of these templates[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1071)
|
||||
|
||||
For all of the class templates X declared in this subclause,
|
||||
instantiating that template with a template-argument that is a class
|
||||
template specialization may result in the implicit instantiation of
|
||||
the template argument if and only if the semantics of X require that
|
||||
the argument is a complete type[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1078)
|
||||
|
||||
For the purpose of defining the templates in this subclause,
|
||||
a function call expression declval<T>() for any type T is considered to be a trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions")) function call
|
||||
that is not an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) of declval in the context of the corresponding definition
|
||||
notwithstanding the restrictions of [[declval]](declval "22.2.6 Function template declval")[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1086)
|
||||
|
||||
For the purpose of defining the templates in this subclause,
|
||||
let *VAL*<T> for some type T be
|
||||
an expression defined as follows:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If T is a reference or function type,*VAL*<T> is an expression
|
||||
with the same type and value category as declval<T>()[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
Otherwise, *VAL*<T> is a prvalue
|
||||
that initially has type T[.](#5.2.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
If T is cv-qualified,
|
||||
the cv-qualification is subject to adjustment ([[expr.type]](expr.type "7.2.2 Type"))[.](#5.2.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
Table [54](#tab:meta.unary.prop) — Type property predicates [[tab:meta.unary.prop]](./tab:meta.unary.prop)
|
||||
|
||||
| [ð](#tab:meta.unary.prop-row-1)<br>**Template** | **Condition** | **Preconditions** |
|
||||
| --- | --- | --- |
|
||||
| [ð](#tab:meta.unary.prop-row-2)<br>template<class T> struct is_const; | T is const-qualified ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-3)<br>template<class T> struct is_volatile; | T is volatile-qualified ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-4)<br>template<class T> struct is_trivially_copyable; | T is a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-4-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-5)<br>template<class T> struct is_trivially_relocatable; | T is a trivially relocatable type ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-5-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-6)<br>template<class T> struct is_replaceable; | T is a replaceable type ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-6-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-7)<br>template<class T> struct is_standard_layout; | T is a standard-layout type ([[basic.types.general]](basic.types.general#term.standard.layout.type "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-7-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-8)<br>template<class T> struct is_empty; | T is a class type, but not a union type, with no non-static data members other than subobjects of zero size, no virtual member functions, no virtual base classes, and no base class B for which is_empty_v<B> is false[.](#tab:meta.unary.prop-row-8-column-2-sentence-1) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-8-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-9)<br>template<class T> struct is_polymorphic; | T is a polymorphic class ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-9-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-10)<br>template<class T> struct is_abstract; | T is an abstract class ([[class.abstract]](class.abstract "11.7.4 Abstract classes")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-10-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-11)<br>template<class T> struct is_final; | T is a class type marked with the [*class-property-specifier*](class.pre#nt:class-property-specifier "11.1 Preamble [class.pre]")final ([[class.pre]](class.pre "11.1 Preamble"))[.](#tab:meta.unary.prop-row-11-column-2-sentence-1)<br>[*Note [2](#tab:meta.unary.prop-row-11-column-2-note-2)*:<br>A union is a class type that can be marked with final[.](#tab:meta.unary.prop-row-11-column-2-sentence-2) â *end note*] | If T is a class type, T shall be a complete type[.](#tab:meta.unary.prop-row-11-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-12)<br>template<class T> struct [is_aggregate](#lib:is_aggregate "21.3.6.4 Type properties [meta.unary.prop]"); | T is an aggregate type ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")) | T shall be an array type, a complete type, or cv void[.](#tab:meta.unary.prop-row-12-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-13)<br>template<class T> struct is_consteval_only; | T is consteval-only ([[basic.types.general]](basic.types.general "6.9.1 General")) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-13-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-14)<br>template<class T> struct is_signed; | If is_arithmetic_v<T> is true, the same result as T(-1) < T(0); otherwise, false | |
|
||||
| [ð](#tab:meta.unary.prop-row-15)<br>template<class T> struct [is_unsigned](#lib:is_unsigned "21.3.6.4 Type properties [meta.unary.prop]"); | If is_arithmetic_v<T> is true, the same result as T(0) < T(-1); otherwise, false | |
|
||||
| [ð](#tab:meta.unary.prop-row-16)<br>template<class T> struct [is_bounded_array](#lib:is_bounded_array "21.3.6.4 Type properties [meta.unary.prop]"); | T is an array type of known bound ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-17)<br>template<class T> struct is_unbounded_array; | T is an array type of unknown bound ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-18)<br>template<class T> struct is_scoped_enum; | T is a scoped enumeration ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")) | |
|
||||
| [ð](#tab:meta.unary.prop-row-19)<br>template<class T, class... Args> struct is_constructible; | For a function type T or for a cv void type T, is_constructible_v<T, Args...> is false, otherwise *see below* | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-19-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-20)<br>template<class T> struct is_default_constructible; | is_constructible_v<T> is true[.](#tab:meta.unary.prop-row-20-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-20-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-21)<br>template<class T> struct is_copy_constructible; | For a referenceable type T ([[defns.referenceable]](defns.referenceable "3.45 referenceable type")), the same result as is_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-21-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-21-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-22)<br>template<class T> struct is_move_constructible; | For a referenceable type T, the same result as is_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-22-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-22-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-23)<br>template<class T, class U> struct is_assignable; | The expression declval<T>() = declval<U>() is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence"))[.](#tab:meta.unary.prop-row-23-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-23-column-2-sentence-2)<br>Only the validity of the immediate context of the assignment expression is considered[.](#tab:meta.unary.prop-row-23-column-2-sentence-3)<br>[*Note [3](#tab:meta.unary.prop-row-23-column-2-note-3)*:<br>The compilation of the expression can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-23-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-23-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-23-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-24)<br>template<class T> struct is_copy_assignable; | For a referenceable type T, the same result as is_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-24-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-24-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-25)<br>template<class T> struct is_move_assignable; | For a referenceable type T, the same result as is_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-25-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-25-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-26)<br>template<class T, class U> struct is_swappable_with; | The expressions swap(declval<T>(), declval<U>()) and swap(declval<U>(), declval<T>()) are each well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")) in an overload-resolution context for swappable values ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements"))[.](#tab:meta.unary.prop-row-26-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-26-column-2-sentence-2)<br>Only the validity of the immediate context of the swap expressions is considered[.](#tab:meta.unary.prop-row-26-column-2-sentence-3)<br>[*Note [4](#tab:meta.unary.prop-row-26-column-2-note-4)*:<br>The compilation of the expressions can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-26-column-2-sentence-4)<br>Such side effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-26-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-26-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-27)<br>template<class T> struct is_swappable; | For a referenceable type T, the same result as is_swappable_with_v<T&, T&>, otherwise false[.](#tab:meta.unary.prop-row-27-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-27-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-28)<br>template<class T> struct is_destructible; | Either T is a reference type, or T is a complete object type for which the expression declval<U&>().~U() is well-formed when treated as an unevaluated operand ([[expr.context]](expr.context#term.unevaluated.operand "7.2.3 Context dependence")), where U is remove_all_extents_t<T>[.](#tab:meta.unary.prop-row-28-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-28-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-29)<br>template<class T, class... Args> struct is_trivially_constructible; | is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known to call no operation that is not trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions"))[.](#tab:meta.unary.prop-row-29-column-2-sentence-1) | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-29-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-30)<br>template<class T> struct is_trivially_default_constructible; | is_trivially_constructible_v<T> is true[.](#tab:meta.unary.prop-row-30-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-30-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-31)<br>template<class T> struct is_trivially_copy_constructible; | For a referenceable type T, the same result as is_trivially_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-31-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-31-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-32)<br>template<class T> struct is_trivially_move_constructible; | For a referenceable type T, the same result as is_trivially_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-32-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-32-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-33)<br>template<class T, class U> struct is_trivially_assignable; | is_assignable_v<T, U> is true and the assignment, as defined by is_assignable, is known to call no operation that is not trivial ([[depr.meta.types]](depr.meta.types#term.trivial.type "D.13 Deprecated type traits"), [[special]](special "11.4.4 Special member functions"))[.](#tab:meta.unary.prop-row-33-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-33-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-34)<br>template<class T> struct is_trivially_copy_assignable; | For a referenceable type T, the same result as is_trivially_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-34-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-34-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-35)<br>template<class T> struct is_trivially_move_assignable; | For a referenceable type T, the same result as is_trivially_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-35-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-35-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-36)<br>template<class T> struct is_trivially_destructible; | is_destructible_v<T> is true and remove_all_extents_t<T> is either a non-class type or a class type with a trivial destructor[.](#tab:meta.unary.prop-row-36-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-36-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-37)<br>template<class T, class... Args> struct is_nothrow_constructible; | is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-37-column-2-sentence-1) | T and all types in the template parameter pack Args shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-37-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-38)<br>template<class T> struct is_nothrow_default_constructible; | is_nothrow_constructible_v<T> is true[.](#tab:meta.unary.prop-row-38-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-38-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-39)<br>template<class T> struct is_nothrow_copy_constructible; | For a referenceable type T, the same result as is_nothrow_constructible_v<T, const T&>, otherwise false[.](#tab:meta.unary.prop-row-39-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-39-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-40)<br>template<class T> struct is_nothrow_move_constructible; | For a referenceable type T, the same result as is_nothrow_constructible_v<T, T&&>, otherwise false[.](#tab:meta.unary.prop-row-40-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-40-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-41)<br>template<class T, class U> struct is_nothrow_assignable; | is_assignable_v<T, U> is true and the assignment is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-41-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-41-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-42)<br>template<class T> struct is_nothrow_copy_assignable; | For a referenceable type T, the same result as is_nothrow_assignable_v<T&, const T&>, otherwise false[.](#tab:meta.unary.prop-row-42-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-42-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-43)<br>template<class T> struct is_nothrow_move_assignable; | For a referenceable type T, the same result as is_nothrow_assignable_v<T&, T&&>, otherwise false[.](#tab:meta.unary.prop-row-43-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-43-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-44)<br>template<class T, class U> struct is_nothrow_swappable_with; | is_swappable_with_v<T, U> is true and each swap expression of the definition of is_swappable_with<T, U> is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-44-column-2-sentence-1) | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-44-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-45)<br>template<class T> struct is_nothrow_swappable; | For a referenceable type T, the same result as is_nothrow_swappable_with_v<T&, T&>, otherwise false[.](#tab:meta.unary.prop-row-45-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-45-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-46)<br>template<class T> struct is_nothrow_destructible; | is_destructible_v<T> is true and the indicated destructor is known not to throw any exceptions ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))[.](#tab:meta.unary.prop-row-46-column-2-sentence-1) | T shall be a complete type, cv void, or an array of unknown bound[.](#tab:meta.unary.prop-row-46-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-47)<br>template<class T> struct is_nothrow_relocatable; | is_trivially_relocatable_v<T> ||(is_nothrow_move_constructible_v<remove_all_extents_t<T>> && is_nothrow_destructible_v<remove_all_extents_t<T>>) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-47-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-48)<br>template<class T> struct is_implicit_lifetime; | T is an implicit-lifetime type ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1 General"))[.](#tab:meta.unary.prop-row-48-column-2-sentence-1) | T shall be an array type, a complete type, or cv void[.](#tab:meta.unary.prop-row-48-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-49)<br>template<class T> struct has_virtual_destructor; | T has a virtual destructor ([[class.dtor]](class.dtor "11.4.7 Destructors")) | If T is a non-union class type, T shall be a complete type[.](#tab:meta.unary.prop-row-49-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-50)<br>template<class T> struct has_unique_object_representations; | For an array type T, the same result as has_unique_object_representations_v<remove_all_extents_t<T>>, otherwise *see below*[.](#tab:meta.unary.prop-row-50-column-2-sentence-1) | remove_all_extents_t<T> shall be a complete type or cv void[.](#tab:meta.unary.prop-row-50-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-51)<br>template<class T, class U> struct reference_constructs_from_temporary; | T is a reference type, and the initialization T t(*VAL*<U>); is well-formed and binds t to a temporary object whose lifetime is extended ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#tab:meta.unary.prop-row-51-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-51-column-2-sentence-2)<br>Only the validity of the immediate context of the variable initialization is considered[.](#tab:meta.unary.prop-row-51-column-2-sentence-3)<br>[*Note [5](#tab:meta.unary.prop-row-51-column-2-note-5)*:<br>The initialization can result in effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-51-column-2-sentence-4)<br>Such effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-51-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-51-column-3-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop-row-52)<br>template<class T, class U> struct reference_converts_from_temporary; | T is a reference type, and the initialization T t = *VAL*<U>; is well-formed and binds t to a temporary object whose lifetime is extended ([[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#tab:meta.unary.prop-row-52-column-2-sentence-1)<br>Access checking is performed as if in a context unrelated to T and U[.](#tab:meta.unary.prop-row-52-column-2-sentence-2)<br>Only the validity of the immediate context of the variable initialization is considered[.](#tab:meta.unary.prop-row-52-column-2-sentence-3)<br>[*Note [6](#tab:meta.unary.prop-row-52-column-2-note-6)*:<br>The initialization can result in effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on[.](#tab:meta.unary.prop-row-52-column-2-sentence-4)<br>Such effects are not in the âimmediate contextâ and can result in the program being ill-formed[.](#tab:meta.unary.prop-row-52-column-2-sentence-5) â *end note*] | T and U shall be complete types, cv void, or arrays of unknown bound[.](#tab:meta.unary.prop-row-52-column-3-sentence-1) |
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1590)
|
||||
|
||||
[*Example [1](#example-1)*: is_const_v<const volatile int> // true is_const_v<const int*> // false is_const_v<const int&> // false is_const_v<int[3]> // false is_const_v<const int[3]> // true â *end example*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1601)
|
||||
|
||||
[*Example [2](#example-2)*: remove_const_t<const volatile int> // volatile int remove_const_t<const int* const> // const int* remove_const_t<const int&> // const int& remove_const_t<const int[3]> // int[3] â *end example*]
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1611)
|
||||
|
||||
[*Example [3](#example-3)*: // Given:struct P final { };union U1 { };union U2 final { };
|
||||
|
||||
// the following assertions hold:static_assert(!is_final_v<int>);static_assert(is_final_v<P>);static_assert(!is_final_v<U1>);static_assert(is_final_v<U2>); â *end example*]
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1628)
|
||||
|
||||
The predicate condition for a template specializationis_constructible<T, Args...> shall be satisfied if and only if the
|
||||
following variable definition would be well-formed for some invented variable t:
|
||||
|
||||
T t(declval<Args>()...);
|
||||
|
||||
[*Note [7](#note-7)*:
|
||||
|
||||
These tokens are never interpreted as a function declaration[.](#9.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
Access checking is performed as if in a context unrelated to T and any of the Args[.](#9.sentence-3)
|
||||
|
||||
Only the validity of the immediate context of the
|
||||
variable initialization is considered[.](#9.sentence-4)
|
||||
|
||||
[*Note [8](#note-8)*:
|
||||
|
||||
The evaluation of the
|
||||
initialization can result in side effects such as the instantiation of class
|
||||
template specializations and function template specializations, the generation
|
||||
of implicitly-defined functions, and so on[.](#9.sentence-5)
|
||||
|
||||
Such side effects are not in the
|
||||
âimmediate contextâ and can result in the program being ill-formed[.](#9.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1652)
|
||||
|
||||
The predicate condition for a template specializationhas_unique_object_representations<T> shall be satisfied if and only if
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
T is trivially copyable, and
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
any two objects of type T with the same value
|
||||
have the same object representation, where
|
||||
* [(10.2.1)](#10.2.1)
|
||||
|
||||
two objects of array or non-union class type are considered to have the same value
|
||||
if their respective sequences of direct subobjects have the same values, and
|
||||
|
||||
* [(10.2.2)](#10.2.2)
|
||||
|
||||
two objects of union type are considered to have the same value
|
||||
if they have the same active member and the corresponding members have the same value[.](#10.sentence-1)
|
||||
|
||||
The set of scalar types for which this condition holds isimplementation-defined[.](#10.sentence-2)
|
||||
|
||||
[*Note [9](#note-9)*:
|
||||
|
||||
If a type has padding bits, the condition does not hold;
|
||||
otherwise, the condition holds true for integral types[.](#10.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
40
cppdraft/meta/unary/prop/query.md
Normal file
40
cppdraft/meta/unary/prop/query.md
Normal file
@@ -0,0 +1,40 @@
|
||||
[meta.unary.prop.query]
|
||||
|
||||
# 21 Metaprogramming library [[meta]](./#meta)
|
||||
|
||||
## 21.3 Metaprogramming and type traits [[type.traits]](type.traits#meta.unary.prop.query)
|
||||
|
||||
### 21.3.7 Type property queries [meta.unary.prop.query]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1676)
|
||||
|
||||
The templates specified in Table [55](#tab:meta.unary.prop.query "Table 55: Type property queries") may be used to query properties of types at compile time[.](#1.sentence-1)
|
||||
|
||||
Table [55](#tab:meta.unary.prop.query) — Type property queries [[tab:meta.unary.prop.query]](./tab:meta.unary.prop.query)
|
||||
|
||||
| [ð](#tab:meta.unary.prop.query-row-1)<br>**Template** | **Value** |
|
||||
| --- | --- |
|
||||
| [ð](#tab:meta.unary.prop.query-row-2)<br>template<class T> struct alignment_of; | alignof(T)[.](#tab:meta.unary.prop.query-row-2-column-2-sentence-1)<br> *Mandates*: alignof(T) is a valid expression ([[expr.alignof]](expr.alignof "7.6.2.6 Alignof")) |
|
||||
| [ð](#tab:meta.unary.prop.query-row-3)<br>template<class T> struct rank; | If T is an array type, an integer value representing the number of dimensions of T; otherwise, 0[.](#tab:meta.unary.prop.query-row-3-column-2-sentence-1) |
|
||||
| [ð](#tab:meta.unary.prop.query-row-4)<br>template<class T, unsigned I = 0> struct extent; | If T is not an array type, or if it has rank less than or equal to I, or if I is 0 and T has type âarray of unknown bound of Uâ, then 0; otherwise, the bound ([[dcl.array]](dcl.array "9.3.4.5 Arrays")) of the Ith dimension of T, where indexing of I is zero-based |
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1713)
|
||||
|
||||
Each of these templates shall be a [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements")) with a
|
||||
base characteristic of integral_constant<size_t, Value>[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1717)
|
||||
|
||||
[*Example [1](#example-1)*: // the following assertions hold:static_assert(rank_v<int> == 0);static_assert(rank_v<int[2]> == 1);static_assert(rank_v<int[][4]> == 2); â *end example*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/meta.tex#L1727)
|
||||
|
||||
[*Example [2](#example-2)*: // the following assertions hold:static_assert(extent_v<int> == 0);static_assert(extent_v<int[2]> == 2);static_assert(extent_v<int[2][4]> == 2);static_assert(extent_v<int[][4]> == 0);static_assert(extent_v<int, 1> == 0);static_assert(extent_v<int[2], 1> == 0);static_assert(extent_v<int[2][4], 1> == 4);static_assert(extent_v<int[][4], 1> == 4); â *end example*]
|
||||
Reference in New Issue
Block a user