Improve <meta> compile time (#164)
* 1. Remove variant usage * 2. Remove <algorithm> * 3. Remove most of <ranges>
This commit is contained in:
@@ -395,12 +395,16 @@ template <reflection_range R1 = initializer_list<info>,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <__config>
|
#include <__config>
|
||||||
#include <algorithm>
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ranges>
|
|
||||||
|
#include <__ranges/access.h>
|
||||||
|
#include <__ranges/concepts.h>
|
||||||
|
#include <__ranges/size.h>
|
||||||
|
|
||||||
#include <source_location>
|
#include <source_location>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -597,7 +601,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pre-incr ++itr;
|
// pre-incr ++itr;
|
||||||
consteval iterator operator++() {
|
consteval iterator& operator++() {
|
||||||
m_currInfoItr = m_next(m_currInfoItr, m_reflectedEntity, m_nextIndex++);
|
m_currInfoItr = m_next(m_currInfoItr, m_reflectedEntity, m_nextIndex++);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -639,6 +643,11 @@ public:
|
|||||||
{
|
{
|
||||||
return m_last;
|
return m_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consteval vector<info> to_vec() const
|
||||||
|
{
|
||||||
|
return vector<info>(m_first, m_last);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Front, typename Next, typename Map>
|
template <typename Front, typename Next, typename Map>
|
||||||
@@ -927,7 +936,7 @@ consteval auto can_substitute(info templ, R &&args) -> bool {
|
|||||||
sub = __metafunction(detail::__metafn_substitute, templ,
|
sub = __metafunction(detail::__metafn_substitute, templ,
|
||||||
ranges::data(args), ranges::size(args), false);
|
ranges::data(args), ranges::size(args), false);
|
||||||
} else {
|
} else {
|
||||||
vector vargs = args | ranges::to<vector>();
|
vector vargs(from_range, args);
|
||||||
sub = __metafunction(detail::__metafn_substitute, templ,
|
sub = __metafunction(detail::__metafn_substitute, templ,
|
||||||
vargs.data(), vargs.size(), false);
|
vargs.data(), vargs.size(), false);
|
||||||
}
|
}
|
||||||
@@ -942,7 +951,7 @@ consteval auto substitute(info templ, R &&args) -> info {
|
|||||||
return __metafunction(detail::__metafn_substitute, templ,
|
return __metafunction(detail::__metafn_substitute, templ,
|
||||||
ranges::data(args), ranges::size(args), true);
|
ranges::data(args), ranges::size(args), true);
|
||||||
} else {
|
} else {
|
||||||
vector vargs = args | ranges::to<vector>();
|
vector vargs(from_range, args);
|
||||||
return __metafunction(detail::__metafn_substitute, templ, vargs.data(),
|
return __metafunction(detail::__metafn_substitute, templ, vargs.data(),
|
||||||
vargs.size(), true);
|
vargs.size(), true);
|
||||||
}
|
}
|
||||||
@@ -1016,19 +1025,20 @@ consteval auto is_accessible(info r, access_context ctx) -> bool {
|
|||||||
r, ctx.scope(), ctx.designating_class());
|
r, ctx.scope(), ctx.designating_class());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class P>
|
||||||
|
consteval auto __filtered(vector<info> v, P pred) -> vector<info> {
|
||||||
|
erase_if(v, [=](info i) { return !pred(i); });
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
consteval auto members_of(info r, access_context ctx) -> vector<info> {
|
consteval auto members_of(info r, access_context ctx) -> vector<info> {
|
||||||
using iterator =
|
using iterator =
|
||||||
__range_of_infos::iterator<__range_of_infos::front_member_of_fn,
|
__range_of_infos::iterator<__range_of_infos::front_member_of_fn,
|
||||||
__range_of_infos::next_member_of_fn,
|
__range_of_infos::next_member_of_fn,
|
||||||
__range_of_infos::map_decl_to_entity_fn>;
|
__range_of_infos::map_decl_to_entity_fn>;
|
||||||
using range = __range_of_infos::range<iterator>;
|
using range = __range_of_infos::range<iterator>;
|
||||||
auto rng = range{r};
|
|
||||||
|
|
||||||
vector<info> v {rng.begin(), rng.end()};
|
return __filtered(range(r).to_vec(), [=](info r) { return is_accessible(r, ctx); });
|
||||||
return vector<info>{
|
|
||||||
from_range,
|
|
||||||
v | views::filter([=](info r) { return is_accessible(r, ctx); })
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the reflected entity is a namespace.
|
// Returns whether the reflected entity is a namespace.
|
||||||
@@ -1045,13 +1055,8 @@ consteval auto bases_of(info r, access_context ctx) -> vector<info> {
|
|||||||
__range_of_infos::next_base_of_fn,
|
__range_of_infos::next_base_of_fn,
|
||||||
__range_of_infos::map_identity_fn>;
|
__range_of_infos::map_identity_fn>;
|
||||||
using range = __range_of_infos::range<iterator>;
|
using range = __range_of_infos::range<iterator>;
|
||||||
auto rng = range{r};
|
|
||||||
|
|
||||||
vector<info> v {rng.begin(), rng.end()};
|
return __filtered(range(r).to_vec(), [=](info r) { return is_accessible(r, ctx); });
|
||||||
return vector<info>{
|
|
||||||
from_range,
|
|
||||||
v | views::filter([=](info r) { return is_accessible(r, ctx); })
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether the reflected entity is a variable.
|
// Returns whether the reflected entity is a variable.
|
||||||
@@ -1064,9 +1069,7 @@ consteval auto static_data_members_of(info r,
|
|||||||
if (is_namespace(r))
|
if (is_namespace(r))
|
||||||
throw "Namespaces cannot have static data members";
|
throw "Namespaces cannot have static data members";
|
||||||
|
|
||||||
return members_of(r, ctx) |
|
return __filtered(members_of(r, ctx), is_variable);
|
||||||
views::filter(is_variable) |
|
|
||||||
ranges::to<vector>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consteval auto nonstatic_data_members_of(info r,
|
consteval auto nonstatic_data_members_of(info r,
|
||||||
@@ -1074,9 +1077,7 @@ consteval auto nonstatic_data_members_of(info r,
|
|||||||
if (is_namespace(r))
|
if (is_namespace(r))
|
||||||
throw "Namespaces cannot have non-static data members";
|
throw "Namespaces cannot have non-static data members";
|
||||||
|
|
||||||
return members_of(r, ctx) |
|
return __filtered(members_of(r, ctx), is_nonstatic_data_member);
|
||||||
views::filter(is_nonstatic_data_member) |
|
|
||||||
ranges::to<vector>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the reflected entity is an enumerable type.
|
// Returns true if the reflected entity is an enumerable type.
|
||||||
@@ -1419,106 +1420,6 @@ consteval auto reflect_function(T &r) -> info {
|
|||||||
return __metafunction(detail::__metafn_reflect_result, type_of(^^r), r);
|
return __metafunction(detail::__metafn_reflect_result, type_of(^^r), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Representation of a data member which may be passed to 'data_member_spec'.
|
|
||||||
struct data_member_options {
|
|
||||||
struct name_type {
|
|
||||||
variant<u8string, string> impl;
|
|
||||||
|
|
||||||
template <typename T> requires constructible_from<u8string, T>
|
|
||||||
consteval name_type(T &&in) : impl(in_place_type<u8string>, in) {}
|
|
||||||
|
|
||||||
template <typename T> requires constructible_from<string, T>
|
|
||||||
consteval name_type(T &&in) : impl(in_place_type<string>, in) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
|
||||||
info unused = ^^::;
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
};
|
|
||||||
|
|
||||||
optional<name_type> name = nullopt;
|
|
||||||
optional<int> alignment = nullopt;
|
|
||||||
optional<int> width = nullopt;
|
|
||||||
bool no_unique_address = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the alignment of the reflected entity.
|
|
||||||
consteval auto alignment_of(info r) -> size_t {
|
|
||||||
return __metafunction(detail::__metafn_alignment_of, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a reflection representing a description of a data member, which may
|
|
||||||
// be used with 'define_aggregate' to define a record type.
|
|
||||||
consteval auto data_member_spec(info member_type,
|
|
||||||
data_member_options options = {}) -> info {
|
|
||||||
if (!is_type(member_type))
|
|
||||||
throw "'member_type' must represent a type";
|
|
||||||
|
|
||||||
auto name = options.name.value_or(u8"").impl;
|
|
||||||
int alignment = options.alignment.value_or(0);
|
|
||||||
int width = options.width.value_or(0);
|
|
||||||
bool no_unique_address = options.no_unique_address;
|
|
||||||
|
|
||||||
auto validate = [&](auto name_string) {
|
|
||||||
if (width) {
|
|
||||||
if (alignment)
|
|
||||||
throw "Cannot specify both width and alignment for data member";
|
|
||||||
if (no_unique_address)
|
|
||||||
throw "Cannot specify both width and no_unique_address for data member";
|
|
||||||
if (width < 0)
|
|
||||||
throw "Cannot specify a negative width for data member";
|
|
||||||
if (!extract<bool>(substitute(^^is_integral_v, {member_type})) &&
|
|
||||||
!extract<bool>(substitute(^^is_enum_v, {member_type})))
|
|
||||||
throw "Bit field must have integral or enumeral type";
|
|
||||||
} else {
|
|
||||||
if (options.width.has_value() && !name_string.empty())
|
|
||||||
throw "Bit-fields of zero width must be unnamed";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alignment) {
|
|
||||||
if (alignment < int(alignment_of(member_type)))
|
|
||||||
throw "Cannot specify an alignment less than that of the member type";
|
|
||||||
if (alignment <= 0 || ((alignment - 1) & alignment))
|
|
||||||
throw "Alignment specifier must be a non-negative power of 2";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (holds_alternative<u8string>(name)) {
|
|
||||||
const u8string &s = get<u8string>(name);
|
|
||||||
validate(s);
|
|
||||||
return __metafunction(detail::__metafn_data_member_spec,
|
|
||||||
member_type,
|
|
||||||
!s.empty(), s.size(), ^^const char8_t, s.data(),
|
|
||||||
options.alignment.has_value(), alignment,
|
|
||||||
options.width.has_value(), width,
|
|
||||||
no_unique_address);
|
|
||||||
} else {
|
|
||||||
const string &s = get<string>(name);
|
|
||||||
validate(s);
|
|
||||||
return __metafunction(detail::__metafn_data_member_spec,
|
|
||||||
member_type,
|
|
||||||
!s.empty(), s.size(), ^^const char, s.data(),
|
|
||||||
options.alignment.has_value(), alignment,
|
|
||||||
options.width.has_value(), width,
|
|
||||||
no_unique_address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Completes the definition of the record type reflected by 'class_type' with
|
|
||||||
// the members described by the reflections in the provided range.
|
|
||||||
template <reflection_range R = initializer_list<info>>
|
|
||||||
consteval auto define_aggregate(info class_type, R &&members) -> info {
|
|
||||||
if constexpr (ranges::contiguous_range<R>) {
|
|
||||||
return __metafunction(detail::__metafn_define_aggregate, class_type,
|
|
||||||
ranges::size(members), ranges::data(members));
|
|
||||||
} else {
|
|
||||||
vector vmembers = members | ranges::to<vector>();
|
|
||||||
return __metafunction(detail::__metafn_define_aggregate, class_type,
|
|
||||||
vmembers.size(), vmembers.data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct member_offset {
|
struct member_offset {
|
||||||
ptrdiff_t bytes;
|
ptrdiff_t bytes;
|
||||||
ptrdiff_t bits;
|
ptrdiff_t bits;
|
||||||
@@ -2122,9 +2023,9 @@ consteval auto annotations_of(info r, info ty) -> vector<info> {
|
|||||||
if (!is_type(ty))
|
if (!is_type(ty))
|
||||||
throw "Expected a reflection of a type";
|
throw "Expected a reflection of a type";
|
||||||
|
|
||||||
return annotations_of(r) | views::filter([=](info annot) {
|
return __filtered(annotations_of(r), [=](info annot) {
|
||||||
return type_of(annot) == ty;
|
return remove_const(type_of(annot)) == remove_const(ty);
|
||||||
}) | ranges::to<vector>();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -2153,17 +2054,23 @@ consteval auto annotate(info entity, info val) -> info {
|
|||||||
|
|
||||||
#endif // __has_feature(annotation_attributes)
|
#endif // __has_feature(annotation_attributes)
|
||||||
|
|
||||||
|
consteval auto __any_inaccessible(vector<info> const& r, access_context ctx) -> bool {
|
||||||
|
for (info i : r) {
|
||||||
|
if (!is_accessible(i, ctx)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
consteval auto has_inaccessible_nonstatic_data_members(
|
consteval auto has_inaccessible_nonstatic_data_members(
|
||||||
info r,
|
info r,
|
||||||
access_context ctx) -> bool {
|
access_context ctx) -> bool {
|
||||||
return !ranges::all_of(
|
return __any_inaccessible(nonstatic_data_members_of(r, access_context::unchecked()), ctx);
|
||||||
nonstatic_data_members_of(r, access_context::unchecked()),
|
|
||||||
[=](info m) { return is_accessible(m, ctx); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consteval auto has_inaccessible_bases(info r, access_context ctx) -> bool {
|
consteval auto has_inaccessible_bases(info r, access_context ctx) -> bool {
|
||||||
return !ranges::all_of(bases_of(r, access_context::unchecked()),
|
return __any_inaccessible(bases_of(r, access_context::unchecked()), ctx);
|
||||||
[=](info b) { return is_accessible(b, ctx); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
@@ -2184,7 +2091,7 @@ consteval auto reflect_invoke(info target, R &&args) -> info {
|
|||||||
static_cast<info *>(nullptr), 0,
|
static_cast<info *>(nullptr), 0,
|
||||||
ranges::data(args), ranges::size(args));
|
ranges::data(args), ranges::size(args));
|
||||||
} else {
|
} else {
|
||||||
vector vargs = args | ranges::to<vector>();
|
vector vargs(from_range, args);
|
||||||
return __metafunction(detail::__metafn_reflect_invoke, target,
|
return __metafunction(detail::__metafn_reflect_invoke, target,
|
||||||
static_cast<info *>(nullptr), 0,
|
static_cast<info *>(nullptr), 0,
|
||||||
vargs.data(), vargs.size());
|
vargs.data(), vargs.size());
|
||||||
@@ -2200,19 +2107,19 @@ consteval auto reflect_invoke(info target, R1 &&targs, R2 &&args) -> info {
|
|||||||
ranges::data(targs), ranges::size(targs),
|
ranges::data(targs), ranges::size(targs),
|
||||||
ranges::data(args), ranges::size(args));
|
ranges::data(args), ranges::size(args));
|
||||||
} else {
|
} else {
|
||||||
vector vargs = args | ranges::to<vector>();
|
vector vargs(from_range, args);
|
||||||
return __metafunction(detail::__metafn_reflect_invoke, target,
|
return __metafunction(detail::__metafn_reflect_invoke, target,
|
||||||
ranges::data(targs), ranges::size(targs),
|
ranges::data(targs), ranges::size(targs),
|
||||||
vargs.data(), vargs.size());
|
vargs.data(), vargs.size());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vector vtargs = targs | ranges::to<vector>();
|
vector vtargs(from_range, targs);
|
||||||
if constexpr (ranges::contiguous_range<R2>) {
|
if constexpr (ranges::contiguous_range<R2>) {
|
||||||
return __metafunction(detail::__metafn_reflect_invoke, target,
|
return __metafunction(detail::__metafn_reflect_invoke, target,
|
||||||
vtargs.data(), vtargs.size(),
|
vtargs.data(), vtargs.size(),
|
||||||
ranges::data(args), ranges::size(args));
|
ranges::data(args), ranges::size(args));
|
||||||
} else {
|
} else {
|
||||||
vector vargs = args | ranges::to<vector>();
|
vector vargs(from_range, args);
|
||||||
return __metafunction(detail::__metafn_reflect_invoke, target,
|
return __metafunction(detail::__metafn_reflect_invoke, target,
|
||||||
vtargs.data(), vtargs.size(),
|
vtargs.data(), vtargs.size(),
|
||||||
vargs.data(), vargs.size());
|
vargs.data(), vargs.size());
|
||||||
@@ -2220,6 +2127,113 @@ consteval auto reflect_invoke(info target, R1 &&targs, R2 &&args) -> info {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Representation of a data member which may be passed to 'data_member_spec'.
|
||||||
|
struct data_member_options {
|
||||||
|
struct name_type {
|
||||||
|
bool is_u8;
|
||||||
|
u8string u8;
|
||||||
|
string s;
|
||||||
|
|
||||||
|
template <typename T> requires constructible_from<u8string, T>
|
||||||
|
consteval name_type(T &&in) : is_u8(true), u8((T&&)in) {}
|
||||||
|
|
||||||
|
template <typename T> requires constructible_from<string, T>
|
||||||
|
consteval name_type(T &&in) : is_u8(false), s((T&&)in) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||||
|
info unused = ^^::;
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
};
|
||||||
|
|
||||||
|
optional<name_type> name = nullopt;
|
||||||
|
optional<int> alignment = nullopt;
|
||||||
|
optional<int> width = nullopt;
|
||||||
|
bool no_unique_address = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns the alignment of the reflected entity.
|
||||||
|
consteval auto alignment_of(info r) -> size_t {
|
||||||
|
return __metafunction(detail::__metafn_alignment_of, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a reflection representing a description of a data member, which may
|
||||||
|
// be used with 'define_aggregate' to define a record type.
|
||||||
|
consteval auto data_member_spec(info member_type,
|
||||||
|
data_member_options options = {}) -> info {
|
||||||
|
if (!is_type(member_type))
|
||||||
|
throw "'member_type' must represent a type";
|
||||||
|
|
||||||
|
bool has_name = options.name.has_value();
|
||||||
|
int alignment = options.alignment.value_or(0);
|
||||||
|
int width = options.width.value_or(0);
|
||||||
|
bool no_unique_address = options.no_unique_address;
|
||||||
|
|
||||||
|
if (width) {
|
||||||
|
if (alignment)
|
||||||
|
throw "Cannot specify both width and alignment for data member";
|
||||||
|
if (no_unique_address)
|
||||||
|
throw "Cannot specify both width and no_unique_address for data member";
|
||||||
|
if (width < 0)
|
||||||
|
throw "Cannot specify a negative width for data member";
|
||||||
|
if (!is_integral_type(member_type) && !is_enum_type(member_type))
|
||||||
|
throw "Bit field must have integral or enumeration type";
|
||||||
|
} else {
|
||||||
|
if (options.width.has_value() && has_name)
|
||||||
|
throw "Bit-fields of zero width must be unnamed";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alignment) {
|
||||||
|
if (alignment < int(alignment_of(member_type)))
|
||||||
|
throw "Cannot specify an alignment less than that of the member type";
|
||||||
|
if (alignment <= 0 || ((alignment - 1) & alignment))
|
||||||
|
throw "Alignment specifier must be a non-negative power of 2";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_name) {
|
||||||
|
if (options.name->is_u8) {
|
||||||
|
const u8string &s = options.name->u8;
|
||||||
|
return __metafunction(detail::__metafn_data_member_spec,
|
||||||
|
member_type,
|
||||||
|
!s.empty(), s.size(), ^^const char8_t, s.data(),
|
||||||
|
options.alignment.has_value(), alignment,
|
||||||
|
options.width.has_value(), width,
|
||||||
|
no_unique_address);
|
||||||
|
} else {
|
||||||
|
const string &s = options.name->s;
|
||||||
|
return __metafunction(detail::__metafn_data_member_spec,
|
||||||
|
member_type,
|
||||||
|
!s.empty(), s.size(), ^^const char, s.data(),
|
||||||
|
options.alignment.has_value(), alignment,
|
||||||
|
options.width.has_value(), width,
|
||||||
|
no_unique_address);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return __metafunction(detail::__metafn_data_member_spec,
|
||||||
|
member_type,
|
||||||
|
false, 0, ^^const char, "",
|
||||||
|
options.alignment.has_value(), alignment,
|
||||||
|
options.width.has_value(), width,
|
||||||
|
no_unique_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Completes the definition of the record type reflected by 'class_type' with
|
||||||
|
// the members described by the reflections in the provided range.
|
||||||
|
template <reflection_range R = initializer_list<info>>
|
||||||
|
consteval auto define_aggregate(info class_type, R &&members) -> info {
|
||||||
|
if constexpr (ranges::contiguous_range<R>) {
|
||||||
|
return __metafunction(detail::__metafn_define_aggregate, class_type,
|
||||||
|
ranges::size(members), ranges::data(members));
|
||||||
|
} else {
|
||||||
|
vector vmembers(from_range, members);
|
||||||
|
return __metafunction(detail::__metafn_define_aggregate, class_type,
|
||||||
|
vmembers.size(), vmembers.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// Deprecated names and APIs
|
// Deprecated names and APIs
|
||||||
// =========================
|
// =========================
|
||||||
@@ -2330,6 +2344,14 @@ consteval auto reflect_constant_string(std::string_view In) -> info {
|
|||||||
return substitute(^^__define_static::FixedArray, Args);
|
return substitute(^^__define_static::FixedArray, Args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consteval auto reflect_constant_string(std::u8string_view In) -> info {
|
||||||
|
vector Args = {^^char8_t};
|
||||||
|
for (char8_t C : In)
|
||||||
|
Args.push_back(reflect_constant(C));
|
||||||
|
Args.push_back(reflect_constant(char8_t{}));
|
||||||
|
return substitute(^^__define_static::FixedArray, Args);
|
||||||
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_REFLECTION_V2
|
_LIBCPP_END_NAMESPACE_REFLECTION_V2
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
@@ -2346,15 +2368,13 @@ consteval auto define_static_array(R &&elems)
|
|||||||
|
|
||||||
// Returns a static string having the provided contents.
|
// Returns a static string having the provided contents.
|
||||||
consteval auto define_static_string(string_view in) -> const char * {
|
consteval auto define_static_string(string_view in) -> const char * {
|
||||||
const char nullterm[1] = {0};
|
meta::info array = meta::reflect_constant_string(in);
|
||||||
vector<span<const char>> v = {in, nullterm};
|
return extract<const char*>(array);
|
||||||
return define_static_array(views::join(v)).data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consteval auto define_static_string(u8string_view in) -> const char8_t * {
|
consteval auto define_static_string(u8string_view in) -> const char8_t * {
|
||||||
const char8_t nullterm[1] = {0};
|
meta::info array = meta::reflect_constant_string(in);
|
||||||
vector<span<const char8_t>> v = {in, nullterm};
|
return extract<const char8_t*>(array);
|
||||||
return define_static_array(views::join(v)).data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <meta>
|
#include <meta>
|
||||||
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::current();
|
constexpr auto ctx = std::meta::access_context::current();
|
||||||
|
|
||||||
@@ -586,7 +586,7 @@ static_assert(is_structured_binding(^^z2));
|
|||||||
static_assert(!is_variable(^^x2));
|
static_assert(!is_variable(^^x2));
|
||||||
static_assert(!is_variable(^^y2));
|
static_assert(!is_variable(^^y2));
|
||||||
static_assert(!is_variable(^^z2));
|
static_assert(!is_variable(^^z2));
|
||||||
// "wrapped" type of each element is
|
// "wrapped" type of each element is
|
||||||
// std::tuple_element<I, std::tuple<int,int,int>>::type
|
// std::tuple_element<I, std::tuple<int,int,int>>::type
|
||||||
// where I is index of tuple field
|
// where I is index of tuple field
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::current();
|
constexpr auto ctx = std::meta::access_context::current();
|
||||||
constexpr auto unchecked = std::meta::access_context::unchecked();
|
constexpr auto unchecked = std::meta::access_context::unchecked();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
|
||||||
using int_alias = int;
|
using int_alias = int;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|
||||||
@@ -406,7 +406,7 @@ struct S {
|
|||||||
void noexcept_true_method() noexcept(true);
|
void noexcept_true_method() noexcept(true);
|
||||||
void noexcept_false_method() noexcept(false);
|
void noexcept_false_method() noexcept(false);
|
||||||
void not_noexcept_method();
|
void not_noexcept_method();
|
||||||
|
|
||||||
// virtual methods
|
// virtual methods
|
||||||
// w/o defining it complains about vtable
|
// w/o defining it complains about vtable
|
||||||
virtual void noexcept_virtual_method() noexcept {}
|
virtual void noexcept_virtual_method() noexcept {}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
using std::meta::access_context;
|
using std::meta::access_context;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <meta>
|
#include <meta>
|
||||||
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <ranges>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <print>
|
#include <print>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
// ==========
|
// ==========
|
||||||
// empty_case
|
// empty_case
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <meta>
|
#include <meta>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ struct Cls {
|
|||||||
template <typename T> consteval Cls(T) : value(sizeof(T)) {}
|
template <typename T> consteval Cls(T) : value(sizeof(T)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto ctor =
|
constexpr auto ctor =
|
||||||
(members_of(^^Cls, ctx) |
|
(members_of(^^Cls, ctx) |
|
||||||
std::views::filter(std::meta::is_constructor) |
|
std::views::filter(std::meta::is_constructor) |
|
||||||
std::views::filter(std::meta::is_user_provided)).front();
|
std::views::filter(std::meta::is_user_provided)).front();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <meta>
|
#include <meta>
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <ranges>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// [reflection]
|
// [reflection]
|
||||||
|
|
||||||
#include <meta>
|
#include <meta>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user