Entity proxies.
This commit is contained in:
@@ -59,19 +59,14 @@ consteval auto template_of(info r) -> info;
|
||||
consteval auto template_arguments_of(info r) -> vector<info>;
|
||||
|
||||
// member queries
|
||||
consteval auto members_of(info class_type) -> vector<info>;
|
||||
consteval auto bases_of(info class_type) -> vector<info>;
|
||||
consteval auto static_data_members_of(info class_type) -> vector<info>;
|
||||
consteval auto nonstatic_data_members_of(info class_type) -> vector<info>;
|
||||
consteval auto subobjects_of(info class_type) -> vector<info>;
|
||||
consteval auto members_of(info class_type, access_context ctx) -> vector<info>;
|
||||
consteval auto bases_of(info class_type, access_context ctx) -> vector<info>;
|
||||
consteval auto static_data_members_of(info class_type,
|
||||
access_context ctx) -> vector<info>;
|
||||
consteval auto nonstatic_data_members_of(info class_type,
|
||||
access_context ctx) -> vector<info>;
|
||||
consteval auto enumerators_of(info enum_type) -> vector<info>;
|
||||
|
||||
// public member queries (removal proposed by P3547)
|
||||
consteval auto get_public_members(info) -> vector<info>;
|
||||
consteval auto get_public_bases(info) -> vector<info>;
|
||||
consteval auto get_static_data_members(info) -> vector<info>;
|
||||
consteval auto get_nonstatic_data_members(info) -> vector<info>;
|
||||
|
||||
// substitute
|
||||
template <reflection_range R = initializer_list<info>>
|
||||
consteval auto can_substitute(info templ, R &&args) -> bool;
|
||||
@@ -340,6 +335,9 @@ consteval auto tuple_element(size_t, info) -> info;
|
||||
consteval auto variant_size(info) -> size_t;
|
||||
consteval auto variant_alternative(size_t, info) -> info;
|
||||
|
||||
// entity proxies (PXYZ)
|
||||
consteval auto is_entity_proxy(info) -> bool;
|
||||
|
||||
// function parameters (P3096)
|
||||
consteval auto parameters_of(info) -> vector<info>;
|
||||
consteval auto has_consistent_identifier(info) -> bool;
|
||||
@@ -486,6 +484,7 @@ enum : unsigned {
|
||||
__metafn_is_variable,
|
||||
__metafn_is_type,
|
||||
__metafn_is_alias,
|
||||
__metafn_is_entity_proxy,
|
||||
__metafn_is_complete_type,
|
||||
__metafn_has_complete_definition,
|
||||
__metafn_is_enumerable_type,
|
||||
@@ -948,7 +947,10 @@ consteval auto is_complete_type(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_complete_type, r);
|
||||
}
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
// Returns whether the reflected class data member is an enumerator.
|
||||
consteval auto is_enumerator(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_enumerator, r);
|
||||
}
|
||||
|
||||
class access_context {
|
||||
consteval access_context(info scope, info naming_class) noexcept
|
||||
@@ -988,20 +990,16 @@ public:
|
||||
};
|
||||
|
||||
consteval auto is_accessible(info r, access_context ctx) -> bool {
|
||||
if (!is_class_member(r) && !is_base(r))
|
||||
// Note: The accessibility of an enumerator may be looked up in a class
|
||||
// for which it's not a member, since that enumerator could be
|
||||
if (!is_class_member(r) && !is_base(r) && !is_enumerator(r))
|
||||
return true;
|
||||
|
||||
return __metafunction(detail::__metafn_is_accessible,
|
||||
r, ctx.scope(), ctx.naming_class());
|
||||
}
|
||||
|
||||
#endif // __has_feature(access_contexts)
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
consteval auto members_of(info r, access_context ctx) -> vector<info> {
|
||||
#else
|
||||
consteval auto members_of(info r) -> vector<info> {
|
||||
#endif // __has_feature(access_contexts)
|
||||
using iterator =
|
||||
__range_of_infos::iterator<__range_of_infos::front_member_of_fn,
|
||||
__range_of_infos::next_member_of_fn,
|
||||
@@ -1010,14 +1008,10 @@ consteval auto members_of(info r) -> vector<info> {
|
||||
auto rng = range{r};
|
||||
|
||||
vector<info> v {rng.begin(), rng.end()};
|
||||
#if __has_feature(access_contexts)
|
||||
return vector<info>{
|
||||
from_range,
|
||||
v | views::filter([=](info r) { return is_accessible(r, ctx); })
|
||||
};
|
||||
#else
|
||||
return v;
|
||||
#endif // __has_feature(access_contexts)
|
||||
}
|
||||
|
||||
// Returns whether the reflected entity is a namespace.
|
||||
@@ -1025,11 +1019,7 @@ consteval auto is_namespace(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_namespace, r);
|
||||
}
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
consteval auto bases_of(info r, access_context ctx) -> vector<info> {
|
||||
#else
|
||||
consteval auto bases_of(info r) -> vector<info> {
|
||||
#endif // __has_feature(access_contexts)
|
||||
if (is_namespace(r))
|
||||
throw "Namespaces cannot have base classes";
|
||||
|
||||
@@ -1041,14 +1031,10 @@ consteval auto bases_of(info r) -> vector<info> {
|
||||
auto rng = range{r};
|
||||
|
||||
vector<info> v {rng.begin(), rng.end()};
|
||||
#if __has_feature(access_contexts)
|
||||
return vector<info>{
|
||||
from_range,
|
||||
v | views::filter([=](info r) { return is_accessible(r, ctx); })
|
||||
};
|
||||
#else
|
||||
return v;
|
||||
#endif // __has_feature(access_contexts)
|
||||
}
|
||||
|
||||
// Returns whether the reflected entity is a variable.
|
||||
@@ -1056,38 +1042,22 @@ consteval auto is_variable(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_variable, r);
|
||||
}
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
consteval auto static_data_members_of(info r,
|
||||
access_context ctx) -> vector<info> {
|
||||
#else
|
||||
consteval auto static_data_members_of(info r) -> vector<info> {
|
||||
#endif // has_feature(access_contexts
|
||||
if (is_namespace(r))
|
||||
throw "Namespaces cannot have static data members";
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
return members_of(r, ctx) |
|
||||
#else
|
||||
return members_of(r) |
|
||||
#endif // __has_feature(access_contexts)
|
||||
views::filter(is_variable) |
|
||||
ranges::to<vector>();
|
||||
}
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
consteval auto nonstatic_data_members_of(info r,
|
||||
access_context ctx) -> vector<info> {
|
||||
#else
|
||||
consteval auto nonstatic_data_members_of(info r) -> vector<info> {
|
||||
#endif // __has_feature(access_contexts)
|
||||
if (is_namespace(r))
|
||||
throw "Namespaces cannot have non-static data members";
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
return members_of(r, ctx) |
|
||||
#else
|
||||
return members_of(r) |
|
||||
#endif // __has_feature(access_contexts)
|
||||
views::filter(is_nonstatic_data_member) |
|
||||
ranges::to<vector>();
|
||||
}
|
||||
@@ -1115,26 +1085,6 @@ consteval auto is_public(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_public, r);
|
||||
}
|
||||
|
||||
#if !__has_feature(access_contexts)
|
||||
consteval auto get_public_members(info r) -> vector<info> {
|
||||
return members_of(r) | views::filter(is_public) | ranges::to<vector>();
|
||||
}
|
||||
|
||||
consteval auto get_public_bases(info r) -> vector<info> {
|
||||
return bases_of(r) | views::filter(is_public) | ranges::to<vector>();
|
||||
}
|
||||
|
||||
consteval auto get_public_static_data_members(info r) -> vector<info> {
|
||||
return static_data_members_of(r) | views::filter(is_public) |
|
||||
ranges::to<vector>();
|
||||
}
|
||||
|
||||
consteval auto get_public_nonstatic_data_members(info r) -> vector<info> {
|
||||
return nonstatic_data_members_of(r) | views::filter(is_public) |
|
||||
ranges::to<vector>();
|
||||
}
|
||||
#endif // !__has_feature(access_contexts)
|
||||
|
||||
// Returns whether the reflected entity is a protected class member.
|
||||
consteval auto is_protected(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_protected, r);
|
||||
@@ -1188,11 +1138,6 @@ consteval auto is_bit_field(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_bit_field, r);
|
||||
}
|
||||
|
||||
// Returns whether the reflected class data member is an enumerator.
|
||||
consteval auto is_enumerator(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_enumerator, r);
|
||||
}
|
||||
|
||||
// Returns whether the reflected type is const-qualified, or if the reflected
|
||||
// entity is of such a type.
|
||||
consteval auto is_const(info r) -> bool {
|
||||
@@ -1275,16 +1220,23 @@ consteval auto is_type(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_type, r);
|
||||
}
|
||||
|
||||
// Returns true if the reflected entity is an alias.
|
||||
// Returns true if the reflected entity is a type alias.
|
||||
consteval auto is_type_alias(info r) -> bool {
|
||||
return is_type(r) && __metafunction(detail::__metafn_is_alias, r);
|
||||
}
|
||||
|
||||
// Returns true if the reflected entity is an alias.
|
||||
// Returns true if the reflected entity is a namespace alias.
|
||||
consteval auto is_namespace_alias(info r) -> bool {
|
||||
return is_namespace(r) && __metafunction(detail::__metafn_is_alias, r);
|
||||
}
|
||||
|
||||
#if __has_feature(entity_proxy_reflection)
|
||||
// Returns true if the reflected entity is an entity proxy.
|
||||
consteval auto is_entity_proxy(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_entity_proxy, r);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Returns true if the reflected entity is a template.
|
||||
consteval auto is_template(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_is_template, r);
|
||||
@@ -2089,11 +2041,7 @@ namespace detail {
|
||||
template <class T> struct __wrap_workaround { using type = T; };
|
||||
consteval auto __workaround_expand_compiler_builtins(info type) -> info {
|
||||
auto r = substitute(^^__wrap_workaround, {type});
|
||||
#if __has_feature(access_contexts)
|
||||
return dealias(members_of(r, access_context::unchecked())[0]);
|
||||
#else
|
||||
return dealias(members_of(r)[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@@ -2193,8 +2141,6 @@ consteval auto annotate(info entity, info val) -> info {
|
||||
|
||||
#endif // __has_feature(annotation_attributes)
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
|
||||
consteval auto has_inaccessible_nonstatic_data_members(
|
||||
info r,
|
||||
access_context ctx) -> bool {
|
||||
@@ -2208,8 +2154,6 @@ consteval auto has_inaccessible_bases(info r, access_context ctx) -> bool {
|
||||
[=](info b) { return is_accessible(b, ctx); });
|
||||
}
|
||||
|
||||
#endif // __has_feature(access_contexts)
|
||||
|
||||
// ===================================================
|
||||
// Other bespoke functions (not proposed at this time)
|
||||
// ===================================================
|
||||
@@ -2310,7 +2254,6 @@ consteval auto define_class(info class_type, R &&members) -> info {
|
||||
return define_aggregate(class_type, members);
|
||||
}
|
||||
|
||||
#if __has_feature(access_contexts)
|
||||
[[deprecated("P3547 requires an 'access_context' argument "
|
||||
"(compile with '-fno-access-contexts' to disable this warning)")]]
|
||||
consteval auto members_of(info r) -> vector<info> {
|
||||
@@ -2340,8 +2283,6 @@ consteval auto has_complete_definition(info r) -> bool {
|
||||
return __metafunction(detail::__metafn_has_complete_definition, r);
|
||||
}
|
||||
|
||||
#endif // __has_feature(access_contexts)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_REFLECTION_V2
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
@@ -2692,12 +2633,8 @@ consteval auto pretty_printer<CharT>::tprint_impl::render() -> string_t {
|
||||
string_t result = render<type_of(R)>() + string_constant("{");
|
||||
|
||||
size_t Idx = 0;
|
||||
#if __has_feature(access_contexts)
|
||||
[:expand(nonstatic_data_members_of(type_of(R),
|
||||
access_context::unchecked())):] >>
|
||||
#else
|
||||
[:expand(nonstatic_data_members_of(type_of(R))):] >>
|
||||
#endif
|
||||
[&]<auto Mem> {
|
||||
if (Idx++ > 0) result += string_constant(", ");
|
||||
result += tprint_impl::render<reflect_value([:R:].[:Mem:])>();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <print>
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// =========================
|
||||
// completion_with_no_fields
|
||||
@@ -43,9 +44,9 @@ consteval {
|
||||
static_assert(is_complete_type(^^S));
|
||||
static_assert(is_complete_type(^^C));
|
||||
static_assert(is_complete_type(^^U));
|
||||
static_assert(nonstatic_data_members_of(^^S).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^C).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^U).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^S, ctx).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^C, ctx).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^U, ctx).size() == 0);
|
||||
|
||||
S s;
|
||||
C c;
|
||||
@@ -69,17 +70,18 @@ consteval {
|
||||
}
|
||||
static_assert(is_complete_type(^^S));
|
||||
// unnamed bitfields are not nonstatic data members.
|
||||
static_assert(nonstatic_data_members_of(^^S).size() == 3);
|
||||
static_assert(nonstatic_data_members_of(^^S, ctx).size() == 3);
|
||||
static_assert(alignment_of(^^S::count) == 16);
|
||||
static_assert(bit_size_of(nonstatic_data_members_of(^^S)[2]) == 5);
|
||||
static_assert((members_of(^^S) | std::views::filter(std::meta::is_bit_field) |
|
||||
static_assert(bit_size_of(nonstatic_data_members_of(^^S, ctx)[2]) == 5);
|
||||
static_assert((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_bit_field) |
|
||||
std::views::transform(std::meta::bit_size_of) |
|
||||
std::ranges::to<std::vector>()) == std::vector<size_t> {0, 5});
|
||||
|
||||
constexpr S s = {14, true, 11};
|
||||
static_assert(s.count == 14);
|
||||
static_assert(s.flag);
|
||||
static_assert(s.[:nonstatic_data_members_of(^^S)[2]:] == 11);
|
||||
static_assert(s.[:nonstatic_data_members_of(^^S, ctx)[2]:] == 11);
|
||||
|
||||
struct Empty {};
|
||||
struct WithEmpty;
|
||||
@@ -105,9 +107,9 @@ consteval {
|
||||
});
|
||||
}
|
||||
static_assert(is_complete_type(^^C));
|
||||
static_assert(nonstatic_data_members_of(^^C).size() == 2);
|
||||
static_assert(nonstatic_data_members_of(^^C, ctx).size() == 2);
|
||||
static_assert(
|
||||
(members_of(^^C) |
|
||||
(members_of(^^C, ctx) |
|
||||
std::views::filter(std::meta::is_nonstatic_data_member) |
|
||||
std::views::filter(std::meta::is_public) |
|
||||
std::ranges::to<std::vector>()).size() == 2);
|
||||
@@ -130,9 +132,9 @@ consteval {
|
||||
}
|
||||
static_assert(is_complete_type(^^U));
|
||||
static_assert(size_of(^^U) == size_of(^^U::count));
|
||||
static_assert(nonstatic_data_members_of(^^U).size() == 2);
|
||||
static_assert(nonstatic_data_members_of(^^U, ctx).size() == 2);
|
||||
static_assert(
|
||||
(members_of(^^U) |
|
||||
(members_of(^^U, ctx) |
|
||||
std::views::filter(std::meta::is_nonstatic_data_member) |
|
||||
std::ranges::to<std::vector>()).size() == 2);
|
||||
|
||||
@@ -164,11 +166,11 @@ consteval {
|
||||
});
|
||||
}
|
||||
|
||||
static_assert(nonstatic_data_members_of(^^S<0>).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^S<1>).size() == 1);
|
||||
static_assert(nonstatic_data_members_of(^^S<0>, ctx).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^S<1>, ctx).size() == 1);
|
||||
static_assert(type_of(^^S<1>::mem) == ^^int);
|
||||
static_assert(nonstatic_data_members_of(^^S<2>).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^S<3>).size() == 1);
|
||||
static_assert(nonstatic_data_members_of(^^S<2>, ctx).size() == 0);
|
||||
static_assert(nonstatic_data_members_of(^^S<3>, ctx).size() == 1);
|
||||
static_assert(type_of(^^S<3>::mem) == ^^bool);
|
||||
static_assert(!is_complete_type(^^S<4>));
|
||||
} // namespace template_specialization_completion
|
||||
@@ -190,7 +192,7 @@ consteval {
|
||||
data_member_spec(^^int, {.name="count"})>();
|
||||
}
|
||||
static_assert(is_complete_type(^^S));
|
||||
static_assert(nonstatic_data_members_of(^^S).size() == 2);
|
||||
static_assert(nonstatic_data_members_of(^^S, ctx).size() == 2);
|
||||
|
||||
S s;
|
||||
} // namespace completion_of_dependent_type
|
||||
@@ -261,7 +263,7 @@ consteval {
|
||||
|
||||
static_assert(type_of(^^foo::i) == ^^int);
|
||||
static_assert(type_of(^^foo::b) == ^^bool);
|
||||
static_assert(nonstatic_data_members_of(^^foo).size() == 2);
|
||||
static_assert(nonstatic_data_members_of(^^foo, ctx).size() == 2);
|
||||
} // namespace with_non_contiguous_range
|
||||
|
||||
// =============================
|
||||
@@ -277,9 +279,10 @@ consteval {
|
||||
data_member_spec(^^int, {.name=u8identifier_of(^^Kühl)})
|
||||
});
|
||||
}
|
||||
static_assert(u8identifier_of(nonstatic_data_members_of(^^Cls1)[0]) ==
|
||||
static_assert(u8identifier_of(nonstatic_data_members_of(^^Cls1, ctx)[0]) ==
|
||||
u8"Kühl");
|
||||
static_assert(identifier_of(nonstatic_data_members_of(^^Cls1)[0]) == "Kühl");
|
||||
static_assert(identifier_of(nonstatic_data_members_of(^^Cls1, ctx)[0]) ==
|
||||
"Kühl");
|
||||
} // namespace utf8_identifier_of_roundtrip
|
||||
|
||||
// ===========================
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
|
||||
#include <print>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// ===========
|
||||
// well_formed
|
||||
// ===========
|
||||
@@ -185,7 +188,8 @@ struct S1 {
|
||||
namespace speculative_and_trial_evaluations {
|
||||
struct S1;
|
||||
consteval auto fn() {
|
||||
return members_of(define_aggregate(^^S1, {})).empty() ? new int : nullptr;
|
||||
return members_of(define_aggregate(^^S1, {}), ctx).empty() ? new int :
|
||||
nullptr;
|
||||
};
|
||||
|
||||
consteval void fn2() {
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
#include <experimental/meta>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
|
||||
struct type {};
|
||||
using alias = type;
|
||||
|
||||
@@ -558,8 +561,8 @@ static_assert(is_complete_type(^^IncompleteTClsAlias<int>));
|
||||
struct Base {};
|
||||
struct Derived : Base {};
|
||||
static_assert(!is_base(^^Base));
|
||||
static_assert(!is_type(bases_of(^^Derived)[0]));
|
||||
static_assert(is_base(bases_of(^^Derived)[0]));
|
||||
static_assert(!is_type(bases_of(^^Derived, ctx)[0]));
|
||||
static_assert(is_base(bases_of(^^Derived, ctx)[0]));
|
||||
|
||||
// =================================================
|
||||
// test_is_structured_binding_and_related_edge_cases
|
||||
@@ -630,29 +633,29 @@ struct S3 { S3(); };
|
||||
S3::S3() {}
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S1) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
(members_of(^^S1, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
static_assert(
|
||||
(members_of(^^S1) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
(members_of(^^S1, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
static_assert(
|
||||
(members_of(^^S2) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
(members_of(^^S2, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 0);
|
||||
static_assert(
|
||||
(members_of(^^S2) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 2);
|
||||
(members_of(^^S2, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 2);
|
||||
static_assert(
|
||||
(members_of(^^S3) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
(members_of(^^S3, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
static_assert(
|
||||
(members_of(^^S3) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
(members_of(^^S3, ctx) | std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_declared) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
} // namespace test_is_user_provided_and_declared
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Copyright 2024 Bloomberg Finance L.P.
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
// ADDITIONAL_COMPILE_FLAGS: -fentity-proxy-reflection
|
||||
// ADDITIONAL_COMPILE_FLAGS: -fannotation-attributes
|
||||
|
||||
// <experimental/reflection>
|
||||
//
|
||||
// [reflection]
|
||||
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
constexpr auto unchecked = std::meta::access_context::unchecked();
|
||||
|
||||
struct Base {};
|
||||
enum Enum { Red };
|
||||
|
||||
struct A {
|
||||
int m;
|
||||
struct Inner : Base { int m; };
|
||||
using Alias = std::vector<int>;
|
||||
};
|
||||
struct B : private A { using A::m; using A::Inner; using A::Alias; };
|
||||
|
||||
struct C { template <typename> struct TCls {}; struct Inner {}; int m; };
|
||||
struct D : C { using C::TCls; using C::Inner; private: using C::m; };
|
||||
|
||||
struct E { using Enum::Red; };
|
||||
namespace InnerNS { using Enum::Red; }
|
||||
|
||||
struct F { int m; int n; };
|
||||
struct G : F { [[=32]] using F::m; public: using F::n; };
|
||||
struct H : G { using G::n; };
|
||||
|
||||
static_assert(is_accessible(^^A::Inner, ctx));
|
||||
static_assert(!is_accessible(^^A::Inner, ctx.via(^^B)));
|
||||
static_assert(is_accessible(^^B::Inner, ctx));
|
||||
|
||||
static_assert(is_entity_proxy(^^B::Inner));
|
||||
static_assert(!is_entity_proxy(^^A::Inner));
|
||||
|
||||
static_assert(nonstatic_data_members_of(dealias(^^B::Inner), ctx).size() == 1);
|
||||
static_assert(bases_of(dealias(^^B::Inner), ctx).size() == 1);
|
||||
|
||||
static_assert(template_arguments_of(dealias(^^B::Alias)) ==
|
||||
std::vector {^^int, ^^std::allocator<int>});
|
||||
static_assert(identifier_of(^^B::Alias) == "Alias");
|
||||
static_assert(source_location_of(^^B::Alias).line() == 34);
|
||||
|
||||
static_assert(type_of(dealias(^^B::m)) == ^^int);
|
||||
static_assert(parent_of(^^B::m) == ^^B);
|
||||
static_assert(dealias(^^B::Alias) == ^^std::vector<int>);
|
||||
static_assert(template_of(dealias(^^B::Alias)) == ^^std::vector);
|
||||
static_assert(has_template_arguments(dealias(^^B::Alias)));
|
||||
static_assert(!has_template_arguments(^^B::Alias));
|
||||
|
||||
static_assert(substitute(dealias(^^D::TCls), {^^D::Inner}) ==
|
||||
^^C::TCls<C::Inner>);
|
||||
|
||||
static_assert(identifier_of(members_of(^^D, unchecked)[2]) == "m");
|
||||
static_assert(is_private(members_of(^^D, unchecked)[2]));
|
||||
|
||||
static_assert(!is_class_member(^^Enum::Red));
|
||||
static_assert(is_class_member(^^E::Red));
|
||||
static_assert(is_entity_proxy(^^E::Red));
|
||||
static_assert(dealias(^^E::Red) == ^^Enum::Red);
|
||||
|
||||
static_assert(!is_namespace_member(^^Enum::Red));
|
||||
static_assert(is_namespace_member(^^InnerNS::Red));
|
||||
|
||||
static_assert(extract<int>(annotations_of(^^G::m)[0]) == 32);
|
||||
static_assert(!is_access_specified(^^G::m));
|
||||
static_assert(is_access_specified(^^G::n));
|
||||
|
||||
static_assert(dealias(^^H::n) == ^^F::n);
|
||||
|
||||
int main() { }
|
||||
@@ -63,8 +63,9 @@ export struct Base {
|
||||
static constexpr int K = 12;
|
||||
};
|
||||
export struct Child : private Empty, Base {};
|
||||
export constexpr auto rBase1 = bases_of(^^Child)[0];
|
||||
export constexpr auto rBase2 = bases_of(^^Child)[1];
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
export constexpr auto rBase1 = bases_of(^^Child, ctx)[0];
|
||||
export constexpr auto rBase2 = bases_of(^^Child, ctx)[1];
|
||||
|
||||
// =================================
|
||||
// Reflections of data members specs
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
|
||||
// <experimental/reflection>
|
||||
//
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// ==========================
|
||||
// class_or_namespace_members
|
||||
// ==========================
|
||||
@@ -214,8 +216,8 @@ struct B1 {};
|
||||
struct B2 {};
|
||||
struct D : B1, virtual B2 { };
|
||||
|
||||
static_assert(!is_virtual(bases_of(^^D)[0]));
|
||||
static_assert(is_virtual(bases_of(^^D)[1]));
|
||||
static_assert(!is_virtual(bases_of(^^D, ctx)[0]));
|
||||
static_assert(is_virtual(bases_of(^^D, ctx)[1]));
|
||||
|
||||
static_assert(!is_virtual(^^B1));
|
||||
static_assert(!is_virtual(^^B2));
|
||||
@@ -241,12 +243,14 @@ struct S {
|
||||
template <typename T> void TMemFn();
|
||||
struct Inner {};
|
||||
};
|
||||
static_assert((members_of(^^S) | std::views::filter(std::meta::is_constructor) |
|
||||
std::ranges::to<std::vector>()).size() == 4);
|
||||
static_assert((members_of(^^S) | std::views::filter(std::meta::is_destructor) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
static_assert((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::ranges::to<std::vector>()).size() == 4);
|
||||
static_assert((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_destructor) |
|
||||
std::ranges::to<std::vector>()).size() == 1);
|
||||
static_assert(
|
||||
(members_of(^^S) |
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_special_member_function) |
|
||||
std::ranges::to<std::vector>()).size() == 6);
|
||||
|
||||
@@ -350,32 +354,32 @@ static_assert(!is_explicit(^^S::mem));
|
||||
static_assert(!is_explicit(^^S::memfn));
|
||||
static_assert(!is_explicit(^^S::TMemFn));
|
||||
static_assert(
|
||||
!is_explicit((members_of(^^S) |
|
||||
!is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::ranges::to<std::vector>())[0]));
|
||||
static_assert(
|
||||
!is_explicit((members_of(^^S) |
|
||||
!is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor_template) |
|
||||
std::ranges::to<std::vector>())[0]));
|
||||
static_assert(
|
||||
is_explicit((members_of(^^S) |
|
||||
is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::ranges::to<std::vector>())[1]));
|
||||
|
||||
static_assert(!is_explicit(^^S::operator int));
|
||||
static_assert(
|
||||
!is_explicit((members_of(^^S) |
|
||||
!is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_template) |
|
||||
std::ranges::to<std::vector>())[3]));
|
||||
static_assert(is_explicit(^^S::operator bool));
|
||||
|
||||
// P2996R3 removes support for checking 'explicit' on templates.
|
||||
static_assert(
|
||||
!is_explicit((members_of(^^S) |
|
||||
!is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::ranges::to<std::vector>())[3]));
|
||||
static_assert(
|
||||
!is_explicit((members_of(^^S) |
|
||||
!is_explicit((members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_template) |
|
||||
std::ranges::to<std::vector>())[4]));
|
||||
|
||||
@@ -768,27 +772,30 @@ struct S {
|
||||
};
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_default_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_default_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {true, true,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false});
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_copy_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_copy_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {false, false,
|
||||
true, true, true, true, true,
|
||||
false, false, false, false, false,
|
||||
false});
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_move_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_move_constructor) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {false, false,
|
||||
false, false, false, false, false,
|
||||
true, true, true, true, true,
|
||||
@@ -818,27 +825,29 @@ struct S {
|
||||
};
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {true, true, true, true,
|
||||
true, true, true, true,
|
||||
true,
|
||||
false});
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_copy_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_copy_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {true, true, true, true,
|
||||
false, false, false, false,
|
||||
false,
|
||||
false});
|
||||
|
||||
static_assert(
|
||||
(members_of(^^S) | std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_move_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::is_move_assignment) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector {false, false, false, false,
|
||||
true, true, true, true,
|
||||
false,
|
||||
@@ -858,7 +867,7 @@ struct S {
|
||||
};
|
||||
|
||||
static_assert(
|
||||
(nonstatic_data_members_of(^^S) |
|
||||
(nonstatic_data_members_of(^^S, ctx) |
|
||||
std::views::transform(std::meta::has_default_member_initializer) |
|
||||
std::ranges::to<std::vector>()) == std::vector {false, true, true});
|
||||
|
||||
@@ -957,7 +966,7 @@ int operator""_b();
|
||||
|
||||
|
||||
constexpr auto conversion_template =
|
||||
(members_of(^^T) | std::views::filter(std::meta::is_template)).front();
|
||||
(members_of(^^T, ctx) | std::views::filter(std::meta::is_template)).front();
|
||||
|
||||
static_assert(is_operator_function(^^S::operator+));
|
||||
static_assert(is_operator_function(^^operator&&));
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
// ADDITIONAL_COMPILE_FLAGS: -faccess-contexts
|
||||
|
||||
// <experimental/reflection>
|
||||
//
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
|
||||
// <experimental/reflection>
|
||||
//
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -fblocks
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
// ADDITIONAL_COMPILE_FLAGS: -fexpansion-statements
|
||||
// ADDITIONAL_COMPILE_FLAGS: -Wno-inconsistent-missing-override
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
static_assert(u8display_string_of(^^::) == u8"(global-namespace)");
|
||||
static_assert(display_string_of(^^::) == "(global-namespace)");
|
||||
static_assert(!has_identifier(^^::));
|
||||
@@ -148,7 +150,7 @@ struct Cls : Base {
|
||||
enum class EnumCls { B };
|
||||
};
|
||||
static_assert(identifier_of(^^Cls) == "Cls");
|
||||
static_assert(!has_identifier(bases_of(^^Cls)[0]));
|
||||
static_assert(!has_identifier(bases_of(^^Cls, ctx)[0]));
|
||||
static_assert(identifier_of(^^Cls::Alias) == "Alias");
|
||||
static_assert(has_identifier(^^Cls::Alias));
|
||||
static_assert(identifier_of(^^Cls::mem) == "mem");
|
||||
@@ -157,18 +159,18 @@ static_assert(identifier_of(^^Cls::sfn) == "sfn");
|
||||
static_assert(identifier_of(^^Cls::Inner) == "Inner");
|
||||
|
||||
static_assert(
|
||||
!has_identifier((members_of(^^Cls) |
|
||||
!has_identifier((members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor)).front()));
|
||||
static_assert(
|
||||
!has_identifier((members_of(^^Cls) |
|
||||
!has_identifier((members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor_template)).front()));
|
||||
static_assert(
|
||||
!has_identifier((members_of(^^Cls) |
|
||||
!has_identifier((members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_destructor)).front()));
|
||||
static_assert(!has_identifier(^^Cls::operator bool));
|
||||
static_assert(
|
||||
!has_identifier(
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_template) |
|
||||
std::ranges::to<std::vector>())[5]));
|
||||
static_assert(identifier_of(^^Cls::TInner) == "TInner");
|
||||
@@ -180,34 +182,34 @@ static_assert(identifier_of(^^Cls::Enum::B) == "B");
|
||||
static_assert(identifier_of(^^Cls::EnumCls) == "EnumCls");
|
||||
static_assert(identifier_of(^^Cls::EnumCls::B) == "B");
|
||||
static_assert(display_string_of(^^Cls) == "Cls");
|
||||
static_assert(display_string_of(bases_of(^^Cls)[0]) == "Base");
|
||||
static_assert(display_string_of(bases_of(^^Cls, ctx)[0]) == "Base");
|
||||
static_assert(display_string_of(^^Cls::Alias) == "Alias");
|
||||
static_assert(display_string_of(^^Cls::mem) == "mem");
|
||||
static_assert(display_string_of(^^Cls::memfn) == "memfn");
|
||||
static_assert(display_string_of(^^Cls::sfn) == "sfn");
|
||||
static_assert(display_string_of(^^Cls::Inner) == "Inner");
|
||||
static_assert(
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided) |
|
||||
std::views::transform(std::meta::display_string_of) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector<std::string_view>{"Cls"});
|
||||
static_assert(
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor_template) |
|
||||
std::views::transform(std::meta::display_string_of) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector<std::string_view>{"Cls"});
|
||||
static_assert(
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_destructor) |
|
||||
std::views::transform(std::meta::display_string_of) |
|
||||
std::ranges::to<std::vector>()) ==
|
||||
std::vector<std::string_view>{"~Cls"});
|
||||
static_assert(display_string_of(^^Cls::operator bool) == "operator bool");
|
||||
static_assert(
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_template) |
|
||||
std::views::transform(std::meta::display_string_of) |
|
||||
std::ranges::to<std::vector>())[5] ==
|
||||
|
||||
@@ -37,8 +37,9 @@ consteval {
|
||||
make_named_tuple(^^R, {{^^int, "x"}, {^^double, "y"}});
|
||||
}
|
||||
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R)[0]) == ^^int);
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R)[1]) == ^^double);
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R, ctx)[0]) == ^^int);
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R, ctx)[1]) == ^^double);
|
||||
|
||||
int main() {
|
||||
[[maybe_unused]] auto r = R{.x=1, .y=2.0};
|
||||
|
||||
@@ -58,10 +58,10 @@ consteval std::meta::info enrich(std::meta::info r) {
|
||||
// the first constructor. The copy/move constructors are added at the }, so
|
||||
// will be the last ones in the list.
|
||||
std::array ctors = {
|
||||
(members_of(^^Choices) |
|
||||
(members_of(^^Choices, std::meta::access_context::current()) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided)).front()...,
|
||||
(members_of(^^unmatched) |
|
||||
(members_of(^^unmatched, std::meta::access_context::current()) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided)).front()
|
||||
};
|
||||
|
||||
@@ -32,8 +32,9 @@ struct member_descriptor
|
||||
// returns std::array<member_descriptor, N>
|
||||
template <typename S>
|
||||
consteval auto get_layout() {
|
||||
auto members = nonstatic_data_members_of(^^S);
|
||||
constexpr size_t sz = nonstatic_data_members_of(^^S).size();
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
auto members = nonstatic_data_members_of(^^S, ctx);
|
||||
constexpr size_t sz = nonstatic_data_members_of(^^S, ctx).size();
|
||||
std::array<member_descriptor, sz> layout;
|
||||
for (int i = 0; i < members.size(); ++i) {
|
||||
layout[i] = {
|
||||
|
||||
@@ -61,8 +61,9 @@ consteval {
|
||||
make_named_tuple(^^R, pair<int, "x">{}, pair<double, "y">{});
|
||||
}
|
||||
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R)[0]) == ^^int);
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R)[1]) == ^^double);
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R, ctx)[0]) == ^^int);
|
||||
static_assert(type_of(nonstatic_data_members_of(^^R, ctx)[1]) == ^^double);
|
||||
|
||||
int main() {
|
||||
[[maybe_unused]] auto r = R{.x=1, .y=2.0};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection
|
||||
// ADDITIONAL_COMPILE_FLAGS: -fexpansion-statements
|
||||
// ADDITIONAL_COMPILE_FLAGS: -Wno-inconsistent-missing-override
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -fexpansion-statements
|
||||
// ADDITIONAL_COMPILE_FLAGS: -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -Wno-inconsistent-missing-override
|
||||
|
||||
// <experimental/reflection>
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
struct S { unsigned i:2, j:6; };
|
||||
|
||||
consteval auto member_number(int n) {
|
||||
return std::meta::nonstatic_data_members_of(^^S)[n];
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
return std::meta::nonstatic_data_members_of(^^S, ctx)[n];
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
struct S { unsigned i:2, j:6; };
|
||||
|
||||
consteval auto member_named(std::string_view name) {
|
||||
for (std::meta::info field : nonstatic_data_members_of(^^S)) {
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
for (std::meta::info field : nonstatic_data_members_of(^^S, ctx)) {
|
||||
if (identifier_of(field) == name) return field;
|
||||
}
|
||||
std::unreachable();
|
||||
|
||||
@@ -38,7 +38,8 @@ template<typename... Ts> struct Tuple {
|
||||
};
|
||||
|
||||
consteval std::meta::info get_nth_field(std::meta::info r, std::size_t n) {
|
||||
return nonstatic_data_members_of(r)[n];
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
return nonstatic_data_members_of(r, ctx)[n];
|
||||
}
|
||||
|
||||
template<std::size_t I, typename... Ts>
|
||||
|
||||
@@ -29,7 +29,9 @@ struct struct_of_arrays_impl {
|
||||
struct impl;
|
||||
|
||||
consteval {
|
||||
std::vector<std::meta::info> old_members = nonstatic_data_members_of(^^T);
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
std::vector<std::meta::info> old_members = nonstatic_data_members_of(^^T,
|
||||
ctx);
|
||||
std::vector<std::meta::info> new_members = {};
|
||||
for (std::meta::info member : old_members) {
|
||||
auto array_type = substitute(^^std::array, {
|
||||
|
||||
@@ -32,8 +32,9 @@ consteval auto struct_to_tuple_type(std::meta::info type) -> std::meta::info {
|
||||
return substitute(^^std::remove_cvref_t, {r});
|
||||
};
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
return substitute(^^std::tuple,
|
||||
nonstatic_data_members_of(type)
|
||||
nonstatic_data_members_of(type, ctx)
|
||||
| std::views::transform(std::meta::type_of)
|
||||
| std::views::transform(remove_cvref)
|
||||
| std::ranges::to<std::vector>());
|
||||
@@ -49,7 +50,8 @@ consteval auto get_struct_to_tuple_helper() {
|
||||
using To = [: struct_to_tuple_type(^^From) :];
|
||||
|
||||
std::vector args = {^^To, ^^From};
|
||||
for (auto mem : nonstatic_data_members_of(^^From)) {
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
for (auto mem : nonstatic_data_members_of(^^From, ctx)) {
|
||||
args.push_back(reflect_value(mem));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
|
||||
// ADDITIONAL_COMPILE_FLAGS: -freflection -fexpansion-statements
|
||||
// ADDITIONAL_COMPILE_FLAGS: -faccess-contexts
|
||||
// ADDITIONAL_COMPILE_FLAGS: -Wno-inconsistent-missing-override
|
||||
|
||||
// <experimental/reflection>
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// =================
|
||||
// with_no_arguments
|
||||
// =================
|
||||
@@ -84,7 +86,8 @@ struct Cls {
|
||||
};
|
||||
|
||||
constexpr auto ctor =
|
||||
(members_of(^^Cls) | std::views::filter(std::meta::is_constructor)).front();
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor)).front();
|
||||
static_assert(parameters_of(ctor).size() == 1);
|
||||
static_assert(type_of(parameters_of(ctor)[0]) == ^^int);
|
||||
static_assert(identifier_of(parameters_of(ctor)[0]) == "a");
|
||||
@@ -94,7 +97,8 @@ static_assert(!is_explicit_object_parameter(parameters_of(ctor)[0]));
|
||||
static_assert(!has_ellipsis_parameter(ctor));
|
||||
|
||||
constexpr auto dtor =
|
||||
(members_of(^^Cls) | std::views::filter(std::meta::is_destructor)).front();
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_destructor)).front();
|
||||
static_assert(parameters_of(dtor).size() == 0);
|
||||
static_assert(!has_ellipsis_parameter(dtor));
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <array>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// ===============
|
||||
// basic_functions
|
||||
// ===============
|
||||
@@ -175,12 +177,12 @@ struct Cls {
|
||||
};
|
||||
|
||||
constexpr auto ctor =
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor) |
|
||||
std::views::filter(std::meta::is_user_provided)).front();
|
||||
|
||||
constexpr auto ctor_template =
|
||||
(members_of(^^Cls) |
|
||||
(members_of(^^Cls, ctx) |
|
||||
std::views::filter(std::meta::is_constructor_template)).front();
|
||||
|
||||
// Non-template constructor.
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
|
||||
// ============
|
||||
// find_type_of
|
||||
// ============
|
||||
@@ -104,7 +106,7 @@ static_assert(parent_of(^^Cls::mem) == ^^Cls);
|
||||
static_assert(parent_of(^^Cls::memfn) == ^^Cls);
|
||||
static_assert(parent_of(^^Cls::sfn) == ^^Cls);
|
||||
static_assert(parent_of(^^Cls::Alias) == ^^Cls);
|
||||
static_assert(parent_of(bases_of(^^Cls)[0]) == ^^Cls);
|
||||
static_assert(parent_of(bases_of(^^Cls, ctx)[0]) == ^^Cls);
|
||||
|
||||
static_assert(parent_of(^^Cls::TSMem) == ^^Cls);
|
||||
static_assert(parent_of(^^Cls::TSMem<int>) == ^^Cls);
|
||||
|
||||
@@ -39,8 +39,9 @@ void foo(int param) {
|
||||
static_assert(source_location_of(^^S).function_name() == FnName);
|
||||
|
||||
struct C : S {};
|
||||
static_assert(source_location_of(bases_of(^^C)[0]).line() ==
|
||||
std::source_location::current().line() - 2);
|
||||
constexpr auto ctx = std::meta::access_context::current();
|
||||
static_assert(source_location_of(bases_of(^^C, ctx)[0]).line() ==
|
||||
std::source_location::current().line() - 3);
|
||||
|
||||
// Check that it works with aliases.
|
||||
using intAlias = int;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
// =============
|
||||
// static_arrays
|
||||
// =============
|
||||
@@ -42,7 +44,8 @@ static_assert(objs.size() == 3);
|
||||
static_assert(objs[0].k == 5 && objs[1].k == 7 && objs[2].k == 9);
|
||||
|
||||
constexpr auto infos = std::define_static_array(
|
||||
nonstatic_data_members_of(^^Cls));
|
||||
nonstatic_data_members_of(^^Cls,
|
||||
ctx));
|
||||
static_assert(infos.size() == 1);
|
||||
static_assert(infos[0] == ^^Cls::k);
|
||||
} // namespace static_arrays
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
template <int K>
|
||||
constexpr std::meta::info RVal = std::meta::reflect_value(K);
|
||||
|
||||
@@ -369,7 +372,8 @@ namespace with_reflection_of_declaration {
|
||||
template <int V> constexpr int Plus1 = V + 1;
|
||||
struct S { static constexpr int val = 4; };
|
||||
|
||||
static_assert([:substitute(^^Plus1, {static_data_members_of(^^S)[0]}):] == 5);
|
||||
static_assert([:substitute(^^Plus1,
|
||||
{static_data_members_of(^^S, ctx)[0]}):] == 5);
|
||||
} // namespace with_reflection_of_declaration
|
||||
|
||||
// ==========================
|
||||
@@ -455,7 +459,7 @@ namespace non_type_ref_regression_test {
|
||||
class Cls { static constexpr int priv = 11; };
|
||||
template <auto &V> static constexpr auto &Value = V;
|
||||
|
||||
static_assert([:substitute(^^Value, {members_of(^^Cls)[0]}):] == 11);
|
||||
static_assert([:substitute(^^Value, {members_of(^^Cls, ctx)[0]}):] == 11);
|
||||
} // namespace non_type_ref_regression_test
|
||||
|
||||
int main() { }
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <experimental/meta>
|
||||
|
||||
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
|
||||
template <typename P1, auto P2, template <typename...> class P3>
|
||||
struct TCls {
|
||||
template <typename> struct TInnerCls {};
|
||||
@@ -327,9 +329,9 @@ template <auto R> void fn() { }
|
||||
|
||||
void fn() {
|
||||
class S { S(); ~S(); };
|
||||
fn<(members_of(^^S) |
|
||||
fn<(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_constructor)).front()>();
|
||||
fn<(members_of(^^S) |
|
||||
fn<(members_of(^^S, ctx) |
|
||||
std::views::filter(std::meta::is_destructor)).front()>();
|
||||
}
|
||||
} // namespace bb_clang_p2996_issue_54_regression_test
|
||||
|
||||
@@ -144,7 +144,8 @@ static_assert(CheckValueIs<42>([]() {
|
||||
static_assert(
|
||||
CheckValueIs<3>(
|
||||
static_data_members_of(substitute(^^TCls,
|
||||
{std::meta::reflect_value(3)}))[0]));
|
||||
{std::meta::reflect_value(3)}),
|
||||
std::meta::access_context::unchecked())[0]));
|
||||
} // namespace extract_results
|
||||
|
||||
// =========
|
||||
|
||||
Reference in New Issue
Block a user