diff --git a/2996_reflection/p2996r2.html b/2996_reflection/p2996r2.html index 6ee3109d..06003976 100644 --- a/2996_reflection/p2996r2.html +++ b/2996_reflection/p2996r2.html @@ -613,11 +613,10 @@

Contents

  • 4.4.8 substitute
  • 4.4.9 value_of<T>
  • 4.4.10 test_type, test_types
  • -
  • 4.4.11 Other Singular Reflection Predicates
  • -
  • 4.4.12 reflect_value
  • -
  • 4.4.13 nsdm_description, define_class
  • -
  • 4.4.14 Data Layout Reflection
  • -
  • 4.4.15 Other Type Traits
  • +
  • 4.4.11 reflect_value
  • +
  • 4.4.12 nsdm_description, define_class
  • +
  • 4.4.13 Data Layout Reflection
  • +
  • 4.4.14 Other Type Traits
  • 5 Proposed Wording @@ -1650,7 +1649,7 @@

    4.4.3< consteval auto test_type(info templ, info type) -> bool; consteval auto test_types(info templ, span<info const> types) -> bool; - // other type predicates + // other type predicates (see the wording) consteval auto is_public(info r) -> bool; consteval auto is_protected(info r) -> bool; consteval auto is_private(info r) -> bool; @@ -1669,39 +1668,40 @@

    4.4.3< consteval auto is_class_member(info entity) -> bool; consteval auto is_namespace_member(info entity) -> bool; consteval auto is_nsdm(info entity) -> bool; - consteval auto is_base(info entity) -> bool; - consteval auto is_namespace(info entity) -> bool; - consteval auto is_function(info entity) -> bool; - consteval auto is_variable(info entity) -> bool; - consteval auto is_type(info entity) -> bool; - consteval auto is_alias(info entity) -> bool; - consteval auto is_incomplete_type(info entity) -> bool; - consteval auto is_template(info entity) -> bool; - consteval auto is_function_template(info entity) -> bool; - consteval auto is_variable_template(info entity) -> bool; - consteval auto is_class_template(info entity) -> bool; - consteval auto is_alias_template(info entity) -> bool; - consteval auto has_template_arguments(info r) -> bool; - consteval auto is_constructor(info r) -> bool; - consteval auto is_destructor(info r) -> bool; - consteval auto is_special_member(info r) -> bool; - - // reflect_value - template<typename T> - consteval auto reflect_value(T value) -> info; - - // define_class - struct nsdm_options_t; - consteval auto nsdm_description(info class_type, nsdm_options_t options = {}) -> info; - consteval auto define_class(info class_type, span<info const>) -> info; - - // data layout - consteval auto offset_of(info entity) -> size_t; - consteval auto size_of(info entity) -> size_t; - consteval auto bit_offset_of(info entity) -> size_t; - consteval auto bit_size_of(info entity) -> size_t; - consteval auto alignment_of(info entity) -> size_t; -} + consteval auto is_static_member(info entity) -> bool; + consteval auto is_base(info entity) -> bool; + consteval auto is_namespace(info entity) -> bool; + consteval auto is_function(info entity) -> bool; + consteval auto is_variable(info entity) -> bool; + consteval auto is_type(info entity) -> bool; + consteval auto is_alias(info entity) -> bool; + consteval auto is_incomplete_type(info entity) -> bool; + consteval auto is_template(info entity) -> bool; + consteval auto is_function_template(info entity) -> bool; + consteval auto is_variable_template(info entity) -> bool; + consteval auto is_class_template(info entity) -> bool; + consteval auto is_alias_template(info entity) -> bool; + consteval auto has_template_arguments(info r) -> bool; + consteval auto is_constructor(info r) -> bool; + consteval auto is_destructor(info r) -> bool; + consteval auto is_special_member(info r) -> bool; + + // reflect_value + template<typename T> + consteval auto reflect_value(T value) -> info; + + // define_class + struct nsdm_options_t; + consteval auto nsdm_description(info class_type, nsdm_options_t options = {}) -> info; + consteval auto define_class(info class_type, span<info const>) -> info; + + // data layout + consteval auto offset_of(info entity) -> size_t; + consteval auto size_of(info entity) -> size_t; + consteval auto bit_offset_of(info entity) -> size_t; + consteval auto bit_size_of(info entity) -> size_t; + consteval auto alignment_of(info entity) -> size_t; +}

    4.4.4 name_of, display_name_of, source_location_of

    @@ -1834,109 +1834,69 @@

    static_assert(test_type(^std::is_class_v, ^S));

    An implementation is permitted to recognize standard predicate templates and implement test_type without actually instantiating the predicate template. In fact, that is recommended practice.

    -

    4.4.11 Other Singular Reflection Predicates

    +

    4.4.11 reflect_value

    namespace std::meta {
    -  consteval auto is_public(info r) -> bool;
    -  consteval auto is_protected(info r) -> bool;
    -  consteval auto is_private(info r) -> bool;
    -  consteval auto is_accessible(info r) -> bool;
    -  consteval auto is_virtual(info r) -> bool;
    -  consteval auto is_pure_virtual(info entity) -> bool;
    -  consteval auto is_override(info entity) -> bool;
    -  consteval auto is_deleted(info entity) -> bool;
    -  consteval auto is_defaulted(info entity) -> bool;
    -  consteval auto is_explicit(info entity) -> bool;
    -  consteval auto is_bit_field(info entity) -> bool;
    -  consteval auto has_static_storage_duration(info r) -> bool;
    -  consteval auto has_internal_linkage(info r) -> bool;
    -  consteval auto has_external_linkage(info r) -> bool;
    -  consteval auto has_linkage(info r) -> bool;
    -
    -  consteval auto is_class_member(info entity) -> bool;
    -  consteval auto is_namespace_member(info entity) -> bool;
    -  consteval auto is_nsdm(info entity) -> bool;
    -  consteval auto is_base(info entity) -> bool;
    -  consteval auto is_namespace(info entity) -> bool;
    -  consteval auto is_function(info entity) -> bool;
    -  consteval auto is_variable(info entity) -> bool;
    -  consteval auto is_type(info entity) -> bool;
    -  consteval auto is_alias(info entity) -> bool;
    -  consteval auto is_incomplete_type(info entity) -> bool;
    -  consteval auto is_template(info entity) -> bool;
    -  consteval auto is_function_template(info entity) -> bool;
    -  consteval auto is_variable_template(info entity) -> bool;
    -  consteval auto is_class_template(info entity) -> bool;
    -  consteval auto is_alias_template(info entity) -> bool;
    -  consteval auto has_template_arguments(info r) -> bool;
    -  consteval auto is_constructor(info r) -> bool;
    -  consteval auto is_destructor(info r) -> bool;
    -  consteval auto is_special_member(info r) -> bool;
    -}
    -
    -

    4.4.12 reflect_value

    -
    -
    namespace std::meta {
    -  template<typename T> consteval auto reflect_value(T value) -> info;
    -}
    + template<typename T> consteval auto reflect_value(T value) -> info; +}

    This metafunction produces a reflection representing the constant value of the operand.

    -

    4.4.13 nsdm_description, define_class

    -
    -
    namespace std::meta {
    -  struct nsdm_options_t {
    -    optional<string_view> name;
    -    optional<int> alignment;
    -    optional<int> width;
    -  };
    -  consteval auto nsdm_description(info type, nsdm_options options = {}) -> info;
    -  consteval auto define_class(info class_type, span<info const>) -> info;
    -}
    +

    4.4.12 nsdm_description, define_class

    +
    +
    namespace std::meta {
    +  struct nsdm_options_t {
    +    optional<string_view> name;
    +    optional<int> alignment;
    +    optional<int> width;
    +  };
    +  consteval auto nsdm_description(info type, nsdm_options options = {}) -> info;
    +  consteval auto define_class(info class_type, span<info const>) -> info;
    +}

    nsdm_description returns a reflection of a description of a non-static data member of given type. Optional alignment, bit-field-width, and name can be provided as well. If no name is provided, the name of the non-static data member is unspecified.

    define_class takes the reflection of an incomplete class/struct/union type and a range of reflections of non-static data member descriptions and it completes the given class type with nonstatic data members as described (in the given order). The given reflection is returned. For now, only non-static data member reflections are supported (via nsdm_description) but the API takes in a range of info anticipating expanding this in the near future.

    For example:

    -
    union U;
    -static_assert(is_type(define_class(^U, {
    -  nsdm_description(^int),
    -  nsdm_description(^char),
    -  nsdm_description(^double),
    -})));
    -
    -// U is now defined to the equivalent of
    -// union U {
    -//   int _0;
    -//   char _1;
    -//   double _2;
    -// };
    -
    -template<typename T> struct S;
    -constexpr auto U = define_class(^S<int>, {
    -  nsdm_description(^int, {.name="i", .align=64}),
    -  nsdm_description(^int, {.name="j", .align=64}),
    -});
    -
    -// S<int> is now defined to the equivalent of
    -// template<> struct S<int> {
    -//   alignas(64) int i;
    -//   alignas(64) int j;
    -// };
    +
    union U;
    +static_assert(is_type(define_class(^U, {
    +  nsdm_description(^int),
    +  nsdm_description(^char),
    +  nsdm_description(^double),
    +})));
    +
    +// U is now defined to the equivalent of
    +// union U {
    +//   int _0;
    +//   char _1;
    +//   double _2;
    +// };
    +
    +template<typename T> struct S;
    +constexpr auto U = define_class(^S<int>, {
    +  nsdm_description(^int, {.name="i", .align=64}),
    +  nsdm_description(^int, {.name="j", .align=64}),
    +});
    +
    +// S<int> is now defined to the equivalent of
    +// template<> struct S<int> {
    +//   alignas(64) int i;
    +//   alignas(64) int j;
    +// };

    When defining a union, if one of the alternatives has a non-trivial destructor, the defined union will still have a destructor provided - that simply does nothing. This allows implementing variant without having to further extend support in define_class for member functions.

    -

    4.4.14 Data Layout Reflection

    -
    -
    namespace std::meta {
    -  consteval auto offset_of(info entity) -> size_t;
    -  consteval auto size_of(info entity) -> size_t;
    -
    -  consteval auto bit_offset_of(info entity) -> size_t;
    -  consteval auto bit_size_of(info entity) -> size_t;
    -
    -  consteval auto alignment_of(info entity) -> size_t;
    -}
    -
    -

    4.4.15 Other Type Traits

    +

    4.4.13 Data Layout Reflection

    +
    +
    namespace std::meta {
    +  consteval auto offset_of(info entity) -> size_t;
    +  consteval auto size_of(info entity) -> size_t;
    +
    +  consteval auto bit_offset_of(info entity) -> size_t;
    +  consteval auto bit_size_of(info entity) -> size_t;
    +
    +  consteval auto alignment_of(info entity) -> size_t;
    +}
    +
    +

    4.4.14 Other Type Traits

    There is a question of whether all the type traits should be provided in std::meta. For instance, a few examples in this paper use std::meta::remove_cvref(t) as if that exists. Technically, the functionality isn’t strictly necessary - since it can be provided indirectly:

    @@ -1951,13 +1911,13 @@

    -

    - + + - - + +
    std::meta::remove_cvref(type)
    std::meta::substitute(^std::remove_cvref_t, {type})
    std::meta::remove_cvref(type)
    std::meta::substitute(^std::remove_cvref_t, {type})
    std::meta::is_const(type)
    std::meta::value_of<bool>(std::meta::substitute(^std::is_const_v, {type}))
    -std::meta::test_type(^std::is_const_v, type)
    std::meta::is_const(type)
    std::meta::value_of<bool>(std::meta::substitute(^std::is_const_v, {type}))
    +std::meta::test_type(^std::is_const_v, type)
    @@ -1969,14 +1929,14 @@

    1 Expressions with unary operators group right-to-left.

    -
      unary-expression:
    -     ...
    -     delete-expression
    -+    ^ ::
    -+    ^ namespace-name
    -+    ^ nested-name-specifieropt template-name
    -+    ^ type-id
    -+    ^ cast-expression
    +
      unary-expression:
    +     ...
    +     delete-expression
    ++    ^ ::
    ++    ^ namespace-name
    ++    ^ nested-name-specifieropt template-name
    ++    ^ type-id
    ++    ^ cast-expression

    5.1.2 [expr.reflect] The Reflection operator

    @@ -1989,7 +1949,7 @@

    4 When applied to a type-id, the reflection produces a reflection for the indicated type or type-alias.

    5 When applied to a cast-expression, the cast-expression shall be a constant expression (7.7 [expr.const]) or an id-expression (7.5.4 [expr.prim.id]) designating a variable, a function, an enumerator constant, or a nonstatic member. The cast-expression is not evaluated. If the operand of the reflection operator is an id-expression, the result is a reflection for the indicated entity. If the operand is a constant expression, the result is a reflection for the resulting value. If the operand is both an id-expression and a constant expression, the result is a reflection for both the indicated entity and the expression’s (constant) value.

    [ Example:

    -
    constexpr auto r = ^std::vector;
    +
    constexpr auto r = ^std::vector;

    end example ]

    @@ -1999,299 +1959,301 @@

    Header <meta> synopsis

    -
    namespace std::meta {
    -  // [meta.reflection.names], reflection names and locations
    -  consteval string_view name_of(info r);
    -  consteval string_view qualified_name_of(info r);
    -  consteval string_view display_name_of(info r);
    -  consteval source_location source_location_of(info r);
    -
    -  // [meta.reflection.queries], reflection queries
    -  consteval bool is_public(info r);
    -  consteval bool is_protected(info r);
    -  consteval bool is_private(info r);
    -  consteval bool is_accessible(info r);
    -  consteval bool is_virtual(info r);
    -  consteval bool is_pure_virtual(info r);
    -  consteval bool is_override(info r);
    -  consteval bool is_deleted(info r);
    -  consteval bool is_defaulted(info r);
    -  consteval bool is_explicit(info r);
    -  consteval bool is_bit_field(info r);
    -  consteval bool has_static_storage_duration(info r);
    -  consteval bool has_internal_linkage(info r);
    -  consteval bool has_external_linkage(info r);
    -  consteval bool has_linkage(info r);
    -
    -  consteval bool is_namespace(info r);
    -  consteval bool is_function(info r);
    -  consteval bool is_variable(info r);
    -  consteval bool is_type(info r);
    -  consteval bool is_alias(info r);
    -  consteval bool is_incomplete_type(info r);
    -  consteval bool is_template(info r);
    -  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 has_template_arguments(info r);
    -  consteval auto is_class_member(info entity) -> bool;
    -  consteval auto is_namespace_member(info entity) -> bool;
    -  consteval bool is_nsdm(info r);
    -  consteval bool is_base(info r);
    -  consteval bool is_constructor(info r);
    -  consteval bool is_destructor(info r);
    -  consteval bool is_special_member(info r);
    -
    -  consteval info type_of(info r);
    -  consteval info parent_of(info r);
    -  consteval info dealias(info r);
    -  consteval info template_of(info r);
    -  consteval vector<info> template_arguments_of(info r);
    -
    -  // [meta.reflection.unary.cat], primary type categories
    -  consteval bool is_void(info type);
    -  consteval bool is_null_pointer(info type);
    -  consteval bool is_integral(info type);
    -  consteval bool is_floating_point(info type);
    -  consteval bool is_array(info type);
    -  consteval bool is_pointer(info type);
    -  consteval bool is_lvalue_reference(info type);
    -  consteval bool is_rvalue_reference(info type);
    -  consteval bool is_member_object_pointer(info type);
    -  consteval bool is_member_function_pointer(info type);
    -  consteval bool is_enum(info type);
    -  consteval bool is_union(info type);
    -  consteval bool is_class(info type);
    -  consteval bool is_function(info type);
    -
    -  // [meta.reflection.unary.comp], composite type categories
    -  consteval bool is_reference(info type);
    -  consteval bool is_arithmetic(info type);
    -  consteval bool is_fundamental(info type);
    -  consteval bool is_object(info type);
    -  consteval bool is_scalar(info type);
    -  consteval bool is_compound(info type);
    -  consteval bool is_member_pointer(info type);
    -
    -  // [meta.reflection unary.prop], type properties
    -  consteval bool is_const(info type);
    -  consteval bool is_volatile(info type);
    -  consteval bool is_trivial(info type);
    -  consteval bool is_trivially_copyable(info type);
    -  consteval bool is_standard_layout(info type);
    -  consteval bool is_empty(info type);
    -  consteval bool is_polymorphic(info type);
    -  consteval bool is_abstract(info type);
    -  consteval bool is_final(info type);
    -  consteval bool is_aggregate(info type);
    -  consteval bool is_signed(info type);
    -  consteval bool is_unsigned(info type);
    -  consteval bool is_bounded_array(info type);
    -  consteval bool is_unbounded_array(info type);
    -  consteval bool is_scoped_enum(info type);
    -
    -  consteval bool is_constructible(info type, span<info const> type_args);
    -  consteval bool is_default_constructible(info type);
    -  consteval bool is_copy_constructible(info type);
    -  consteval bool is_move_constructible(info type);
    -
    -  consteval bool is_assignable(info dst_type, info src_type);
    -  consteval bool is_copy_assignable(info type);
    -  consteval bool is_move_assignable(info type);
    -
    -  consteval bool is_swappable_with(info dst_type, info src_type);
    -  consteval bool is_swappable(info type);
    -
    -  consteval bool is_destructible(info type);
    -
    -  consteval bool is_trivially_constructible(info type, span<info const> type_args);
    -  consteval bool is_trivially_default_constructible(info type);
    -  consteval bool is_trivially_copy_constructible(info type);
    -  consteval bool is_trivially_move_constructible(info type);
    -
    -  consteval bool is_trivially_assignable(info dst_type, info src_type);
    -  consteval bool is_trivially_copy_assignable(info type);
    -  consteval bool is_trivially_move_assignable(info type);
    -  consteval bool is_trivially_destructible(info type);
    -
    -  consteval bool is_nothrow_constructible(info type, span<info const> type_args);
    -  consteval bool is_nothrow_default_constructible(info type);
    -  consteval bool is_nothrow_copy_constructible(info type);
    -  consteval bool is_nothrow_move_constructible(info type);
    -
    -  consteval bool is_nothrow_assignable(info dst_type, info src_type);
    -  consteval bool is_nothrow_copy_assignable(info type);
    -  consteval bool is_nothrow_move_assignable(info type);
    -
    -  consteval bool is_nothrow_swappable_with(info dst_type, info src_type);
    -  consteval bool is_nothrow_swappable(info type);
    -
    -  consteval bool is_nothrow_destructible(info type);
    -
    -  consteval bool is_implicit_lifetime(info type);
    -
    -  consteval bool has_virtual_destructor(info type);
    -
    -  consteval bool has_unique_object_representations(info type);
    -
    -  consteval bool reference_constructs_from_temporary(info dst_type, info src_type);
    -  consteval bool reference_converts_from_temporary(info dst_type, info src_type);
    -
    -  // [meta.reflection.unary.prop.query], type property queries
    -  consteval size_t alignment_of(info type);
    -  consteval size_t rank(info type);
    -  consteval size_t extent(info type, unsigned i = 0);
    -
    -  // [meta.reflection.rel], type relations
    -  consteval bool is_same(info type1, info type2);
    -  consteval bool is_base_of(info base_type, info derived_type);
    -  consteval bool is_convertible(info src_type, info dst_type);
    -  consteval bool is_nothrow_convertible(info src_type, info dst_type);
    -  consteval bool is_layout_compatible(info type1, info type2);
    -  consteval bool is_pointer_interconvertible_base_of(info base_type, info derived_type);
    -
    -  consteval bool is_invocable(info type, span<const info> type_args);
    -  consteval bool is_invocable_r(info result_type, info type, span<const info> type_args);
    -
    -  consteval bool is_nothrow_invocable(info type, span<const info> type_args);
    -  consteval bool is_nothrow_invocable_r(info result_type, info type, span<const info> type_args);
    -
    -  // [meta.reflection.trans.cv], const-volatile modifications
    -  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);
    -
    -  // [meta.reflection.trans.ref], reference modifications
    -  consteval info remove_reference(info type);
    -  consteval info add_lvalue_reference(info type);
    -  consteval info add_rvalue_reference(info type);
    -
    -  // [meta.reflection.trans.sign], sign modifications
    -  consteval info make_signed(info type);
    -  consteval info make_unsigned(info type);
    -
    -  // [meta.reflection.trans.arr], array modifications
    -  consteval info remove_extent(info type);
    -  consteval info remove_all_extents(info type);
    -
    -  // [meta.reflection.trans.ptr], pointer modifications
    -  consteval info remove_pointer(info type);
    -  consteval info add_pointer(info type);
    -
    -  // [meta.reflection.trans.other], other transformations
    -  consteval info remove_cvref(info type);
    -  consteval info decay(info type);
    -  consteval info common_type(span<const info> type_args);
    -  consteval info common_reference(span<const info> type_args);
    -  consteval info underlying_type(info type);
    -  consteval info invoke_result(info type, span<const info> type_args);
    -  consteval info unwrap_reference(info type);
    -  consteval info unwrap_ref_decay(info type);
    -}
    +
    namespace std::meta {
    +  // [meta.reflection.names], reflection names and locations
    +  consteval string_view name_of(info r);
    +  consteval string_view qualified_name_of(info r);
    +  consteval string_view display_name_of(info r);
    +  consteval source_location source_location_of(info r);
    +
    +  // [meta.reflection.queries], reflection queries
    +  consteval bool is_public(info r);
    +  consteval bool is_protected(info r);
    +  consteval bool is_private(info r);
    +  consteval bool is_accessible(info r);
    +  consteval bool is_virtual(info r);
    +  consteval bool is_pure_virtual(info r);
    +  consteval bool is_override(info r);
    +  consteval bool is_deleted(info r);
    +  consteval bool is_defaulted(info r);
    +  consteval bool is_explicit(info r);
    +  consteval bool is_bit_field(info r);
    +  consteval bool has_static_storage_duration(info r);
    +  consteval bool has_internal_linkage(info r);
    +  consteval bool has_external_linkage(info r);
    +  consteval bool has_linkage(info r);
    +
    +  consteval bool is_namespace(info r);
    +  consteval bool is_function(info r);
    +  consteval bool is_variable(info r);
    +  consteval bool is_type(info r);
    +  consteval bool is_alias(info r);
    +  consteval bool is_incomplete_type(info r);
    +  consteval bool is_template(info r);
    +  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 has_template_arguments(info r);
    +  consteval auto is_class_member(info entity) -> bool;
    +  consteval auto is_namespace_member(info entity) -> bool;
    +  consteval bool is_nsdm(info r);
    +  consteval bool is_static_member(info r);
    +  consteval bool is_base(info r);
    +  consteval bool is_constructor(info r);
    +  consteval bool is_destructor(info r);
    +  consteval bool is_special_member(info r);
    +
    +  consteval info type_of(info r);
    +  consteval info parent_of(info r);
    +  consteval info dealias(info r);
    +  consteval info template_of(info r);
    +  consteval vector<info> template_arguments_of(info r);
    +
    +  // [meta.reflection.unary.cat], primary type categories
    +  consteval bool is_void(info type);
    +  consteval bool is_null_pointer(info type);
    +  consteval bool is_integral(info type);
    +  consteval bool is_floating_point(info type);
    +  consteval bool is_array(info type);
    +  consteval bool is_pointer(info type);
    +  consteval bool is_lvalue_reference(info type);
    +  consteval bool is_rvalue_reference(info type);
    +  consteval bool is_member_object_pointer(info type);
    +  consteval bool is_member_function_pointer(info type);
    +  consteval bool is_enum(info type);
    +  consteval bool is_union(info type);
    +  consteval bool is_class(info type);
    +  consteval bool is_function(info type);
    +
    +  // [meta.reflection.unary.comp], composite type categories
    +  consteval bool is_reference(info type);
    +  consteval bool is_arithmetic(info type);
    +  consteval bool is_fundamental(info type);
    +  consteval bool is_object(info type);
    +  consteval bool is_scalar(info type);
    +  consteval bool is_compound(info type);
    +  consteval bool is_member_pointer(info type);
    +
    +  // [meta.reflection unary.prop], type properties
    +  consteval bool is_const(info type);
    +  consteval bool is_volatile(info type);
    +  consteval bool is_trivial(info type);
    +  consteval bool is_trivially_copyable(info type);
    +  consteval bool is_standard_layout(info type);
    +  consteval bool is_empty(info type);
    +  consteval bool is_polymorphic(info type);
    +  consteval bool is_abstract(info type);
    +  consteval bool is_final(info type);
    +  consteval bool is_aggregate(info type);
    +  consteval bool is_signed(info type);
    +  consteval bool is_unsigned(info type);
    +  consteval bool is_bounded_array(info type);
    +  consteval bool is_unbounded_array(info type);
    +  consteval bool is_scoped_enum(info type);
    +
    +  consteval bool is_constructible(info type, span<info const> type_args);
    +  consteval bool is_default_constructible(info type);
    +  consteval bool is_copy_constructible(info type);
    +  consteval bool is_move_constructible(info type);
    +
    +  consteval bool is_assignable(info dst_type, info src_type);
    +  consteval bool is_copy_assignable(info type);
    +  consteval bool is_move_assignable(info type);
    +
    +  consteval bool is_swappable_with(info dst_type, info src_type);
    +  consteval bool is_swappable(info type);
    +
    +  consteval bool is_destructible(info type);
    +
    +  consteval bool is_trivially_constructible(info type, span<info const> type_args);
    +  consteval bool is_trivially_default_constructible(info type);
    +  consteval bool is_trivially_copy_constructible(info type);
    +  consteval bool is_trivially_move_constructible(info type);
    +
    +  consteval bool is_trivially_assignable(info dst_type, info src_type);
    +  consteval bool is_trivially_copy_assignable(info type);
    +  consteval bool is_trivially_move_assignable(info type);
    +  consteval bool is_trivially_destructible(info type);
    +
    +  consteval bool is_nothrow_constructible(info type, span<info const> type_args);
    +  consteval bool is_nothrow_default_constructible(info type);
    +  consteval bool is_nothrow_copy_constructible(info type);
    +  consteval bool is_nothrow_move_constructible(info type);
    +
    +  consteval bool is_nothrow_assignable(info dst_type, info src_type);
    +  consteval bool is_nothrow_copy_assignable(info type);
    +  consteval bool is_nothrow_move_assignable(info type);
    +
    +  consteval bool is_nothrow_swappable_with(info dst_type, info src_type);
    +  consteval bool is_nothrow_swappable(info type);
    +
    +  consteval bool is_nothrow_destructible(info type);
    +
    +  consteval bool is_implicit_lifetime(info type);
    +
    +  consteval bool has_virtual_destructor(info type);
    +
    +  consteval bool has_unique_object_representations(info type);
    +
    +  consteval bool reference_constructs_from_temporary(info dst_type, info src_type);
    +  consteval bool reference_converts_from_temporary(info dst_type, info src_type);
    +
    +  // [meta.reflection.unary.prop.query], type property queries
    +  consteval size_t alignment_of(info type);
    +  consteval size_t rank(info type);
    +  consteval size_t extent(info type, unsigned i = 0);
    +
    +  // [meta.reflection.rel], type relations
    +  consteval bool is_same(info type1, info type2);
    +  consteval bool is_base_of(info base_type, info derived_type);
    +  consteval bool is_convertible(info src_type, info dst_type);
    +  consteval bool is_nothrow_convertible(info src_type, info dst_type);
    +  consteval bool is_layout_compatible(info type1, info type2);
    +  consteval bool is_pointer_interconvertible_base_of(info base_type, info derived_type);
    +
    +  consteval bool is_invocable(info type, span<const info> type_args);
    +  consteval bool is_invocable_r(info result_type, info type, span<const info> type_args);
    +
    +  consteval bool is_nothrow_invocable(info type, span<const info> type_args);
    +  consteval bool is_nothrow_invocable_r(info result_type, info type, span<const info> type_args);
    +
    +  // [meta.reflection.trans.cv], const-volatile modifications
    +  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);
    +
    +  // [meta.reflection.trans.ref], reference modifications
    +  consteval info remove_reference(info type);
    +  consteval info add_lvalue_reference(info type);
    +  consteval info add_rvalue_reference(info type);
    +
    +  // [meta.reflection.trans.sign], sign modifications
    +  consteval info make_signed(info type);
    +  consteval info make_unsigned(info type);
    +
    +  // [meta.reflection.trans.arr], array modifications
    +  consteval info remove_extent(info type);
    +  consteval info remove_all_extents(info type);
    +
    +  // [meta.reflection.trans.ptr], pointer modifications
    +  consteval info remove_pointer(info type);
    +  consteval info add_pointer(info type);
    +
    +  // [meta.reflection.trans.other], other transformations
    +  consteval info remove_cvref(info type);
    +  consteval info decay(info type);
    +  consteval info common_type(span<const info> type_args);
    +  consteval info common_reference(span<const info> type_args);
    +  consteval info underlying_type(info type);
    +  consteval info invoke_result(info type, span<const info> type_args);
    +  consteval info unwrap_reference(info type);
    +  consteval info unwrap_ref_decay(info type);
    +}

    5.2.2 [meta.reflection.names] Reflection names and locations

    -
    consteval string_view name_of(info r);
    -consteval string_view qualified_name_of(info r);
    +
    consteval string_view name_of(info r);
    +consteval string_view qualified_name_of(info r);

    1 Returns: If r designates a declared entity X, then the unqualified and qualified names of X, respectively. Otherwise, an empty string_view.

    -
    consteval string_view display_name_of(info r);
    +
    consteval string_view display_name_of(info r);

    2 Returns: An implementation-defined string suitable for identifying the reflected construct.

    -
    consteval source_location source_location_of(info r);
    +
    consteval source_location source_location_of(info r);

    3 Returns: An implementation-defined source_location corresponding to the reflected construct.

    5.2.3 [meta.reflection.queries] Reflection queries

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

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

    -
    consteval bool is_accessible(info r);
    +
    consteval bool is_accessible(info r);

    2 Returns: TODO

    -
    consteval bool is_virtual(info r);
    +
    consteval bool is_virtual(info r);

    3 Returns: true if r designates a either a virtual member function or a virtual base class. Otherwise, false.

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

    4 Returns: true if r designates a member function that is pure virtual or an override, respectively. Otherwise, false.

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

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

    +
    consteval bool is_deleted(info r);

    5 Returns: true if r designates a function or member function that is defined as deleted. Otherwise, false.

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

    6 Returns: true if r designates a member function that is defined as defaulted. Otherwise, false.

    -
    consteval bool is_explicit(info r);
    +
    consteval bool is_explicit(info r);

    7 Returns: true if r designates a member function that is declared explicit. Otherwise, false.

    -
    consteval bool is_bit_field(info r);
    +
    consteval bool is_bit_field(info r);

    8 Returns: true if r designates a bit-field. Otherwise, false.

    -
    consteval bool has_static_storage_duration(info r);
    +
    consteval bool has_static_storage_duration(info r);

    9 Returns: true if r designates an object that has static storage duration. Otherwise, false.

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

    10 Returns: true if r designates an entity that has internal linkage, external linkage, or any linkage, respectively ([basic.link]). Otherwise, false.

    -
    consteval bool is_namespace(info r);
    +
    consteval bool is_namespace(info r);

    11 Returns: true if r designates a namespace or namespace alias. Otherwise, false.

    -
    consteval bool is_function(info r);
    +
    consteval bool is_function(info r);

    12 Returns: true if r designates a function or member function. Otherwise, false.

    -
    consteval bool is_variable(info r);
    +
    consteval bool is_variable(info r);

    13 Returns: true if r designates a variable. Otherwise, false.

    -
    consteval bool is_type(info r);
    +
    consteval bool is_type(info r);

    14 Returns: true if r designates a type or a type alias. Otherwise, false.

    -
    consteval bool is_alias(info r);
    +
    consteval bool is_alias(info r);

    15 Returns: true if r designates a type alias, alias template, or namespace alias. Otherwise, false.

    -
    consteval bool is_incomplete_type(info r);
    +
    consteval bool is_incomplete_type(info r);

    16 Returns: true if delias(r) designates an incomplete type. Otherwise, false.

    -
    consteval bool is_template(info r);
    +
    consteval bool is_template(info r);

    17 Returns: true if r designates a function template, class template, variable template, or alias template. Otherwise, false.

    18 Note 1: A template specialization is not a template. is_template(^std::vector) is true but is_template(^std::vector<int>) 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_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);

    19 Returns: true if r designates a function template, class template, variable template, or alias template, respectively. Otherwise, false.

    -
    consteval bool has_template_arguments(info r);
    +
    consteval bool has_template_arguments(info r);

    20 Returns: true if r designates an instantiation of a function template, variable template, class template, or an alias template. Otherwise, false.

    -
    consteval auto is_class_member(info entity) -> bool;
    -consteval auto is_namespace_member(info entity) -> bool;
    -consteval bool is_nsdm(info r);
    -consteval bool is_base(info r);
    -consteval bool is_constructor(info r);
    -consteval bool is_destructor(info r);
    -consteval bool is_special_member(info r);
    -

    21 Returns: true if r designates a class member, namespace member, non-static data member, base class member, constructor, destructor, or special member, respectively. Otherwise, false.

    -
    consteval info type_of(info r);
    +
    consteval auto is_class_member(info entity) -> bool;
    +consteval auto is_namespace_member(info entity) -> bool;
    +consteval bool is_nsdm(info r);
    +consteval bool is_static_member(info r);
    +consteval bool is_base(info r);
    +consteval bool is_constructor(info r);
    +consteval bool is_destructor(info r);
    +consteval bool is_special_member(info r);
    +

    21 Returns: true if r designates a class member, namespace member, non-static data member, static member, base class member, constructor, destructor, or special member, respectively. Otherwise, false.

    +
    consteval info type_of(info r);

    22 Mandates: r designates a typed entity.

    23 Returns: A reflection of the type of that entity.

    -
    consteval info parent_of(info r);
    +
    consteval info parent_of(info r);

    24 Mandates: r designates a member of a class or a namespace.

    25 Returns: A reflection of the that entity’s immediately enclosing class or namespace.

    -
    consteval info dealias(info r);
    +
    consteval info dealias(info r);

    26 Returns: If r designates a type alias or a namespace alias, a reflection designating the underlying entity. Otherwise, r.

    27 [Example

    -
    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);
    +
    consteval info template_of(info r);
    +consteval vector<info> template_arguments_of(info r);

    28 Mandates: has_template_arguments(r) is true.

    -

    29 Returns: A reflection of the template, and the reflections of the template arguments, repectively.

    +

    29 Returns: A reflection of the template of r, and the reflections of the template arguments of, the specialization designated by r, repectively.

    30 [Example:

    -
    template <class T, class U=T> struct Pair { };
    -template <class T> using PairPtr = Pair<T*>;
    -
    -static_assert(template_of(^Pair<int>) == ^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> using PairPtr = Pair<T*>;
    +
    +static_assert(template_of(^Pair<int>) == ^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]

    @@ -2306,27 +2268,27 @@

    1 For any type T, for each function std::meta::TRAIT defined in this clause, std::meta::TRAIT(^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(info type);
    -consteval bool is_null_pointer(info type);
    -consteval bool is_integral(info type);
    -consteval bool is_floating_point(info type);
    -consteval bool is_array(info type);
    -consteval bool is_pointer(info type);
    -consteval bool is_lvalue_reference(info type);
    -consteval bool is_rvalue_reference(info type);
    -consteval bool is_member_object_pointer(info type);
    -consteval bool is_member_function_pointer(info type);
    -consteval bool is_enum(info type);
    -consteval bool is_union(info type);
    -consteval bool is_class(info type);
    -consteval bool is_function(info type);
    +
    consteval bool is_void(info type);
    +consteval bool is_null_pointer(info type);
    +consteval bool is_integral(info type);
    +consteval bool is_floating_point(info type);
    +consteval bool is_array(info type);
    +consteval bool is_pointer(info type);
    +consteval bool is_lvalue_reference(info type);
    +consteval bool is_rvalue_reference(info type);
    +consteval bool is_member_object_pointer(info type);
    +consteval bool is_member_function_pointer(info type);
    +consteval bool is_enum(info type);
    +consteval bool is_union(info type);
    +consteval bool is_class(info type);
    +consteval bool is_function(info type);

    2 [Example

    -
    // an example implementation
    -namespace std::meta {
    -  consteval bool is_void(info type) {
    -    return value_of<bool>(substitute(^is_void_v, {type}));
    -  }
    -}
    +
    // an example implementation
    +namespace std::meta {
    +  consteval bool is_void(info type) {
    +    return value_of<bool>(substitute(^is_void_v, {type}));
    +  }
    +}

    -end example]

    @@ -2334,13 +2296,13 @@

    1 For any type T, for each function std::meta::TRAIT defined in this clause, std::meta::TRAIT(^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(info type);
    -consteval bool is_arithmetic(info type);
    -consteval bool is_fundamental(info type);
    -consteval bool is_object(info type);
    -consteval bool is_scalar(info type);
    -consteval bool is_compound(info type);
    -consteval bool is_member_pointer(info type);
    +
    consteval bool is_reference(info type);
    +consteval bool is_arithmetic(info type);
    +consteval bool is_fundamental(info type);
    +consteval bool is_object(info type);
    +consteval bool is_scalar(info type);
    +consteval bool is_compound(info type);
    +consteval bool is_member_pointer(info type);

    5.2.4.3 [meta.reflection.unary.prop] Type properties

    @@ -2349,68 +2311,68 @@

    1 For any type T, for each function std::meta::UNARY-TRAIT defined in this clause with signature bool(std::meta::info), 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 For any types T and U, for each function std::meta::BINARY-TRAIT defined in this clause with signature bool(std::meta::info, std::meta::info), 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 For any type T and pack of types U..., for each function std::meta::VARIADIC-TRAIT defined in this clause with signature bool(std::meta::info, std::span<const std::meta::info>), std::meta::VARIADIC-TRAIT(^T, {^U...}) 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(info type);
    -consteval bool is_volatile(info type);
    -consteval bool is_trivial(info type);
    -consteval bool is_trivially_copyable(info type);
    -consteval bool is_standard_layout(info type);
    -consteval bool is_empty(info type);
    -consteval bool is_polymorphic(info type);
    -consteval bool is_abstract(info type);
    -consteval bool is_final(info type);
    -consteval bool is_aggregate(info type);
    -consteval bool is_signed(info type);
    -consteval bool is_unsigned(info type);
    -consteval bool is_bounded_array(info type);
    -consteval bool is_unbounded_array(info type);
    -consteval bool is_scoped_enum(info type);
    -
    -consteval bool is_constructible(info type, span<info const> type_args);
    -consteval bool is_default_constructible(info type);
    -consteval bool is_copy_constructible(info type);
    -consteval bool is_move_constructible(info type);
    -
    -consteval bool is_assignable(info dst_type, info src_type);
    -consteval bool is_copy_assignable(info type);
    -consteval bool is_move_assignable(info type);
    -
    -consteval bool is_swappable_with(info dst_type, info src_type);
    -consteval bool is_swappable(info type);
    -
    -consteval bool is_destructible(info type);
    -
    -consteval bool is_trivially_constructible(info type, span<info const> type_args);
    -consteval bool is_trivially_default_constructible(info type);
    -consteval bool is_trivially_copy_constructible(info type);
    -consteval bool is_trivially_move_constructible(info type);
    -
    -consteval bool is_trivially_assignable(info dst_type, info src_type);
    -consteval bool is_trivially_copy_assignable(info type);
    -consteval bool is_trivially_move_assignable(info type);
    -consteval bool is_trivially_destructible(info type);
    -
    -consteval bool is_nothrow_constructible(info type, span<info const> type_args);
    -consteval bool is_nothrow_default_constructible(info type);
    -consteval bool is_nothrow_copy_constructible(info type);
    -consteval bool is_nothrow_move_constructible(info type);
    -
    -consteval bool is_nothrow_assignable(info dst_type, info src_type);
    -consteval bool is_nothrow_copy_assignable(info type);
    -consteval bool is_nothrow_move_assignable(info type);
    -
    -consteval bool is_nothrow_swappable_with(info dst_type, info src_type);
    -consteval bool is_nothrow_swappable(info type);
    -
    -consteval bool is_nothrow_destructible(info type);
    -
    -consteval bool is_implicit_lifetime(info type);
    -
    -consteval bool has_virtual_destructor(info type);
    -
    -consteval bool has_unique_object_representations(info type);
    -
    -consteval bool reference_constructs_from_temporary(info dst_type, info src_type);
    -consteval bool reference_converts_from_temporary(info dst_type, info src_type);
    +
    consteval bool is_const(info type);
    +consteval bool is_volatile(info type);
    +consteval bool is_trivial(info type);
    +consteval bool is_trivially_copyable(info type);
    +consteval bool is_standard_layout(info type);
    +consteval bool is_empty(info type);
    +consteval bool is_polymorphic(info type);
    +consteval bool is_abstract(info type);
    +consteval bool is_final(info type);
    +consteval bool is_aggregate(info type);
    +consteval bool is_signed(info type);
    +consteval bool is_unsigned(info type);
    +consteval bool is_bounded_array(info type);
    +consteval bool is_unbounded_array(info type);
    +consteval bool is_scoped_enum(info type);
    +
    +consteval bool is_constructible(info type, span<info const> type_args);
    +consteval bool is_default_constructible(info type);
    +consteval bool is_copy_constructible(info type);
    +consteval bool is_move_constructible(info type);
    +
    +consteval bool is_assignable(info dst_type, info src_type);
    +consteval bool is_copy_assignable(info type);
    +consteval bool is_move_assignable(info type);
    +
    +consteval bool is_swappable_with(info dst_type, info src_type);
    +consteval bool is_swappable(info type);
    +
    +consteval bool is_destructible(info type);
    +
    +consteval bool is_trivially_constructible(info type, span<info const> type_args);
    +consteval bool is_trivially_default_constructible(info type);
    +consteval bool is_trivially_copy_constructible(info type);
    +consteval bool is_trivially_move_constructible(info type);
    +
    +consteval bool is_trivially_assignable(info dst_type, info src_type);
    +consteval bool is_trivially_copy_assignable(info type);
    +consteval bool is_trivially_move_assignable(info type);
    +consteval bool is_trivially_destructible(info type);
    +
    +consteval bool is_nothrow_constructible(info type, span<info const> type_args);
    +consteval bool is_nothrow_default_constructible(info type);
    +consteval bool is_nothrow_copy_constructible(info type);
    +consteval bool is_nothrow_move_constructible(info type);
    +
    +consteval bool is_nothrow_assignable(info dst_type, info src_type);
    +consteval bool is_nothrow_copy_assignable(info type);
    +consteval bool is_nothrow_move_assignable(info type);
    +
    +consteval bool is_nothrow_swappable_with(info dst_type, info src_type);
    +consteval bool is_nothrow_swappable(info type);
    +
    +consteval bool is_nothrow_destructible(info type);
    +
    +consteval bool is_implicit_lifetime(info type);
    +
    +consteval bool has_virtual_destructor(info type);
    +
    +consteval bool has_unique_object_representations(info type);
    +
    +consteval bool reference_constructs_from_temporary(info dst_type, info src_type);
    +consteval bool reference_converts_from_temporary(info dst_type, info src_type);

    5.2.4.4 [meta.reflection.unary.prop.query] Type property queries

    @@ -2418,9 +2380,9 @@

    1 For any type T, for each function std::meta::PROP defined in this clause with signature size_t(std::meta::info), std::meta::PROP(^T) equals the value of the corresponding type property std::PROP_v<T> as specified in 21.3.6 [meta.unary.prop.query].

    2 For any type T and unsigned integer value I, std::meta::extent(^T, I) equals std::extent_v<T, I> ([meta.unary.prop.query]).

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

    5.2.4.5 [meta.reflection.rel], Type relations

    @@ -2429,18 +2391,18 @@

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

    2 For any type T and pack of types U..., for each function std::meta::VARIADIC-REL defined in this clause with signature bool(std::meta::info, std::span<const std::meta::info>), std::meta::VARIADIC-REL(^T, {^U...}) equals the value of the corresponding type relation std::VARIADIC-REL_v<T, U...> as specified in 21.3.7 [meta.rel].

    3 For any types T and R and pack of types U..., for each function std::meta::VARIADIC-REL-R defined in this clause with signature bool(std::meta::info, std::meta::info, std::span<const std::meta::info>), std::meta::VARIADIC-REL-R(^R, ^T, {^U...}) 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(info type1, info type2);
    -consteval bool is_base_of(info base_type, info derived_type);
    -consteval bool is_convertible(info src_type, info dst_type);
    -consteval bool is_nothrow_convertible(info src_type, info dst_type);
    -consteval bool is_layout_compatible(info type1, info type2);
    -consteval bool is_pointer_interconvertible_base_of(info base_type, info derived_type);
    -
    -consteval bool is_invocable(info type, span<const info> type_args);
    -consteval bool is_invocable_r(info result_type, info type, span<const info> type_args);
    -
    -consteval bool is_nothrow_invocable(info type, span<const info> type_args);
    -consteval bool is_nothrow_invocable_r(info result_type, info type, span<const info> type_args);
    +
    consteval bool is_same(info type1, info type2);
    +consteval bool is_base_of(info base_type, info derived_type);
    +consteval bool is_convertible(info src_type, info dst_type);
    +consteval bool is_nothrow_convertible(info src_type, info dst_type);
    +consteval bool is_layout_compatible(info type1, info type2);
    +consteval bool is_pointer_interconvertible_base_of(info base_type, info derived_type);
    +
    +consteval bool is_invocable(info type, span<const info> type_args);
    +consteval bool is_invocable_r(info result_type, info type, span<const info> type_args);
    +
    +consteval bool is_nothrow_invocable(info type, span<const info> type_args);
    +consteval bool is_nothrow_invocable_r(info result_type, info type, span<const info> type_args);

    4 Note 1: 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(t, u) is true. t == dealias(u) is also true. — end note ].

    @@ -2448,45 +2410,45 @@

    1 For any type 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);

    5.2.4.7 [meta.reflection.trans.ref], Reference modifications

    1 For any type 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);

    5.2.4.8 [meta.reflection.trans.sign], Sign modifications

    1 For any type 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);

    5.2.4.9 [meta.reflection.trans.arr], Array modifications

    1 For any type 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);

    5.2.4.10 [meta.reflection.trans.ptr], Pointer modifications

    1 For any type 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);

    5.2.4.11 [meta.reflection.trans.other], Other transformations

    @@ -2496,23 +2458,23 @@

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

    2 For any pack of types T..., for each function std::meta::VARIADIC-MOD defined in this clause with signature std::meta::info(std::span<const std::meta::info>), std::meta::VARIADIC-MOD({^T...}) returns the reflection of the corresponding type std::VARIADIC-MOD_t<T...> as specified in 21.3.8.7 [meta.trans.other].

    3 For any type T and pack of types U..., std::meta::invoke_result(^T, {^u...}) 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);
    -consteval info common_type(span<const info> type_args);
    -consteval info common_reference(span<const info> type_args);
    -consteval info underlying_type(info type);
    -consteval info invoke_result(info type, span<const info> type_args);
    -consteval info unwrap_reference(info type);
    -consteval info unwrap_ref_decay(info type);
    +
    consteval info remove_cvref(info type);
    +consteval info decay(info type);
    +consteval info common_type(span<const info> type_args);
    +consteval info common_reference(span<const info> type_args);
    +consteval info underlying_type(info type);
    +consteval info invoke_result(info type, span<const info> type_args);
    +consteval info unwrap_reference(info type);
    +consteval info unwrap_ref_decay(info type);

    4 [Example:

    -
    // example implementation
    -consteval info unwrap_reference(info 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) {
    +  if (has_template_arguments(type) && template_of(type) == ^reference_wrapper) {
    +    return add_lvalue_reference(template_arguments_of(type)[0]);
    +  } else {
    +    return type;
    +  }
    +}

    -end example]

    diff --git a/2996_reflection/reflection.md b/2996_reflection/reflection.md index 3bcf72db..7ab69046 100644 --- a/2996_reflection/reflection.md +++ b/2996_reflection/reflection.md @@ -1318,7 +1318,7 @@ namespace std::meta { consteval auto test_type(info templ, info type) -> bool; consteval auto test_types(info templ, span types) -> bool; - // @[other type predicates](#other-singular-reflection-predicates)@ + // other type predicates (see @[the wording](#meta.reflection.queries-reflection-queries)@) consteval auto is_public(info r) -> bool; consteval auto is_protected(info r) -> bool; consteval auto is_private(info r) -> bool; @@ -1337,6 +1337,7 @@ namespace std::meta { consteval auto is_class_member(info entity) -> bool; consteval auto is_namespace_member(info entity) -> bool; consteval auto is_nsdm(info entity) -> bool; + consteval auto is_static_member(info entity) -> bool; consteval auto is_base(info entity) -> bool; consteval auto is_namespace(info entity) -> bool; consteval auto is_function(info entity) -> bool; @@ -1595,51 +1596,6 @@ static_assert(test_type(^std::is_class_v, ^S)); An implementation is permitted to recognize standard predicate templates and implement `test_type` without actually instantiating the predicate template. In fact, that is recommended practice. -### Other Singular Reflection Predicates - -:::bq -```c++ -namespace std::meta { - consteval auto is_public(info r) -> bool; - consteval auto is_protected(info r) -> bool; - consteval auto is_private(info r) -> bool; - consteval auto is_accessible(info r) -> bool; - consteval auto is_virtual(info r) -> bool; - consteval auto is_pure_virtual(info entity) -> bool; - consteval auto is_override(info entity) -> bool; - consteval auto is_deleted(info entity) -> bool; - consteval auto is_defaulted(info entity) -> bool; - consteval auto is_explicit(info entity) -> bool; - consteval auto is_bit_field(info entity) -> bool; - consteval auto has_static_storage_duration(info r) -> bool; - consteval auto has_internal_linkage(info r) -> bool; - consteval auto has_external_linkage(info r) -> bool; - consteval auto has_linkage(info r) -> bool; - - consteval auto is_class_member(info entity) -> bool; - consteval auto is_namespace_member(info entity) -> bool; - consteval auto is_nsdm(info entity) -> bool; - consteval auto is_base(info entity) -> bool; - consteval auto is_namespace(info entity) -> bool; - consteval auto is_function(info entity) -> bool; - consteval auto is_variable(info entity) -> bool; - consteval auto is_type(info entity) -> bool; - consteval auto is_alias(info entity) -> bool; - consteval auto is_incomplete_type(info entity) -> bool; - consteval auto is_template(info entity) -> bool; - consteval auto is_function_template(info entity) -> bool; - consteval auto is_variable_template(info entity) -> bool; - consteval auto is_class_template(info entity) -> bool; - consteval auto is_alias_template(info entity) -> bool; - consteval auto has_template_arguments(info r) -> bool; - consteval auto is_constructor(info r) -> bool; - consteval auto is_destructor(info r) -> bool; - consteval auto is_special_member(info r) -> bool; -} -``` -::: - - ### `reflect_value` :::bq @@ -1860,6 +1816,7 @@ namespace std::meta { consteval auto is_class_member(info entity) -> bool; consteval auto is_namespace_member(info entity) -> bool; consteval bool is_nsdm(info r); + consteval bool is_static_member(info r); consteval bool is_base(info r); consteval bool is_constructor(info r); consteval bool is_destructor(info r); @@ -2068,7 +2025,7 @@ consteval bool is_virtual(info r); consteval bool is_pure_virtual(info r); consteval bool is_override(info r); ``` -[#]{.pnum} *Returns*: `true` if `r` designates a member function that is pure virtual or an override, respectively. Otherwise, `false`. +[#]{.pnum} *Returns*: `true` if `r` designates a member function that is pure virtual or overrides another member function, respectively. Otherwise, `false`. ```cpp consteval bool is_deleted(info r); @@ -2165,13 +2122,14 @@ consteval bool has_template_arguments(info r); consteval auto is_class_member(info entity) -> bool; consteval auto is_namespace_member(info entity) -> bool; consteval bool is_nsdm(info r); +consteval bool is_static_member(info r); consteval bool is_base(info r); consteval bool is_constructor(info r); consteval bool is_destructor(info r); consteval bool is_special_member(info r); ``` -[#]{.pnum} *Returns*: `true` if `r` designates a class member, namespace member, non-static data member, base class member, constructor, destructor, or special member, respectively. Otherwise, `false`. +[#]{.pnum} *Returns*: `true` if `r` designates a class member, namespace member, non-static data member, static member, base class member, constructor, destructor, or special member, respectively. Otherwise, `false`. ```cpp consteval info type_of(info r); @@ -2211,7 +2169,7 @@ consteval vector template_arguments_of(info r); ``` [#]{.pnum} *Mandates*: `has_template_arguments(r)` is `true`. -[#]{.pnum} *Returns*: A reflection of the template, and the reflections of the template arguments, repectively. +[#]{.pnum} *Returns*: A reflection of the template of `r`, and the reflections of the template arguments of, the specialization designated by `r`, repectively. [#]{.pnum} [*Example*: ```