Updates to 'access_context' and 'define_static_*'.
Accessors for the former; put the latter in 'std::*'.
This commit is contained in:
@@ -361,6 +361,11 @@ consteval auto annotate(info) -> info;
|
||||
|
||||
// modeling access control (P3547)
|
||||
struct access_context {
|
||||
access_context() = delete;
|
||||
|
||||
consteval auto scope() const -> info;
|
||||
consteval auto naming_class() const -> info;
|
||||
|
||||
static consteval auto current() noexcept -> access_context;
|
||||
static consteval auto unprivileged() noexcept -> access_context;
|
||||
static consteval auto unchecked() noexcept -> access_context;
|
||||
@@ -942,22 +947,26 @@ consteval auto is_class_type(info r) -> bool {
|
||||
|
||||
class access_context {
|
||||
consteval access_context(info scope, info naming_class) noexcept
|
||||
: scope{scope}, naming_class{naming_class} { }
|
||||
: d_scope{scope}, d_naming_class{naming_class} { }
|
||||
|
||||
public:
|
||||
const info scope;
|
||||
const info naming_class;
|
||||
const info d_scope;
|
||||
const info d_naming_class;
|
||||
|
||||
consteval access_context() = delete;
|
||||
|
||||
consteval access_context() noexcept : scope{^^::}, naming_class{} { };
|
||||
consteval access_context(const access_context &) noexcept = default;
|
||||
consteval access_context(access_context &&) noexcept = default;
|
||||
|
||||
consteval info scope() const { return d_scope; }
|
||||
consteval info naming_class() const { return d_naming_class; }
|
||||
|
||||
static consteval access_context current() noexcept {
|
||||
return {__metafunction(detail::__metafn_access_context), {}};
|
||||
}
|
||||
|
||||
static consteval access_context unprivileged() noexcept {
|
||||
return access_context{};
|
||||
return access_context{^^::, info{}};
|
||||
}
|
||||
|
||||
static consteval access_context unchecked() noexcept {
|
||||
@@ -968,7 +977,7 @@ public:
|
||||
if (!is_class_type(new_naming_class))
|
||||
throw "naming class must be a reflection of a class type";
|
||||
|
||||
return access_context{scope, new_naming_class};
|
||||
return access_context{d_scope, new_naming_class};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -977,7 +986,7 @@ consteval auto is_accessible(info r, access_context ctx) -> bool {
|
||||
return true;
|
||||
|
||||
return __metafunction(detail::__metafn_is_accessible,
|
||||
r, ctx.scope, ctx.naming_class);
|
||||
r, ctx.scope(), ctx.naming_class());
|
||||
}
|
||||
|
||||
#endif // __has_feature(access_contexts)
|
||||
@@ -1572,55 +1581,6 @@ consteval auto bit_size_of(info r) -> size_t {
|
||||
return __metafunction(detail::__metafn_bit_size_of, r);
|
||||
}
|
||||
|
||||
namespace __define_static {
|
||||
|
||||
template <typename ValTy, ValTy... Vals>
|
||||
inline constexpr ValTy FixedArray[sizeof...(Vals)] = {Vals...};
|
||||
|
||||
template <auto &S>
|
||||
inline constexpr span StaticSpan(S, size(S));
|
||||
|
||||
template <typename ValTy>
|
||||
consteval span<const ValTy> impl(const span<const ValTy> &in) {
|
||||
if (in.size() == 0)
|
||||
return {};
|
||||
|
||||
vector Args = {^^ValTy};
|
||||
for (const auto &V : in)
|
||||
Args.push_back(reflect_value(V));
|
||||
|
||||
return extract<span<const ValTy>>(
|
||||
substitute(^^StaticSpan, { substitute(^^FixedArray, Args) }));
|
||||
}
|
||||
} // namespace __define_static
|
||||
|
||||
template <ranges::input_range R>
|
||||
requires (is_constructible_v<ranges::range_value_t<R>,
|
||||
ranges::range_reference_t<R>>)
|
||||
consteval auto define_static_array(R &&elems)
|
||||
-> span<const ranges::range_value_t<R>> {
|
||||
using ValTy = ranges::range_value_t<R>;
|
||||
using ImplTy = span<const ValTy>(*)(const span<const ValTy> &);
|
||||
auto impl = extract<ImplTy>(substitute(^^__define_static::impl, {^^ValTy}));
|
||||
|
||||
vector<ValTy> vals(from_range, elems);
|
||||
return impl(vals);
|
||||
}
|
||||
|
||||
// Returns a static string having the provided contents.
|
||||
consteval auto define_static_string(string_view in) -> const char * {
|
||||
const char nullterm[1] = {0};
|
||||
vector<span<const char>> v = {in, nullterm};
|
||||
return define_static_array(views::join(v)).data();
|
||||
}
|
||||
|
||||
consteval auto define_static_string(u8string_view in) -> const char8_t * {
|
||||
const char8_t nullterm[1] = {0};
|
||||
vector<span<const char8_t>> v = {in, nullterm};
|
||||
return define_static_array(views::join(v)).data();
|
||||
}
|
||||
|
||||
|
||||
// Type trait wrappers
|
||||
|
||||
consteval auto is_void_type(info r) -> bool {
|
||||
@@ -2383,6 +2343,62 @@ consteval auto has_complete_definition(info r) -> bool {
|
||||
|
||||
#endif // __has_feature(access_contexts)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_REFLECTION_V2
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace __define_static {
|
||||
|
||||
template <typename ValTy, ValTy... Vals>
|
||||
inline constexpr ValTy FixedArray[sizeof...(Vals)] = {Vals...};
|
||||
|
||||
template <auto &S>
|
||||
inline constexpr span StaticSpan(S, size(S));
|
||||
|
||||
template <typename ValTy>
|
||||
consteval span<const ValTy> impl(const span<const ValTy> &in) {
|
||||
if (in.size() == 0)
|
||||
return {};
|
||||
|
||||
vector Args = {^^ValTy};
|
||||
for (const auto &V : in)
|
||||
Args.push_back(meta::reflect_value(V));
|
||||
|
||||
return meta::extract<span<const ValTy>>(
|
||||
meta::substitute(^^StaticSpan, { meta::substitute(^^FixedArray, Args) }));
|
||||
}
|
||||
} // namespace __define_static
|
||||
|
||||
template <ranges::input_range R>
|
||||
requires (is_constructible_v<ranges::range_value_t<R>,
|
||||
ranges::range_reference_t<R>>)
|
||||
consteval auto define_static_array(R &&elems)
|
||||
-> span<const ranges::range_value_t<R>> {
|
||||
using ValTy = ranges::range_value_t<R>;
|
||||
using ImplTy = span<const ValTy>(*)(const span<const ValTy> &);
|
||||
auto impl = meta::extract<ImplTy>(meta::substitute(^^__define_static::impl,
|
||||
{^^ValTy}));
|
||||
|
||||
vector<ValTy> vals(from_range, elems);
|
||||
return impl(vals);
|
||||
}
|
||||
|
||||
// Returns a static string having the provided contents.
|
||||
consteval auto define_static_string(string_view in) -> const char * {
|
||||
const char nullterm[1] = {0};
|
||||
vector<span<const char>> v = {in, nullterm};
|
||||
return define_static_array(views::join(v)).data();
|
||||
}
|
||||
|
||||
consteval auto define_static_string(u8string_view in) -> const char8_t * {
|
||||
const char8_t nullterm[1] = {0};
|
||||
vector<span<const char8_t>> v = {in, nullterm};
|
||||
return define_static_array(views::join(v)).data();
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_REFLECTION_V2
|
||||
|
||||
// ====================================
|
||||
// (u8)display_string_of implementation
|
||||
|
||||
@@ -50,20 +50,29 @@ struct BitField {
|
||||
};
|
||||
static_assert(offset_of(^^BitField::bf1) == std::meta::member_offset{0, 0});
|
||||
static_assert(offset_of(^^BitField::bf2) == std::meta::member_offset{0, 1});
|
||||
static_assert(offset_of(nonstatic_data_members_of(^^BitField, {})[2]) ==
|
||||
std::meta::member_offset{1, 0});
|
||||
static_assert(
|
||||
offset_of(
|
||||
nonstatic_data_members_of(^^BitField,
|
||||
std::meta::access_context::current())[2]) ==
|
||||
std::meta::member_offset{1, 0});
|
||||
static_assert(offset_of(^^BitField::bf3) == std::meta::member_offset{1, 0});
|
||||
static_assert(offset_of(^^BitField::bf4) == std::meta::member_offset{1, 3});
|
||||
static_assert(bit_size_of(^^BitField::bf1) == 1);
|
||||
static_assert(bit_size_of(^^BitField::bf2) == 2);
|
||||
static_assert(bit_size_of((members_of(^^BitField, {}) |
|
||||
std::views::filter(std::meta::is_bit_field) |
|
||||
std::ranges::to<std::vector>())[2]) == 0);
|
||||
static_assert(
|
||||
bit_size_of(
|
||||
(members_of(^^BitField, std::meta::access_context::current()) |
|
||||
std::views::filter(std::meta::is_bit_field) |
|
||||
std::ranges::to<std::vector>())[2]) ==
|
||||
0);
|
||||
static_assert(bit_size_of(^^BitField::bf3) == 3);
|
||||
static_assert(bit_size_of(^^BitField::bf4) == 3);
|
||||
|
||||
// unnamed bitfield not included.
|
||||
static_assert(nonstatic_data_members_of(^^BitField, {}).size() == 4);
|
||||
static_assert(
|
||||
nonstatic_data_members_of(
|
||||
^^BitField,
|
||||
std::meta::access_context::current()).size() == 4);
|
||||
static_assert(size_of(^^BitField) == 4);
|
||||
|
||||
alignas(64) int i1;
|
||||
@@ -125,12 +134,18 @@ struct A { char a; };
|
||||
struct B { bool b; };
|
||||
struct C : A, B {};
|
||||
|
||||
static_assert(offset_of(bases_of(^^C, {})[0]) == std::meta::member_offset{0, 0});
|
||||
static_assert(offset_of(bases_of(^^C, {})[1]) == std::meta::member_offset{1, 0});
|
||||
static_assert(
|
||||
offset_of(bases_of(^^C, std::meta::access_context::current())[0]) ==
|
||||
std::meta::member_offset{0, 0});
|
||||
static_assert(
|
||||
offset_of(bases_of(^^C, std::meta::access_context::current())[1]) ==
|
||||
std::meta::member_offset{1, 0});
|
||||
|
||||
struct V { };
|
||||
struct D : V { virtual void fn() = 0; };
|
||||
static_assert(offset_of(bases_of(^^D, {})[0]) == std::meta::member_offset{0, 0});
|
||||
static_assert(
|
||||
offset_of(bases_of(^^D, std::meta::access_context::current())[0]) ==
|
||||
std::meta::member_offset{0, 0});
|
||||
|
||||
} // namespace base_offsets
|
||||
|
||||
|
||||
@@ -248,16 +248,14 @@ consteval access_context FriendFnOfAccess() {
|
||||
// =====================
|
||||
|
||||
|
||||
static_assert(access_context{}.scope == ^^::);
|
||||
static_assert(access_context::current().scope == ^^::);
|
||||
static_assert(access_context::current().scope() == ^^::);
|
||||
namespace new_accessibility_api {
|
||||
static_assert(access_context::current().scope == ^^::new_accessibility_api);
|
||||
static_assert(access_context::current().scope() == ^^::new_accessibility_api);
|
||||
|
||||
void fn() {
|
||||
static_assert(access_context{}.scope == ^^::);
|
||||
static_assert(access_context::current().scope == ^^fn);
|
||||
static_assert(access_context::current().scope() == ^^fn);
|
||||
[] {
|
||||
constexpr auto repr = access_context::current().scope;
|
||||
constexpr auto repr = access_context::current().scope();
|
||||
static_assert(is_function(repr));
|
||||
static_assert(repr != ^^fn);
|
||||
}();
|
||||
|
||||
@@ -76,7 +76,7 @@ struct Clap {
|
||||
};
|
||||
|
||||
template for (constexpr auto Pair :
|
||||
std::meta::define_static_array([]() consteval {
|
||||
std::define_static_array([]() consteval {
|
||||
auto ctx = std::meta::access_context::current();
|
||||
|
||||
auto spec_members = nonstatic_data_members_of(^^Spec, ctx);
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
// =============
|
||||
|
||||
namespace static_arrays {
|
||||
constexpr auto empty = std::meta::define_static_array(std::vector<int>{});
|
||||
constexpr auto empty = std::define_static_array(std::vector<int>{});
|
||||
static_assert(empty.size() == 0);
|
||||
|
||||
constexpr auto ints = std::meta::define_static_array(std::vector{1, 3, 5});
|
||||
constexpr auto ints = std::define_static_array(std::vector{1, 3, 5});
|
||||
static_assert(ints.size() == 3);
|
||||
static_assert(ints[0] == 1 && ints[1] == 3 && ints[2] == 5);
|
||||
|
||||
@@ -37,11 +37,11 @@ struct Cls {
|
||||
consteval Cls(int v) : k(v) {}
|
||||
consteval Cls(const Cls &rhs) : k(rhs.k + 1) {}
|
||||
};
|
||||
constexpr auto objs = std::meta::define_static_array(std::vector<Cls>{1, 3, 5});
|
||||
constexpr auto objs = std::define_static_array(std::vector<Cls>{1, 3, 5});
|
||||
static_assert(objs.size() == 3);
|
||||
static_assert(objs[0].k == 5 && objs[1].k == 7 && objs[2].k == 9);
|
||||
|
||||
constexpr auto infos = std::meta::define_static_array(
|
||||
constexpr auto infos = std::define_static_array(
|
||||
nonstatic_data_members_of(^^Cls));
|
||||
static_assert(infos.size() == 1);
|
||||
static_assert(infos[0] == ^^Cls::k);
|
||||
@@ -54,7 +54,7 @@ static_assert(infos[0] == ^^Cls::k);
|
||||
namespace static_strings {
|
||||
// Ensure 'define_static_string("literal")' can be used as a template argument.
|
||||
template <auto S> consteval auto fn() { return S[0]; }
|
||||
static_assert(fn<std::meta::define_static_string("literal")>() == 'l');
|
||||
static_assert(fn<std::define_static_string("literal")>() == 'l');
|
||||
|
||||
} // namespace static_strings
|
||||
|
||||
|
||||
Reference in New Issue
Block a user