From bdbffea0a5b9761800086137631e010d1c7230d2 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Tue, 10 Dec 2024 21:57:44 -0600 Subject: [PATCH] Adding null-terminated requirement --- 2996_reflection/p2996r8.html | 1197 +++++++++++++++++---------------- 2996_reflection/reflection.md | 14 +- 2 files changed, 620 insertions(+), 591 deletions(-) diff --git a/2996_reflection/p2996r8.html b/2996_reflection/p2996r8.html index 681527db..9f74289b 100644 --- a/2996_reflection/p2996r8.html +++ b/2996_reflection/p2996r8.html @@ -786,9 +786,9 @@

Contents

  • 7.5 [expr.prim] Primary expressions
  • -
  • 7.5.4.1 +
  • 7.5.5.1 [expr.prim.id.general] General
  • -
  • 7.5.4.3 +
  • 7.5.5.3 [expr.prim.id.qual] Qualified names
  • 7.5.8* [expr.prim.splice] @@ -5831,7 +5831,7 @@

    7.5 7.5.4.1 +

    7.5.5.1 [expr.prim.id.general] General

    Modify paragraph 2 to avoid transforming non-static members into @@ -5843,7 +5843,7 @@

    7.5.4.1 If an id-expression E denotes a non-static non-type member of some class C at a -point where the current class (7.5.2 [expr.prim.this]) is +point where the current class (7.5.3 [expr.prim.this]) is X and

    Note 3: The implicit -transformation (7.5.4 [expr.prim.id]) whereby +transformation (7.5.5 [expr.prim.id]) whereby an id-expression denoting a non-static member becomes a class member access does not apply to a splice-expression. @@ -7980,7 +7980,7 @@

    12.2.2.2 qualified function call. If the current class is, or is derived from, T, and the keyword this -(7.5.2 [expr.prim.this]) +(7.5.3 [expr.prim.this]) refers to it, then the implied object argument is (*this). Otherwise, a contrived object of type T becomes the implied object @@ -9468,6 +9468,23 @@

    [meta.ref — end note ] +

    3 +Any function in namespace +std::meta +that whose return type is +string_view or +u8string_view returns an object +V such that V.data()[V.size()] == '\0'.

    +
    +Example 2: +
    struct C { };
    +
    +constexpr string_view sv = identifier_of(^^C);
    +static_assert(sv == "C");
    +static_assert(sv.data()[0] == 'C');
    +static_assert(sv.data()[1] == '\0');
    + — end example ] +
    @@ -9476,11 +9493,11 @@

    [
    -
    enum class operators {
    -  see below;
    -};
    -using enum operators;
    -

    1 +

    enum class operators {
    +  see below;
    +};
    +using enum operators;
    +

    1 This enum class specifies constants used to identify operators that can be overloaded, with the meanings listed in Table 1. The values of the constants are distinct.

    @@ -9732,24 +9749,24 @@

    [ -
    consteval operators operator_of(info r);
    -

    2 +

    consteval operators operator_of(info r);
    +

    2 Constant When: r represents an operator function or operator function template.

    -

    3 +

    3 Returns: The value of the enumerator from operators whose corresponding operator-function-id is the unqualified name of the entity represented by r.

    -
    consteval string_view symbol_of(operators op);
    -consteval u8string_view u8symbol_of(operators op);
    -

    4 +

    consteval string_view symbol_of(operators op);
    +consteval u8string_view u8symbol_of(operators op);
    +

    4 Constant When: The value of op corresponds to one of the enumerators in operators.

    -

    5 -Returns: A string_view or +

    5 +Returns: string_view or u8string_view containing the characters of the operator symbol name corresponding to op, respectively encoded with the @@ -9762,15 +9779,15 @@

    -
    consteval bool has_identifier(info r);
    -

    1 +

    consteval bool has_identifier(info r);
    +

    1 Returns:

      -
    • (1.1) +
    • (1.1) If r is an unnamed entity other than a class that has a typedef name for linkage purposes (9.2.4 [dcl.typedef]), then false.
    • -
    • (1.2) +
    • (1.2) Otherwise, if r represents a class type C, then true when @@ -9779,14 +9796,14 @@

      C has a typedef name for linkage purposes. Otherwise, false.

    • -
    • (1.3) +
    • (1.3) Otherwise, if r represents a function, then true if the function is not a function template specialization, constructor, destructor, operator function, or conversion function. Otherwise, false.
    • -
    • (1.4) +
    • (1.4) Otherwise, if r represents a function template, then true if @@ -9794,20 +9811,20 @@

      false.

    • -
    • (1.5) +
    • (1.5) Otherwise, if r represents variable or a type alias, then !has_template_arguments(r).
    • -
    • (1.6) +
    • (1.6) Otherwise, if r represents a structured binding, enumerator, non-static data member, template, namespace, or namespace alias, then true. Otherwise, false.
    • -
    • (1.7) +
    • (1.7) Otherwise, if r represents a direct base class relationship, then has_identifier(type_of(r)).
    • -
    • (1.8) +
    • (1.8) Otherwise, r represents a data member description (T, N, @@ -9816,39 +9833,39 @@

      NUA) (11.4.1 [class.mem.general]); N != -1.

    -
    consteval string_view identifier_of(info r);
    -consteval u8string_view u8identifier_of(info r);
    -

    2 +

    consteval string_view identifier_of(info r);
    +consteval u8string_view u8identifier_of(info r);
    +

    2 Let E be UTF-8 if returning a u8string_view, and otherwise the ordinary literal encoding.

    -

    3 +

    3 Constant When: has_identifier(r) is true and the identifier that would be returned (see below) is representable by E.

    -

    4 +

    4 Returns:

      -
    • (4.1) +
    • (4.1) If r represents a literal operator or literal operator template, then the ud-suffix of the operator or operator template.
    • -
    • (4.2) +
    • (4.2) Otherwise, if r represents a class type, then either the typedef name for linkage purposes or the identifier introduced by the declaration of the represented type.
    • -
    • (4.3) +
    • (4.3) Otherwise, if r represents an entity, then the identifier introduced by the declaration of that entity.
    • -
    • (4.4) +
    • (4.4) Otherwise, if r represents a direct base class relationship, then identifier_of(type_of(r)) or u8identifier_of(type_of(r)), respectively.
    • -
    • (4.5) +
    • (4.5) Otherwise, r represents a data member description (T, N, @@ -9860,23 +9877,23 @@

      N encoded with E.

    -
    consteval string_view display_string_of(info r);
    -consteval u8string_view u8display_string_of(info r);
    -

    5 +

    consteval string_view display_string_of(info r);
    +consteval u8string_view u8display_string_of(info r);
    +

    5 Returns: An implementation-defined string_view or u8string_view, respectively.

    -

    6 +

    6 Recommended practice: Where possible, implementations should return a string suitable for identifying the represented construct.

    -
    consteval source_location source_location_of(info r);
    -

    7 +

    consteval source_location source_location_of(info r);
    +

    7 Returns: If r represents a value, a non-class type, the global namespace, or a data member description, then source_location{}. Otherwise, an implementation-defined source_location value.

    -

    8 +

    8 Recommended practice: If r represents an entity, name, or direct base class relationship that was introduced by a declaration, implementations should return a value @@ -9892,59 +9909,59 @@

    [meta.ref
    -
    consteval bool is_public(info r);
    -consteval bool is_protected(info r);
    -consteval bool is_private(info r);
    -

    1 +

    consteval bool is_public(info r);
    +consteval bool is_protected(info r);
    +consteval bool is_private(info r);
    +

    1 Returns: true if r represents a class member or direct base class relationship that is public, protected, or private, respectively. Otherwise, false.

    -
    consteval bool is_virtual(info r);
    -

    2 +

    consteval bool is_virtual(info r);
    +

    2 Returns: true if r represents either a virtual member function or a direct base class relationship that is virtual. Otherwise, false.

    -
    consteval bool is_pure_virtual(info r);
    -consteval bool is_override(info r);
    -

    3 +

    consteval bool is_pure_virtual(info r);
    +consteval bool is_override(info r);
    +

    3 Returns: true if r represents a member function that is pure virtual or overrides another member function, respectively. Otherwise, false.

    -
    consteval bool is_final(info r);
    -

    4 +

    consteval bool is_final(info r);
    +

    4 Returns: true if r represents a final class or a final member function. Otherwise, false.

    -
    consteval bool is_deleted(info r);
    -consteval bool is_defaulted(info r);
    -

    5 +

    consteval bool is_deleted(info r);
    +consteval bool is_defaulted(info r);
    +

    5 Returns: true if r represents a function that is a deleted function ([dcl.fct.def.delete]) or defined as defaulted ([dcl.fct.def.default]), respectively. Otherwise, false.

    -
    consteval bool is_user_provided(info r);
    -consteval bool is_user_declared(info r);
    -

    6 +

    consteval bool is_user_provided(info r);
    +consteval bool is_user_declared(info r);
    +

    6 Returns: true if r represents a function that is user-provided or user-declared (9.5.2 [dcl.fct.def.default]), respectively. Otherwise, false.

    -
    consteval bool is_explicit(info r);
    -

    7 +

    consteval bool is_explicit(info r);
    +

    7 Returns: true if r represents a member function that @@ -9958,8 +9975,8 @@

    [meta.ref false because in general such queries for templates cannot be answered. — end note ]

    -
    consteval bool is_noexcept(info r);
    -

    8 +

    consteval bool is_noexcept(info r);
    +

    8 Returns: true if r represents a @@ -9975,8 +9992,8 @@

    [meta.ref false because in general such queries for templates cannot be answered. — end note ]

    -
    consteval bool is_bit_field(info r);
    -

    9 +

    consteval bool is_bit_field(info r);
    +

    9 Returns: true if r represents a bit-field, or if @@ -9989,16 +10006,16 @@

    [meta.ref for which W is not -1. Otherwise, false.

    -
    consteval bool is_enumerator(info r);
    -

    10 +

    consteval bool is_enumerator(info r);
    +

    10 Returns: true if r represents an enumerator. Otherwise, false.

    -
    consteval bool is_const(info r);
    -consteval bool is_volatile(info r);
    -

    11 +

    consteval bool is_const(info r);
    +consteval bool is_volatile(info r);
    +

    11 Returns: true if r represents a const or volatile @@ -10006,38 +10023,38 @@

    [meta.ref (respectively), or an object, variable, non-static data member, or function with such a type. Otherwise, false.

    -
    consteval bool is_mutable_member(info r);
    -

    12 +

    consteval bool is_mutable_member(info r);
    +

    12 Returns: true if r represents a mutable non-static data member. Otherwise, false.

    -
    consteval bool is_lvalue_reference_qualified(info r);
    -consteval bool is_rvalue_reference_qualified(info r);
    -

    13 +

    consteval bool is_lvalue_reference_qualified(info r);
    +consteval bool is_rvalue_reference_qualified(info r);
    +

    13 Returns: true if r represents a lvalue- or rvalue-reference qualified function type (respectively), or a member function with such a type. Otherwise, false.

    -
    consteval bool has_static_storage_duration(info r);
    -consteval bool has_thread_storage_duration(info r);
    -consteval bool has_automatic_storage_duration(info r);
    -

    14 +

    consteval bool has_static_storage_duration(info r);
    +consteval bool has_thread_storage_duration(info r);
    +consteval bool has_automatic_storage_duration(info r);
    +

    14 Returns: true if r represents an object or variable that has static, thread, or automatic storage duration, respectively ([basic.stc]). Otherwise, false.

    -
    consteval bool has_internal_linkage(info r);
    -consteval bool has_module_linkage(info r);
    -consteval bool has_external_linkage(info r);
    -consteval bool has_linkage(info r);
    -

    15 +

    consteval bool has_internal_linkage(info r);
    +consteval bool has_module_linkage(info r);
    +consteval bool has_external_linkage(info r);
    +consteval bool has_linkage(info r);
    +

    15 Returns: true if r represents a variable, function, @@ -10045,8 +10062,8 @@

    [meta.ref linkage, external linkage, or any linkage, respectively ([basic.link]). Otherwise, false.

    -
    consteval bool is_complete_type(info r);
    -

    16 +

    consteval bool is_complete_type(info r);
    +

    16 Returns: true if is_type(r) @@ -10055,8 +10072,8 @@

    [meta.ref represented by dealias(r) is not an incomplete type ([basic.types]). Otherwise, false.

    -
    consteval bool has_complete_definition(info r);
    -

    17 +

    consteval bool has_complete_definition(info r);
    +

    17 Returns: true if r represents a function, class type, @@ -10064,29 +10081,29 @@

    [meta.ref introduced within the scope of the entity represented by r. Otherwise false.

    -
    consteval bool is_namespace(info r);
    -

    18 +

    consteval bool is_namespace(info r);
    +

    18 Returns: true if r represents a namespace or namespace alias. Otherwise, false.

    -
    consteval bool is_variable(info r);
    -

    19 +

    consteval bool is_variable(info r);
    +

    19 Returns: true if r represents a variable. Otherwise, false.

    -
    consteval bool is_type(info r);
    -

    20 +

    consteval bool is_type(info r);
    +

    20 Returns: true if r represents an entity whose underlying entity is a type. Otherwise, false.

    -
    consteval bool is_type_alias(info r);
    -consteval bool is_namespace_alias(info r);
    -

    21 +

    consteval bool is_type_alias(info r);
    +consteval bool is_namespace_alias(info r);
    +

    21 Returns: true if r represents a type alias or @@ -10094,31 +10111,31 @@

    [meta.ref 3: A specialization of an alias template is a type alias — end note ]. Otherwise, false.

    -
    consteval bool is_function(info r);
    -

    22 +

    consteval bool is_function(info r);
    +

    22 Returns: true if r represents a function. Otherwise, false.

    -
    consteval bool is_conversion_function(info r);
    -consteval bool is_operator_function(info r);
    -consteval bool is_literal_operator(info r);
    -

    23 +

    consteval bool is_conversion_function(info r);
    +consteval bool is_operator_function(info r);
    +consteval bool is_literal_operator(info r);
    +

    23 Returns: true if r represents a conversion function, operator function, or literal operator, respectively. Otherwise, false.

    -
    consteval bool is_special_member_function(info r);
    -consteval bool is_constructor(info r);
    -consteval bool is_default_constructor(info r);
    -consteval bool is_copy_constructor(info r);
    -consteval bool is_move_constructor(info r);
    -consteval bool is_assignment(info r);
    -consteval bool is_copy_assignment(info r);
    -consteval bool is_move_assignment(info r);
    -consteval bool is_destructor(info r);
    -

    24 +

    consteval bool is_special_member_function(info r);
    +consteval bool is_constructor(info r);
    +consteval bool is_default_constructor(info r);
    +consteval bool is_copy_constructor(info r);
    +consteval bool is_move_constructor(info r);
    +consteval bool is_assignment(info r);
    +consteval bool is_copy_assignment(info r);
    +consteval bool is_move_assignment(info r);
    +consteval bool is_destructor(info r);
    +

    24 Returns: true if r represents a function that is a @@ -10127,15 +10144,15 @@

    [meta.ref operator, a copy assignment operator, a move assignment operator, or a destructor, respectively. Otherwise, false.

    -
    consteval bool is_template(info r);
    -

    25 +

    consteval bool is_template(info r);
    +

    25 Returns: true if r represents a function template, class template, variable template, alias template, or concept. Otherwise, false.

    -

    26 +

    26 Note 4: A template specialization is not a template. is_template(^^std::vector) is true but @@ -10143,16 +10160,16 @@

    [meta.ref is false. — end note ]

    -
    consteval bool is_function_template(info r);
    -consteval bool is_variable_template(info r);
    -consteval bool is_class_template(info r);
    -consteval bool is_alias_template(info r);
    -consteval bool is_conversion_function_template(info r);
    -consteval bool is_operator_function_template(info r);
    -consteval bool is_literal_operator_template(info r);
    -consteval bool is_constructor_template(info r);
    -consteval bool is_concept(info r);
    -

    27 +

    consteval bool is_function_template(info r);
    +consteval bool is_variable_template(info r);
    +consteval bool is_class_template(info r);
    +consteval bool is_alias_template(info r);
    +consteval bool is_conversion_function_template(info r);
    +consteval bool is_operator_function_template(info r);
    +consteval bool is_literal_operator_template(info r);
    +consteval bool is_constructor_template(info r);
    +consteval bool is_concept(info r);
    +

    27 Returns: true if r represents a function template, @@ -10160,55 +10177,55 @@

    [meta.ref template, operator function template, literal operator template, constructor template, or concept respectively. Otherwise, false.

    -
    consteval bool has_template_arguments(info r);
    -

    28 +

    consteval bool has_template_arguments(info r);
    +

    28 Returns: true if r represents a specialization of a function template, variable template, class template, or an alias template. Otherwise, false.

    -
    consteval bool is_value(info r);
    -consteval bool is_object(info r);
    -

    29 +

    consteval bool is_value(info r);
    +consteval bool is_object(info r);
    +

    29 Returns: true if r represents a value or object, respectively. Otherwise, false.

    -
    consteval bool is_structured_binding(info r);
    -

    30 +

    consteval bool is_structured_binding(info r);
    +

    30 Returns: true if r represents a structured binding. Otherwise, false.

    -
    consteval bool is_class_member(info r);
    -consteval bool is_namespace_member(info r);
    -consteval bool is_nonstatic_data_member(info r);
    -consteval bool is_static_member(info r);
    -consteval bool is_base(info r);
    -

    31 +

    consteval bool is_class_member(info r);
    +consteval bool is_namespace_member(info r);
    +consteval bool is_nonstatic_data_member(info r);
    +consteval bool is_static_member(info r);
    +consteval bool is_base(info r);
    +

    31 Returns: true if r represents a class member, namespace member, non-static data member, static member, or direct base class relationship, respectively. Otherwise, false.

    -
    consteval bool has_default_member_initializer(info r);
    -

    32 +

    consteval bool has_default_member_initializer(info r);
    +

    32 Returns: true if r represents a non-static data member that has a default member initializer. Otherwise, false.

    -
    consteval info type_of(info r);
    -

    33 +

    consteval info type_of(info r);
    +

    33 Constant When: r represents a value, object, variable, function that is not a constructor or destructor, enumerator, non-static data member, bit-field, direct base class relationship, or data member description.

    -

    34 +

    34 Returns: If r represents an entity, object, or value, then a reflection of the type of what is represented by r. Otherwise, if @@ -10222,119 +10239,119 @@

    [meta.ref NUA) (11.4.1 [class.mem.general]), a reflection of the type T.

    -
    consteval info object_of(info r);
    -

    35 +

    consteval info object_of(info r);
    +

    35 Constant When: r is a reflection representing either an object or a variable denoting an object with static storage duration ([expr.const]).

    -

    36 +

    36 Returns: If r is a reflection of a variable, then a reflection of the object denoted by the variable. Otherwise, r.

    Example 1: -
    int x;
    -int& y = x;
    -
    -static_assert(^^x != ^^y);                       // OK, x and y are different variables so their
    -                                                 // reflections compare different
    -static_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference
    -                                                 // to x, their underlying objects are the same
    +
    int x;
    +int& y = x;
    +
    +static_assert(^^x != ^^y);                       // OK, x and y are different variables so their
    +                                                 // reflections compare different
    +static_assert(object_of(^^x) == object_of(^^y)); // OK, because y is a reference
    +                                                 // to x, their underlying objects are the same
    — end example ]
    -
    consteval info value_of(info r);
    -

    37 +

    consteval info value_of(info r);
    +

    37 Constant When: r is a reflection representing

      -
    • (37.1) +
    • (37.1) either an object or variable, usable in constant expressions from some point in the evaluation context ([expr.const]), whose type is a structural type ([temp.type]),
    • -
    • (37.2) +
    • (37.2) an enumerator, or
    • -
    • (37.3) +
    • (37.3) a value.
    -

    38 +

    38 Returns:

      -
    • (38.1) +
    • (38.1) If r is a reflection of an object o, or a reflection of a variable which designates an object o, then a reflection of the value held by o. The reflected value has type type_of(o), with the cv-qualifiers removed if this is a scalar type
    • -
    • (38.2) +
    • (38.2) Otherwise, if r is a reflection of an enumerator, then a reflection of the value of the enumerator.
    • -
    • (38.3) +
    • (38.3) Otherwise, r.
    Example 2: -
    constexpr int x = 0;
    -constexpr int y = 0;
    -
    -static_assert(^^x != ^^y);                         // OK, x and y are different variables so their
    -                                                 // reflections compare different
    -static_assert(value_of(^^x) == value_of(^^y));     // OK, both value_of(^^x) and value_of(^^y) represent
    -                                                 // the value 0
    -static_assert(value_of(^^x) == reflect_value(0)); // OK, likewise
    +
    constexpr int x = 0;
    +constexpr int y = 0;
    +
    +static_assert(^^x != ^^y);                         // OK, x and y are different variables so their
    +                                                 // reflections compare different
    +static_assert(value_of(^^x) == value_of(^^y));     // OK, both value_of(^^x) and value_of(^^y) represent
    +                                                 // the value 0
    +static_assert(value_of(^^x) == reflect_value(0)); // OK, likewise
    — end example ]
    -
    consteval info parent_of(info r);
    -

    39 +

    consteval info parent_of(info r);
    +

    39 Constant When: r represents a variable, structured binding, function, enumerator, class, class member, bit-field, template, namespace or namespace alias (other than ::), type alias, or direct base class relationship.

    -

    40 +

    40 Returns: If r represents a non-static data member that is a direct member of an anonymous union, then a reflection representing the innermost enclosing anonymous union. Otherwise, a reflection of the class, function, or namespace that is the target scope ([basic.scope.scope]) of the first declaration of what is represented by r.

    -
    consteval info dealias(info r);
    -

    41 +

    consteval info dealias(info r);
    +

    41 Returns: A reflection representing the underlying entity of r.

    -

    42

    +

    42

    Example 3: -
    using X = int;
    -using Y = X;
    -static_assert(dealias(^^int) == ^^int);
    -static_assert(dealias(^^X) == ^^int);
    -static_assert(dealias(^^Y) == ^^int);
    +
    using X = int;
    +using Y = X;
    +static_assert(dealias(^^int) == ^^int);
    +static_assert(dealias(^^X) == ^^int);
    +static_assert(dealias(^^Y) == ^^int);
    — end example ]
    -
    consteval info template_of(info r);
    -consteval vector<info> template_arguments_of(info r);
    -

    43 +

    consteval info template_of(info r);
    +consteval vector<info> template_arguments_of(info r);
    +

    43 Constant When: has_template_arguments(r) is true.

    -

    44 +

    44 Returns: A reflection of the primary template of r, and the reflections of the template arguments of the specialization represented by r, respectively.

    -

    45

    +

    45

    Example 4: -
    template <class T, class U=T> struct Pair { };
    -template <class T> struct Pair<char, T> { };
    -template <class T> using PairPtr = Pair<T*>;
    -
    -static_assert(template_of(^^Pair<int>) == ^^Pair);
    -static_assert(template_of(^^Pair<char, char>) == ^^Pair);
    -static_assert(template_arguments_of(^^Pair<int>).size() == 2);
    -
    -static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);
    -static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);
    +
    template <class T, class U=T> struct Pair { };
    +template <class T> struct Pair<char, T> { };
    +template <class T> using PairPtr = Pair<T*>;
    +
    +static_assert(template_of(^^Pair<int>) == ^^Pair);
    +static_assert(template_of(^^Pair<char, char>) == ^^Pair);
    +static_assert(template_arguments_of(^^Pair<int>).size() == 2);
    +
    +static_assert(template_of(^^PairPtr<int>) == ^^PairPtr);
    +static_assert(template_arguments_of(^^PairPtr<int>).size() == 1);
    — end example ]

    @@ -10345,12 +10362,12 @@

    -
    consteval vector<info> members_of(info r);
    -

    1 +

    consteval vector<info> members_of(info r);
    +

    1 Constant When: r is a reflection representing either a class type that is complete from some point in the evaluation context or a namespace.

    -

    2 +

    2 A member of a class or namespace E is members-of-representable if it is either

    @@ -10373,7 +10390,7 @@

    3 +

    3 A member M of a class or namespace is members-of-reachable from a point P if there exists a @@ -10384,7 +10401,7 @@

    D is declared in the translation unit containing P.

    -

    4 +

    4 Returns: A vector containing reflections of all members-of-representable members of the entity represented by r that are @@ -10398,11 +10415,11 @@

    Note 2: Base classes are not members. Implicitly-declared special members appear after any user-declared members. — end note ]

    -
    consteval vector<info> bases_of(info type);
    -

    5 +

    consteval vector<info> bases_of(info type);
    +

    5 Constant When: dealias(type) is a reflection representing a complete class type.

    -

    6 +

    6 Returns: Let C be the type represented by dealias(type). A vector containing the reflections @@ -10411,71 +10428,71 @@

    C.

    -
    consteval vector<info> static_data_members_of(info type);
    -

    7 +

    consteval vector<info> static_data_members_of(info type);
    +

    7 Constant When: dealias(type) represents a complete class type.

    -

    8 +

    8 Returns: A vector containing each element e of members_of(type) such that is_variable(e) is true, in order.

    -
    consteval vector<info> nonstatic_data_members_of(info type);
    -

    9 +

    consteval vector<info> nonstatic_data_members_of(info type);
    +

    9 Constant When: dealias(type) represents a complete class type.

    -

    10 +

    10 Returns: A vector containing each element e of members_of(type) such that is_nonstatic_data_member(e) is true, in order.

    -
    consteval vector<info> enumerators_of(info type_enum);
    -

    11 +

    consteval vector<info> enumerators_of(info type_enum);
    +

    11 Constant When: dealias(type_enum) represents an enumeration type and has_complete_definition(dealias(type_enum)) is true.

    -

    12 +

    12 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.

    -
    consteval vector<info> get_public_members(info type);
    -

    13 +

    consteval vector<info> get_public_members(info type);
    +

    13 Constant When: dealias(type) represents a complete class type.

    -

    14 +

    14 Returns: A vector containing each element e of members_of(type) such that is_public(e) is true, in order.

    -
    consteval vector<info> get_public_bases(info type);
    -

    15 +

    consteval vector<info> get_public_bases(info type);
    +

    15 Constant When: dealias(type) represents a complete class type.

    -

    16 +

    16 Returns: A vector containing each element e of bases_of(type) such that is_public(e) is true, in order.

    -
    consteval vector<info> get_public_static_data_members(info type);
    -

    17 +

    consteval vector<info> get_public_static_data_members(info type);
    +

    17 Constant When: dealias(type) represents a complete class type.

    -

    18 +

    18 Returns: A vector containing each element e of static_data_members_of(type) such that is_public(e) is true, in order.

    -
    consteval vector<info> get_public_nonstatic_data_members(info type);
    -

    19 +

    consteval vector<info> get_public_nonstatic_data_members(info type);
    +

    19 Constant When: dealias(type) represents a complete class type.

    -

    20 +

    20 Returns: A vector containing each element e of nonstatic_data_members_of(type) such that is_public(e) @@ -10489,23 +10506,23 @@

    [me
    -
    constexpr ptrdiff_t member_offset::total_bits() const;
    -

    1 +

    constexpr ptrdiff_t member_offset::total_bits() const;
    +

    1 Returns: bytes * CHAR_BIT + bits.

    -
    consteval member_offset offset_of(info r);
    -

    2 +

    consteval member_offset offset_of(info r);
    +

    2 Constant When: r represents a non-static data member, unnamed bit-field, or direct base class relationship other than a virtual base class of an abstract class.

    -

    3 +

    3 Let V be the offset in bits from the beginning of a complete object of type parent_of(r) to the subobject associated with the entity represented by r.

    -

    4 +

    4 Returns: {V / CHAR_BIT, V % CHAR_BIT}.

    -
    consteval size_t size_of(info r);
    -

    5 +

    consteval size_t size_of(info r);
    +

    5 Constant When: dealias(r) is a reflection of a type, object, value, variable of non-reference type, non-static data member, direct base class relationship, or data @@ -10513,7 +10530,7 @@

    [me represents a type T, there is a point within the evaluation context from which T is not incomplete.

    -

    6 +

    6 Returns: If r represents a non-static data member whose corresponding subobject has type T, or a data member @@ -10530,8 +10547,8 @@

    [me corresponding to a non-static data member of reference type has the same size and alignment as the corresponding pointer type. — end note ]

    -
    consteval size_t alignment_of(info r);
    -

    7 +

    consteval size_t alignment_of(info r);
    +

    7 Constant When: dealias(r) is a reflection representing a type, object, variable, non-static data member that is not a bit-field, direct base class relationship, or data @@ -10539,21 +10556,21 @@

    [me represents a type T, there is a point within the evaluation context from which T is not incomplete.

    -

    8 +

    8 Returns:

      -
    • (8.1) +
    • (8.1) If dealias(r) represents a type, variable, or object, then the alignment requirement of the entity or object.
    • -
    • (8.2) +
    • (8.2) Otherwise, if r represents a direct base class relationship, then alignment_of(type_of(r)).
    • -
    • (8.3) +
    • (8.3) Otherwise, if r represents a non-static data member, then the alignment requirement of the subobject associated with the represented entity within any object of type parent_of(r).
    • -
    • (8.4) +
    • (8.4) Otherwise, r represents a data member description (T, N, @@ -10562,8 +10579,8 @@

      [me NUA) (11.4.1 [class.mem.general]). The value A.

    -
    consteval size_t bit_size_of(info r);
    -

    9 +

    consteval size_t bit_size_of(info r);
    +

    9 Constant When: 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 @@ -10571,7 +10588,7 @@

    [me represents a type T, there is a point within the evaluation context from which T is not incomplete.

    -

    10 +

    10 Returns: If r represents a non-static data member that is a bit-field or unnamed bit-field with width W, or a data member @@ -10589,32 +10606,32 @@

    [meta.refle
    -

    1 +

    1 The extract function template may be used to extract a value out of a reflection when the type is known.

    -

    2 +

    2 The following are defined for exposition only to aid in the specification of extract:

    -
    template <class T>
    -  consteval T extract-ref(info r); // exposition only
    -

    3 +

    template <class T>
    +  consteval T extract-ref(info r); // exposition only
    +

    3 Note 1: T is a reference type. — end note ]

    -

    4 +

    4 Constant When: r represents a variable or object of type U that is usable in constant expressions from some point in the evaluation context and is_convertible_v<remove_reference_t<U>(*)[], remove_reference_t<T>(*)[]> is true.

    -

    5 +

    5 Returns: the object represented by object_of(r).

    -
    template <class T>
    -  consteval T extract-member-or-function(info r); // exposition only
    -

    6 +

    template <class T>
    +  consteval T extract-member-or-function(info r); // exposition only
    +

    6 Constant When:

      -
    • (6.1) +
    • (6.1) If r represents a non-static data member of a class C with type X, then when @@ -10622,7 +10639,7 @@

      [meta.refle X C::* and r does not represent a bit-field.

    • -
    • (6.2) +
    • (6.2) Otherwise, if r represents an implicit object member function of class C with type @@ -10630,7 +10647,7 @@

      [meta.refle F noexcept, then when T is F C::*.

    • -
    • (6.3) +
    • (6.3) Otherwise, r represents a function, static member function, or explicit object member function of function type F or @@ -10638,58 +10655,58 @@

      [meta.refle then when T is F*.

    -

    7 +

    7 Returns:

      -
    • (7.1) +
    • (7.1) If T is a pointer type, then a pointer value pointing to the entity represented by r.
    • -
    • (7.2) +
    • (7.2) Otherwise, a pointer-to-member value designating the entity represented by r.
    -
    template <class T>
    -  consteval T extract-val(info r); // exposition only
    -

    8 +

    template <class T>
    +  consteval T extract-val(info r); // exposition only
    +

    8 Let U be the type of the value that r represents.

    -

    9 +

    9 Constant When:

      -
    • (9.1) +
    • (9.1) U is a pointer type, T and U are similar types ([conv.qual]), and is_convertible_v<U, T> is true,
    • -
    • (9.2) +
    • (9.2) U is not a pointer type and the cv-unqualified types of T and U are the same, or
    • -
    • (9.3) +
    • (9.3) U is a closure type, T is a function pointer type, and the value that r represents is convertible to T.
    -

    10 +

    10 Returns: the value that r represents converted to T.

    -
    template <class T>
    -  consteval T extract(info r);
    -

    11 +

    template <class T>
    +  consteval T extract(info r);
    +

    11 Effects:

      -
    • 12 +
    • 12 If T is a reference type, then equivalent to return extract-ref<T>(r);
    • -
    • 13 +
    • 13 Otherwise, if r represents a function, non-static data member, or member function, equivalent to return extract-member-or-function<T>(r);
    • -
    • 14 +
    • 14 Otherwise, equivalent to return extract-value<T>(value_of(r))
    @@ -10700,47 +10717,47 @@

    [
    -
    template <class R>
    -concept reflection_range =
    -  ranges::input_range<R> &&
    -  same_as<ranges::range_value_t<R>, info> &&
    -  same_as<remove_cvref_t<ranges::range_reference_t<R>>, info>;
    -
    template <reflection_range R = initializer_list<info>>
    -consteval bool can_substitute(info templ, R&& arguments);
    -

    1 +

    template <class R>
    +concept reflection_range =
    +  ranges::input_range<R> &&
    +  same_as<ranges::range_value_t<R>, info> &&
    +  same_as<remove_cvref_t<ranges::range_reference_t<R>>, info>;
    +
    template <reflection_range R = initializer_list<info>>
    +consteval bool can_substitute(info templ, R&& arguments);
    +

    1 Constant When: templ represents a template and every reflection in arguments represents a construct usable as a template argument ([temp.arg]).

    -

    2 +

    2 Let Z be the template represented by templ and let Args... be the sequence of entities, values, and objects represented by the elements of arguments.

    -

    3 +

    3 Returns: true if Z<Args...> is a valid template-id ([temp.names]). Otherwise, false.

    -

    4 +

    4 Remarks: If attempting to substitute leads to a failure outside of the immediate context, the program is ill-formed.

    -
    template <reflection_range R = initializer_list<info>>
    -consteval info substitute(info templ, R&& arguments);
    -

    5 +

    template <reflection_range R = initializer_list<info>>
    +consteval info substitute(info templ, R&& arguments);
    +

    5 Constant When: can_substitute(templ, arguments) is true.

    -

    6 +

    6 Let Z be the template represented by templ and let Args... be the sequence of entities, values, and objects represented by the elements of arguments.

    -

    7 +

    7 Returns: ^^Z<Args...>.

    -

    8 +

    8 Note 1: Z<Args..> is not instantiated. — end note ]

    @@ -10751,72 +10768,72 @@

    -
    template <typename T>
    -  consteval info reflect_value(const T& expr);
    -

    1 +

    template <typename T>
    +  consteval info reflect_value(const T& expr);
    +

    1 Mandates: T is a structural type that is neither a reference type nor an array type.

    -

    2 +

    2 Constant When: Any value computed by expr having pointer type, or every subobject of the value computed by expr having pointer or reference type, is the address of or refers to an object or function that

      -
    • (2.1) +
    • (2.1) is a permitted result of a constant expression ([expr.const]),
    • -
    • (2.2) +
    • (2.2) is not a temporary object ([class.temporary]),
    • -
    • (2.3) +
    • (2.3) is not a string literal object ([lex.string]),
    • -
    • (2.4) +
    • (2.4) is not the result of a typeid expression ([expr.typeid]), and
    • -
    • (2.5) +
    • (2.5) is not an object associated with a predefined __func__ variable ([dcl.fct.def.general]).
    -

    3 +

    3 Returns: A reflection of the value computed by an lvalue-to-rvalue conversion applied to expr. The type of the represented value is the cv-unqualified version of T.

    -
    template <typename T>
    -  consteval info reflect_object(T& expr);
    -

    4 +

    template <typename T>
    +  consteval info reflect_object(T& expr);
    +

    4 Mandates: T is not a function type.

    -

    5 +

    5 Constant When: expr designates an object or function that

      -
    • (5.1) +
    • (5.1) is a permitted result of a constant expression ([expr.const]),
    • -
    • (5.2) +
    • (5.2) is not a temporary object ([class.temporary]),
    • -
    • (5.3) +
    • (5.3) is not a string literal object ([lex.string]),
    • -
    • (5.4) +
    • (5.4) is not the result of a typeid expression ([expr.typeid]), and
    • -
    • (5.5) +
    • (5.5) is not an object associated with a predefined __func__ variable ([dcl.fct.def.general]).
    -

    6 +

    6 Returns: A reflection of the object designated by expr.

    -
    template <typename T>
    -  consteval info reflect_function(T& expr);
    -

    7 +

    template <typename T>
    +  consteval info reflect_function(T& expr);
    +

    7 Mandates: T is a function type.

    -

    8 +

    8 Returns: ^^fn, where fn is the function designated by @@ -10829,35 +10846,35 @@

    -

    1 +

    1 The classes data_member_options and name_type are consteval-only types ([basic.types.general]), and are not a structural types ([temp.param]).

    -
    struct data_member_options {
    -  struct name_type {
    -    template<class T> requires constructible_from<u8string, T>
    -      consteval name_type(T &&);
    -
    -    template<class T> requires constructible_from<string, T>
    -      consteval name_type(T &&);
    -
    -    variant<u8string, string> contents;    // exposition only
    -  };
    -
    -  optional<name_type> name;
    -  optional<int> alignment;
    -  optional<int> bit_width;
    -  bool no_unique_address = false;
    -};
    -
    template <class T> requires constructible_from<u8string, T>
    -consteval data_member_options::name_type(T&& value);
    -

    2 +

    struct data_member_options {
    +  struct name_type {
    +    template<class T> requires constructible_from<u8string, T>
    +      consteval name_type(T &&);
    +
    +    template<class T> requires constructible_from<string, T>
    +      consteval name_type(T &&);
    +
    +    variant<u8string, string> contents;    // exposition only
    +  };
    +
    +  optional<name_type> name;
    +  optional<int> alignment;
    +  optional<int> bit_width;
    +  bool no_unique_address = false;
    +};
    +
    template <class T> requires constructible_from<u8string, T>
    +consteval data_member_options::name_type(T&& value);
    +

    2 Effects: Initializes contents with u8string(value).

    -
    template<class T> requires constructible_from<string, T>
    -consteval data_member_options::name_type(T&& value);
    -

    3 +

    template<class T> requires constructible_from<string, T>
    +consteval data_member_options::name_type(T&& value);
    +

    3 Effects: Initializes contents with string(value).

    @@ -10872,70 +10889,70 @@

    string, etc) or a UTF-8 string literal (or u8string_view, u8string, etc) equally well.

    -
    constexpr auto mem1 = data_member_spec(^^int, {.name="ordinary_literal_encoding"});
    -constexpr auto mem2 = data_member_spec(^^int, {.name=u8"utf8_encoding"});
    +
    constexpr auto mem1 = data_member_spec(^^int, {.name="ordinary_literal_encoding"});
    +constexpr auto mem2 = data_member_spec(^^int, {.name=u8"utf8_encoding"});
    — end note ]

    -
    consteval info data_member_spec(info type,
    -                                data_member_options options);
    -

    4 +

    consteval info data_member_spec(info type,
    +                                data_member_options options);
    +

    4 Constant When:

      -
    • (4.1) +
    • (4.1) dealias(type) represents a type cv T where T is either an object type or a reference type;
    • -
    • (4.2) +
    • (4.2) if options.name contains a value, then:
        -
      • (4.2.1) +
      • (4.2.1) holds_alternative<u8string>(options.name->contents) is true and get<u8string>(options.name->contents) contains a valid identifier when interpreted with UTF-8, or
      • -
      • (4.2.2) +
      • (4.2.2) holds_alternative<string>(options.name->contents) is true and get<string>(options.name->contents) contains a valid identifier when interpreted with the ordinary literal encoding;
    • -
    • (4.3) +
    • (4.3) otherwise, if options.name does not contain a value, then options.bit_width contains a value;
    • -
    • (4.4) +
    • (4.4) if options.alignment contains a value, it is an alignment value ([basic.align]) not less than alignment_of(type); and
    • -
    • (4.5) +
    • (4.5) if options.bit_width contains a value V, then
    -

    5 +

    5 Returns: A reflection of a data member description (T, N, @@ -10944,10 +10961,10 @@

    NUA) (11.4.1 [class.mem.general]) where

      -
    • (5.1) +
    • (5.1) T is the type or type alias represented by type,
    • -
    • (5.2) +
    • (5.2) N is either the identifier encoded by options.name @@ -10955,23 +10972,23 @@

      options.name is empty,

    • -
    • (5.3) +
    • (5.3) A is either the alignment value held by options.alignment or -1 if options.alignment is empty,
    • -
    • (5.4) +
    • (5.4) W is either the value held by options.bit_width or -1 if options.bit_width is empty, and
    • -
    • (5.5) +
    • (5.5) NUA is the value held by options.no_unique_address.
    -

    6 +

    6 Note 2: The returned reflection value is primarily useful in conjunction with define_aggregate. Certain other @@ -10982,16 +10999,16 @@

    data_member_spec. — end note ]

    -
    consteval bool is_data_member_spec(info r);
    -

    7 +

    consteval bool is_data_member_spec(info r);
    +

    7 Returns: true if r represents a data member description. Otherwise, false.

    -
      template <reflection_range R = initializer_list<info>>
    -  consteval info define_aggregate(info class_type, R&& mdescrs);
    -

    8 +

      template <reflection_range R = initializer_list<info>>
    +  consteval info define_aggregate(info class_type, R&& mdescrs);
    +

    8 Constant When: Letting C be the class represented by class_type and @@ -10999,7 +11016,7 @@

    Kth reflection value in mdescrs,

      -
    • (8.1) +
    • (8.1) If C is a complete type from some point in the evaluation context, then
        @@ -11016,18 +11033,18 @@

        Kth data member of C.

    • -
    • (8.2) +
    • (8.2) is_data_member_spec(rK) is true for every rK in mdescrs,
    • -
    • (8.3) +
    • (8.3) the type represented by type_of(rK) is a complete type for every rK in mdescrs, and
    • -
    • (8.4) +
    • (8.4) for every pair 0 ≤ K < L < mdescrs.size(), if has_identifier(rK) && has_identifier(rL), @@ -11041,37 +11058,37 @@

      C could be a class template specialization for which there is no reachable definition. — end note ]

      -

      9 +

      9 Let {tk} be a sequence of reflections and {ok} be a sequence of data_member_options values such that

      -
      data_member_spec(tk, ok) == rk
      +
      data_member_spec(tk, ok) == rk

      for every rk in mdescrs.

      -

      10 +

      10 Effects: Produces an injected declaration D ([expr.const]) that provides a definition for C with properties as follows:

        -
      • (10.1) +
      • (10.1) The target scope of D is the scope to which C belongs ([basic.scope.scope]).
      • -
      • (10.2) +
      • (10.2) The locus of D follows immediately after the manifestly constant-evaluated expression currently under evaluation.
      • -
      • (10.3) +
      • (10.3) If C is a specialization of a class template T, then D is is an explicit specialization of T.
      • -
      • (10.4) +
      • (10.4) D contains a public non-static data member or unnamed bit-field corresponding to each reflection value @@ -11084,28 +11101,28 @@

        rK precedes the declaration of rL.

      • -
      • (10.5) +
      • (10.5) A non-static data member or unnamed bit-field corresponding to each rK is declared with the type or type alias represented by tK.
      • -
      • (10.6) +
      • (10.6) A non-static data member corresponding to a reflection rK for which oK.no_unique_address is true is declared with the attribute [[no_unique_address]].
      • -
      • (10.7) +
      • (10.7) A non-static data member or unnamed bit-field corresponding to a reflection rK for which oK.bit_width contains a value is declared as a bit-field whose width is that value.
      • -
      • (10.8) +
      • (10.8) A non-static data member corresponding to a reflection rK for which oK.alignment contains a value is declared with the alignment-specifier alignas(oK.alignment).
      • -
      • (10.9) +
      • (10.9) A non-static data member or unnamed bit-field corresponding to a reflection rK is declared with a @@ -11117,18 +11134,18 @@

        u8identifier_of(rK) in UTF-8.

    • -
    • (10.10) +
    • (10.10) If C is a union type for which any of its members are not trivially default constructible, then D has a user-provided default constructor which has no effect.
    • -
    • (10.11) +
    • (10.11) If C is a union type for which any of its members are not trivially destructible, then D has a user-provided destructor which has no effect.
    -

    11 +

    11 Returns: class_type.

    @@ -11138,10 +11155,10 @@

    [meta.reflec
    -

    1 +

    1 Subclause [meta.reflection.unary] contains consteval functions that may be used to query the properties of a type at compile time.

    -

    2 +

    2 For each function taking an argument of type meta::info whose name contains type, a call to @@ -11160,43 +11177,43 @@

    [m
    -

    1 +

    1 For any type or type alias T, for each function std::meta::TRAIT_type defined in this clause, std::meta::TRAIT_type(^^T) equals the value of the corresponding unary type trait std::TRAIT_v<T> as specified in 21.3.5.2 [meta.unary.cat].

    -
    consteval bool is_void_type(info type);
    -consteval bool is_null_pointer_type(info type);
    -consteval bool is_integral_type(info type);
    -consteval bool is_floating_point_type(info type);
    -consteval bool is_array_type(info type);
    -consteval bool is_pointer_type(info type);
    -consteval bool is_lvalue_reference_type(info type);
    -consteval bool is_rvalue_reference_type(info type);
    -consteval bool is_member_object_pointer_type(info type);
    -consteval bool is_member_function_pointer_type(info type);
    -consteval bool is_enum_type(info type);
    -consteval bool is_union_type(info type);
    -consteval bool is_class_type(info type);
    -consteval bool is_function_type(info type);
    -consteval bool is_reflection_type(info type);
    -

    2

    +
    consteval bool is_void_type(info type);
    +consteval bool is_null_pointer_type(info type);
    +consteval bool is_integral_type(info type);
    +consteval bool is_floating_point_type(info type);
    +consteval bool is_array_type(info type);
    +consteval bool is_pointer_type(info type);
    +consteval bool is_lvalue_reference_type(info type);
    +consteval bool is_rvalue_reference_type(info type);
    +consteval bool is_member_object_pointer_type(info type);
    +consteval bool is_member_function_pointer_type(info type);
    +consteval bool is_enum_type(info type);
    +consteval bool is_union_type(info type);
    +consteval bool is_class_type(info type);
    +consteval bool is_function_type(info type);
    +consteval bool is_reflection_type(info type);
    +

    2

    Example 1: -
    namespace std::meta {
    -  consteval bool is_void_type(info type) {
    -    // one example implementation
    -    return extract<bool>(substitute(^^is_void_v, {type}));
    -
    -    // another example implementation
    -    type = dealias(type);
    -    return type == ^^void
    -        || type == ^^const void
    -        || type == ^^volatile void
    -        || type == ^^const volatile void;
    -  }
    -}
    +
    namespace std::meta {
    +  consteval bool is_void_type(info type) {
    +    // one example implementation
    +    return extract<bool>(substitute(^^is_void_v, {type}));
    +
    +    // another example implementation
    +    type = dealias(type);
    +    return type == ^^void
    +        || type == ^^const void
    +        || type == ^^volatile void
    +        || type == ^^const volatile void;
    +  }
    +}
    — end example ]
    @@ -11207,19 +11224,19 @@

    -

    1 +

    1 For any type or type alias T, for each function std::meta::TRAIT_type defined in this clause, std::meta::TRAIT_type(^^T) equals the value of the corresponding unary type trait std::TRAIT_v<T> as specified in 21.3.5.3 [meta.unary.comp].

    -
    consteval bool is_reference_type(info type);
    -consteval bool is_arithmetic_type(info type);
    -consteval bool is_fundamental_type(info type);
    -consteval bool is_object_type(info type);
    -consteval bool is_scalar_type(info type);
    -consteval bool is_compound_type(info type);
    -consteval bool is_member_pointer_type(info type);
    +
    consteval bool is_reference_type(info type);
    +consteval bool is_arithmetic_type(info type);
    +consteval bool is_fundamental_type(info type);
    +consteval bool is_object_type(info type);
    +consteval bool is_scalar_type(info type);
    +consteval bool is_compound_type(info type);
    +consteval bool is_member_pointer_type(info type);

    @@ -11228,7 +11245,7 @@

    [meta.ref
    -

    1 +

    1 For any type or type alias T, for each function std::meta::UNARY-TRAIT_type or std::meta::UNARY-TRAIT @@ -11237,7 +11254,7 @@

    [meta.ref or std::meta::UNARY-TRAIT(^^T) equals the value of the corresponding type property std::UNARY-TRAIT_v<T> as specified in 21.3.5.4 [meta.unary.prop].

    -

    2 +

    2 For any types or type aliases T and U, for each function std::meta::BINARY-TRAIT_type or std::meta::BINARY-TYPE @@ -11246,7 +11263,7 @@

    [meta.ref or std::meta::BINARY-TRAIT(^^T, ^^U) equals the value of the corresponding type property std::BINARY-TRAIT_v<T, U> as specified in 21.3.5.4 [meta.unary.prop].

    -

    3 +

    3 For any type or type alias T, pack of types or type aliases U..., and @@ -11256,71 +11273,71 @@

    [meta.ref defined in this clause, std::meta::VARIADIC-TRAIT_type(^^T, r) equals the value of the corresponding type property std::VARIADIC-TRAIT_v<T, U...> as specified in 21.3.5.4 [meta.unary.prop].

    -
    consteval bool is_const_type(info type);
    -consteval bool is_volatile_type(info type);
    -consteval bool is_trivial_type(info type);
    -consteval bool is_trivially_copyable_type(info type);
    -consteval bool is_standard_layout_type(info type);
    -consteval bool is_empty_type(info type);
    -consteval bool is_polymorphic_type(info type);
    -consteval bool is_abstract_type(info type);
    -consteval bool is_final_type(info type);
    -consteval bool is_aggregate_type(info type);
    -consteval bool is_signed_type(info type);
    -consteval bool is_unsigned_type(info type);
    -consteval bool is_bounded_array_type(info type);
    -consteval bool is_unbounded_array_type(info type);
    -consteval bool is_scoped_enum_type(info type);
    -
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_constructible_type(info type, R&& type_args);
    -consteval bool is_default_constructible_type(info type);
    -consteval bool is_copy_constructible_type(info type);
    -consteval bool is_move_constructible_type(info type);
    -
    -consteval bool is_assignable_type(info type_dst, info type_src);
    -consteval bool is_copy_assignable_type(info type);
    -consteval bool is_move_assignable_type(info type);
    -
    -consteval bool is_swappable_with_type(info type_dst, info type_src);
    -consteval bool is_swappable_type(info type);
    -
    -consteval bool is_destructible_type(info type);
    -
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_trivially_constructible_type(info type, R&& type_args);
    -consteval bool is_trivially_default_constructible_type(info type);
    -consteval bool is_trivially_copy_constructible_type(info type);
    -consteval bool is_trivially_move_constructible_type(info type);
    -
    -consteval bool is_trivially_assignable_type(info type_dst, info type_src);
    -consteval bool is_trivially_copy_assignable_type(info type);
    -consteval bool is_trivially_move_assignable_type(info type);
    -consteval bool is_trivially_destructible_type(info type);
    -
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_nothrow_constructible_type(info type, R&& type_args);
    -consteval bool is_nothrow_default_constructible_type(info type);
    -consteval bool is_nothrow_copy_constructible_type(info type);
    -consteval bool is_nothrow_move_constructible_type(info type);
    -
    -consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
    -consteval bool is_nothrow_copy_assignable_type(info type);
    -consteval bool is_nothrow_move_assignable_type(info type);
    -
    -consteval bool is_nothrow_swappable_with_type(info type_dst, info type_src);
    -consteval bool is_nothrow_swappable_type(info type);
    -
    -consteval bool is_nothrow_destructible_type(info type);
    -
    -consteval bool is_implicit_lifetime_type(info type);
    -
    -consteval bool has_virtual_destructor(info type);
    -
    -consteval bool has_unique_object_representations(info type);
    -
    -consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
    -consteval bool reference_converts_from_temporary(info type_dst, info type_src);
    +
    consteval bool is_const_type(info type);
    +consteval bool is_volatile_type(info type);
    +consteval bool is_trivial_type(info type);
    +consteval bool is_trivially_copyable_type(info type);
    +consteval bool is_standard_layout_type(info type);
    +consteval bool is_empty_type(info type);
    +consteval bool is_polymorphic_type(info type);
    +consteval bool is_abstract_type(info type);
    +consteval bool is_final_type(info type);
    +consteval bool is_aggregate_type(info type);
    +consteval bool is_signed_type(info type);
    +consteval bool is_unsigned_type(info type);
    +consteval bool is_bounded_array_type(info type);
    +consteval bool is_unbounded_array_type(info type);
    +consteval bool is_scoped_enum_type(info type);
    +
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_constructible_type(info type, R&& type_args);
    +consteval bool is_default_constructible_type(info type);
    +consteval bool is_copy_constructible_type(info type);
    +consteval bool is_move_constructible_type(info type);
    +
    +consteval bool is_assignable_type(info type_dst, info type_src);
    +consteval bool is_copy_assignable_type(info type);
    +consteval bool is_move_assignable_type(info type);
    +
    +consteval bool is_swappable_with_type(info type_dst, info type_src);
    +consteval bool is_swappable_type(info type);
    +
    +consteval bool is_destructible_type(info type);
    +
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_trivially_constructible_type(info type, R&& type_args);
    +consteval bool is_trivially_default_constructible_type(info type);
    +consteval bool is_trivially_copy_constructible_type(info type);
    +consteval bool is_trivially_move_constructible_type(info type);
    +
    +consteval bool is_trivially_assignable_type(info type_dst, info type_src);
    +consteval bool is_trivially_copy_assignable_type(info type);
    +consteval bool is_trivially_move_assignable_type(info type);
    +consteval bool is_trivially_destructible_type(info type);
    +
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_nothrow_constructible_type(info type, R&& type_args);
    +consteval bool is_nothrow_default_constructible_type(info type);
    +consteval bool is_nothrow_copy_constructible_type(info type);
    +consteval bool is_nothrow_move_constructible_type(info type);
    +
    +consteval bool is_nothrow_assignable_type(info type_dst, info type_src);
    +consteval bool is_nothrow_copy_assignable_type(info type);
    +consteval bool is_nothrow_move_assignable_type(info type);
    +
    +consteval bool is_nothrow_swappable_with_type(info type_dst, info type_src);
    +consteval bool is_nothrow_swappable_type(info type);
    +
    +consteval bool is_nothrow_destructible_type(info type);
    +
    +consteval bool is_implicit_lifetime_type(info type);
    +
    +consteval bool has_virtual_destructor(info type);
    +
    +consteval bool has_unique_object_representations(info type);
    +
    +consteval bool reference_constructs_from_temporary(info type_dst, info type_src);
    +consteval bool reference_converts_from_temporary(info type_dst, info type_src);

    @@ -11329,13 +11346,13 @@

    -
    consteval size_t rank(info type);
    -

    1 +

    consteval size_t rank(info type);
    +

    1 Effects: Equivalent to return std::rank_v<T>, where T is the type represented by type.

    -
    consteval size_t extent(info type, unsigned i = 0);
    -

    2 +

    consteval size_t extent(info type, unsigned i = 0);
    +

    2 Effects: Equivalent to return std::extent_v<T, i>, where T is the type represented by type.

    @@ -11347,17 +11364,17 @@

    [meta.reflection.
    -

    1 +

    1 The consteval functions specified in this clause may be used to query relationships between types at compile time.

    -

    2 +

    2 For any types or type aliases T and U, for each function std::meta::REL_type defined in this clause with signature bool(std::meta::info, std::meta::info), std::meta::REL_type(^^T, ^^U) equals the value of the corresponding type relation std::REL_v<T, U> as specified in 21.3.7 [meta.rel].

    -

    3 +

    3 For any type or type alias T, pack of types or type aliases U..., and @@ -11367,7 +11384,7 @@

    [meta.reflection. std::meta::VARIADIC-REL_type(^^T, r) equals the value of the corresponding type relation std::VARIADIC-REL_v<T, U...> as specified in 21.3.7 [meta.rel].

    -

    4 +

    4 For any types or type aliases T and R, pack of types or type aliases U..., and @@ -11377,24 +11394,24 @@

    [meta.reflection. defined in this clause, std::meta::VARIADIC-REL-R(^^R, ^^T, r)_type equals the value of the corresponding type relation std::VARIADIC-REL-R_v<R, T, U...> as specified in 21.3.7 [meta.rel].

    -
    consteval bool is_same_type(info type1, info type2);
    -consteval bool is_base_of_type(info type_base, info type_derived);
    -consteval bool is_virtual_base_of_type(info type_base, info type_derived);
    -consteval bool is_convertible_type(info type_src, info type_dst);
    -consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
    -consteval bool is_layout_compatible_type(info type1, info type2);
    -consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
    -
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_invocable_type(info type, R&& type_args);
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
    -
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_nothrow_invocable_type(info type, R&& type_args);
    -template <reflection_range R = initializer_list<info>>
    -consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
    -

    5 +

    consteval bool is_same_type(info type1, info type2);
    +consteval bool is_base_of_type(info type_base, info type_derived);
    +consteval bool is_virtual_base_of_type(info type_base, info type_derived);
    +consteval bool is_convertible_type(info type_src, info type_dst);
    +consteval bool is_nothrow_convertible_type(info type_src, info type_dst);
    +consteval bool is_layout_compatible_type(info type1, info type2);
    +consteval bool is_pointer_interconvertible_base_of_type(info type_base, info type_derived);
    +
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_invocable_type(info type, R&& type_args);
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_invocable_r_type(info type_result, info type, R&& type_args);
    +
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_nothrow_invocable_type(info type, R&& type_args);
    +template <reflection_range R = initializer_list<info>>
    +consteval bool is_nothrow_invocable_r_type(info type_result, info type, R&& type_args);
    +

    5 Note 1: If t is a reflection of the type int and @@ -11416,7 +11433,7 @@

    -

    1 +

    1 Subclause [meta.reflection.trans] contains consteval functions that may be used to transform one type to another following some predefined rule.

    @@ -11428,18 +11445,18 @@

    -

    1 +

    1 For any type or type alias T, for each function std::meta::MOD defined in this clause, std::meta::MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.2 [meta.trans.cv].

    -
    consteval info remove_const(info type);
    -consteval info remove_volatile(info type);
    -consteval info remove_cv(info type);
    -consteval info add_const(info type);
    -consteval info add_volatile(info type);
    -consteval info add_cv(info type);
    +
    consteval info remove_const(info type);
    +consteval info remove_volatile(info type);
    +consteval info remove_cv(info type);
    +consteval info add_const(info type);
    +consteval info add_volatile(info type);
    +consteval info add_cv(info type);

    @@ -11448,15 +11465,15 @@

    [m
    -

    1 +

    1 For any type or type alias T, for each function std::meta::MOD defined in this clause, std::meta::MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.3 [meta.trans.ref].

    -
    consteval info remove_reference(info type);
    -consteval info add_lvalue_reference(info type);
    -consteval info add_rvalue_reference(info type);
    +
    consteval info remove_reference(info type);
    +consteval info add_lvalue_reference(info type);
    +consteval info add_rvalue_reference(info type);
    @@ -11465,14 +11482,14 @@

    [meta.
    -

    1 +

    1 For any type or type alias T, for each function std::meta::MOD defined in this clause, std::meta::MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.4 [meta.trans.sign].

    -
    consteval info make_signed(info type);
    -consteval info make_unsigned(info type);
    +
    consteval info make_signed(info type);
    +consteval info make_unsigned(info type);
    @@ -11481,14 +11498,14 @@

    [meta.
    -

    1 +

    1 For any type or type alias T, for each function std::meta::MOD defined in this clause, std::meta::MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.5 [meta.trans.arr].

    -
    consteval info remove_extent(info type);
    -consteval info remove_all_extents(info type);
    +
    consteval info remove_extent(info type);
    +consteval info remove_all_extents(info type);
    @@ -11497,14 +11514,14 @@

    [met
    -

    1 +

    1 For any type or type alias T, for each function std::meta::MOD defined in this clause, std::meta::MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.6 [meta.trans.ptr].

    -
    consteval info remove_pointer(info type);
    -consteval info add_pointer(info type);
    +
    consteval info remove_pointer(info type);
    +consteval info add_pointer(info type);
    @@ -11523,14 +11540,14 @@

    [m
    -

    1 +

    1 For any type or type alias T, for each function std::meta::type_MOD defined in this clause with signature std::meta::info(std::meta::info), std::meta::type_MOD(^^T) returns the reflection of the corresponding type std::MOD_t<T> as specified in 21.3.8.7 [meta.trans.other].

    -

    2 +

    2 For any pack of types or type aliases T... and range r such that ranges::to<vector>(r) == vector{^^T...} @@ -11539,7 +11556,7 @@

    [m defined in this clause, std::meta::VARIADIC-MOD(r) returns the reflection of the corresponding type std::VARIADIC-MOD_t<T...> as specified in 21.3.8.7 [meta.trans.other].

    -

    3 +

    3 For any type or type alias T, pack of types or type aliases U..., and @@ -11548,29 +11565,29 @@

    [m std::meta::invoke_result(^^T, r) returns the reflection of the corresponding type std::invoke_result_t<T, U...> (21.3.8.7 [meta.trans.other]).

    -
    consteval info remove_cvref(info type);
    -consteval info decay(info type);
    -template <reflection_range R = initializer_list<info>>
    -consteval info common_type(R&& type_args);
    -template <reflection_range R = initializer_list<info>>
    -consteval info common_reference(R&& type_args);
    -consteval info underlying_type(info type);
    -template <reflection_range R = initializer_list<info>>
    -consteval info invoke_result(info type, R&& type_args);
    -consteval info unwrap_reference(info type);
    -consteval info unwrap_ref_decay(info type);
    -

    4

    +
    consteval info remove_cvref(info type);
    +consteval info decay(info type);
    +template <reflection_range R = initializer_list<info>>
    +consteval info common_type(R&& type_args);
    +template <reflection_range R = initializer_list<info>>
    +consteval info common_reference(R&& type_args);
    +consteval info underlying_type(info type);
    +template <reflection_range R = initializer_list<info>>
    +consteval info invoke_result(info type, R&& type_args);
    +consteval info unwrap_reference(info type);
    +consteval info unwrap_ref_decay(info type);
    +

    4

    Example 1: -
    // example implementation
    -consteval info unwrap_reference(info type) {
    -  type = dealias(type);
    -  if (has_template_arguments(type) && template_of(type) == ^^reference_wrapper) {
    -    return add_lvalue_reference(template_arguments_of(type)[0]);
    -  } else {
    -    return type;
    -  }
    -}
    +
    // example implementation
    +consteval info unwrap_reference(info type) {
    +  type = dealias(type);
    +  if (has_template_arguments(type) && template_of(type) == ^^reference_wrapper) {
    +    return add_lvalue_reference(template_arguments_of(type)[0]);
    +  } else {
    +    return type;
    +  }
    +}
    — end example ]

    @@ -11581,25 +11598,25 @@

    -

    1 +

    1 For any type or type alias T, for each function std::meta::UNARY-TRAIT defined in this clause with the signature size_t(std::meta::info), std::meta::UNARY-TRAIT(^^T) equals the value of the corresponding property std::UNARY-TRAIT_v<T> as defined in 22.4 [tuple] or 22.6 [variant].

    -

    2 +

    2 For any type or type alias T and value I, for each function std::meta::BINARY-TRAIT defined in this clause with the signature info(size_t, std::meta::info), std::meta::BINARY-TRAIT(I, ^^T) returns a reflection representing the type std::BINARY-TRAIT_t<I, T> as defined in 22.4 [tuple] or 22.6 [variant].

    -
    consteval size_t tuple_size(info type);
    -consteval info tuple_element(size_t index, info type);
    -
    -consteval size_t variant_size(info type);
    -consteval info variant_alternative(size_t index, info type);
    +
    consteval size_t tuple_size(info type);
    +consteval info tuple_element(size_t index, info type);
    +
    +consteval size_t variant_size(info type);
    +consteval info variant_alternative(size_t index, info type);

    @@ -11610,7 +11627,7 @@

    22.15.3 22.15.3 [bit.cast]/3:

    -

    3 +

    3 Remarks: This function is constexpr if and only if To, From, and the types of all @@ -11618,27 +11635,27 @@

    22.15.3 From are types T such that:

    @@ -11656,10 +11673,10 @@

    -
      __cpp_impl_coroutine 201902L
    -  __cpp_impl_destroying_delete 201806L
    -  __cpp_impl_three_way_comparison 201907L
    -+ __cpp_impl_reflection 2024XXL
    +
      __cpp_impl_coroutine 201902L
    +  __cpp_impl_destroying_delete 201806L
    +  __cpp_impl_three_way_comparison 201907L
    ++ __cpp_impl_reflection 2024XXL

    @@ -11667,7 +11684,7 @@

    -
    + #define __cpp_lib_reflection 2024XXL // also in <meta>
    +
    + #define __cpp_lib_reflection 2024XXL // also in <meta>

    diff --git a/2996_reflection/reflection.md b/2996_reflection/reflection.md index 6f97d22e..f70be3b8 100644 --- a/2996_reflection/reflection.md +++ b/2996_reflection/reflection.md @@ -5412,6 +5412,18 @@ static_assert(size_of(^^X) == sizeof(int)); // instantiates X ::: ::: +[3]{.pnum} Any function in namespace `std::meta` that whose return type is `string_view` or `u8string_view` returns an object `$V$` such that `$V$.data()[$V$.size()] == '\0'`. + +::: example +```cpp +struct C { }; + +constexpr string_view sv = identifier_of(^^C); +static_assert(sv == "C"); +static_assert(sv.data()[0] == 'C'); +static_assert(sv.data()[1] == '\0'); +``` +::: ::: ::: @@ -5494,7 +5506,7 @@ consteval u8string_view u8symbol_of(operators op); [#]{.pnum} *Constant When*: The value of `op` corresponds to one of the enumerators in `operators`. -[#]{.pnum} *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. +[#]{.pnum} *Returns*: `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. ::: :::