meta: static local meta type node fallback
This commit is contained in:
@@ -32,14 +32,18 @@ namespace internal {
|
||||
class basic_meta_factory {
|
||||
using invoke_type = std::remove_pointer_t<decltype(meta_func_node::invoke)>;
|
||||
|
||||
auto &fetch_node() noexcept {
|
||||
return meta_context::from(*ctx).value[parent];
|
||||
}
|
||||
|
||||
auto *find_member_or_assert() {
|
||||
auto *member = find_member<&meta_data_node::id>(details->data, bucket);
|
||||
auto *member = find_member<&meta_data_node::id>(fetch_node().details->data, bucket);
|
||||
ENTT_ASSERT(member != nullptr, "Cannot find member");
|
||||
return member;
|
||||
}
|
||||
|
||||
auto *find_overload_or_assert() {
|
||||
auto *overload = find_overload(find_member<&meta_func_node::id>(details->func, bucket), invoke);
|
||||
auto *overload = find_overload(find_member<&meta_func_node::id>(fetch_node().details->func, bucket), invoke);
|
||||
ENTT_ASSERT(overload != nullptr, "Cannot find overload");
|
||||
return overload;
|
||||
}
|
||||
@@ -52,7 +56,7 @@ class basic_meta_factory {
|
||||
protected:
|
||||
void type(const id_type id, const char *name) noexcept {
|
||||
reset_bucket(parent);
|
||||
auto &&elem = meta_context::from(*ctx).value[parent];
|
||||
auto &elem = fetch_node();
|
||||
ENTT_ASSERT(elem.id == id || !resolve(*ctx, id), "Duplicate identifier");
|
||||
elem.name = name;
|
||||
elem.id = id;
|
||||
@@ -60,36 +64,42 @@ protected:
|
||||
|
||||
template<typename Type>
|
||||
void insert_or_assign(Type node) {
|
||||
auto &elem = fetch_node();
|
||||
|
||||
reset_bucket(parent);
|
||||
|
||||
if constexpr(std::is_same_v<Type, meta_base_node>) {
|
||||
auto *member = find_member<&meta_base_node::type>(details->base, node.type);
|
||||
member ? (*member = node) : details->base.emplace_back(node);
|
||||
auto *member = find_member<&meta_base_node::type>(elem.details->base, node.type);
|
||||
member ? (*member = node) : elem.details->base.emplace_back(node);
|
||||
} else if constexpr(std::is_same_v<Type, meta_conv_node>) {
|
||||
auto *member = find_member<&meta_conv_node::type>(details->conv, node.type);
|
||||
member ? (*member = node) : details->conv.emplace_back(node);
|
||||
auto *member = find_member<&meta_conv_node::type>(elem.details->conv, node.type);
|
||||
member ? (*member = node) : elem.details->conv.emplace_back(node);
|
||||
} else {
|
||||
static_assert(std::is_same_v<Type, meta_ctor_node>, "Unexpected type");
|
||||
auto *member = find_member<&meta_ctor_node::id>(details->ctor, node.id);
|
||||
member ? (*member = node) : details->ctor.emplace_back(node);
|
||||
auto *member = find_member<&meta_ctor_node::id>(elem.details->ctor, node.id);
|
||||
member ? (*member = node) : elem.details->ctor.emplace_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
void data(meta_data_node node) {
|
||||
auto &elem = fetch_node();
|
||||
|
||||
reset_bucket(node.id);
|
||||
|
||||
if(auto *member = find_member<&meta_data_node::id>(details->data, node.id); member == nullptr) {
|
||||
details->data.emplace_back(std::move(node));
|
||||
if(auto *member = find_member<&meta_data_node::id>(elem.details->data, node.id); member == nullptr) {
|
||||
elem.details->data.emplace_back(std::move(node));
|
||||
} else if(member->set != node.set || member->get != node.get) {
|
||||
*member = std::move(node);
|
||||
}
|
||||
}
|
||||
|
||||
void func(meta_func_node node) {
|
||||
auto &elem = fetch_node();
|
||||
|
||||
reset_bucket(node.id, node.invoke);
|
||||
|
||||
if(auto *member = find_member<&meta_func_node::id>(details->func, node.id); member == nullptr) {
|
||||
details->func.emplace_back(std::move(node));
|
||||
if(auto *member = find_member<&meta_func_node::id>(elem.details->func, node.id); member == nullptr) {
|
||||
elem.details->func.emplace_back(std::move(node));
|
||||
} else if(auto *overload = find_overload(member, node.invoke); overload == nullptr) {
|
||||
while(member->next != nullptr) { member = member->next.get(); }
|
||||
member->next = std::make_unique<meta_func_node>(std::move(node));
|
||||
@@ -98,7 +108,7 @@ protected:
|
||||
|
||||
void traits(const meta_traits value) {
|
||||
if(bucket == parent) {
|
||||
meta_context::from(*ctx).value[bucket].traits |= value;
|
||||
fetch_node().traits |= value;
|
||||
} else if(invoke == nullptr) {
|
||||
find_member_or_assert()->traits |= value;
|
||||
} else {
|
||||
@@ -108,7 +118,7 @@ protected:
|
||||
|
||||
void custom(meta_custom_node node) {
|
||||
if(bucket == parent) {
|
||||
details->custom = std::move(node);
|
||||
fetch_node().details->custom = std::move(node);
|
||||
} else if(invoke == nullptr) {
|
||||
find_member_or_assert()->custom = std::move(node);
|
||||
} else {
|
||||
@@ -117,15 +127,12 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
basic_meta_factory(meta_ctx &area, meta_type_node node)
|
||||
basic_meta_factory(meta_ctx &area, const meta_type_node &node)
|
||||
: ctx{&area},
|
||||
parent{node.info->hash()},
|
||||
bucket{parent},
|
||||
details{node.details.get()} {
|
||||
if(details == nullptr) {
|
||||
node.details = std::make_shared<meta_type_descriptor>();
|
||||
meta_context::from(*ctx).value[parent] = node;
|
||||
details = node.details.get();
|
||||
bucket{parent} {
|
||||
if(auto &curr = meta_context::from(*ctx).value.try_emplace(parent, node).first->second; curr.details == nullptr) {
|
||||
curr.details = std::make_shared<meta_type_descriptor>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +141,6 @@ private:
|
||||
id_type parent{};
|
||||
id_type bucket{};
|
||||
invoke_type *invoke{};
|
||||
meta_type_descriptor *details{};
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -76,8 +76,8 @@ public:
|
||||
private:
|
||||
const meta_ctx *ctx{};
|
||||
const void *data{};
|
||||
internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
|
||||
internal::meta_type_node (*const_reference_node)(const internal::meta_context &){};
|
||||
const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
|
||||
const internal::meta_type_node &(*const_reference_node)(const internal::meta_context &){};
|
||||
size_type (*size_fn)(const void *){};
|
||||
bool (*clear_fn)(void *){};
|
||||
bool (*reserve_fn)(void *, const size_type){};
|
||||
@@ -142,9 +142,9 @@ public:
|
||||
private:
|
||||
const meta_ctx *ctx{};
|
||||
const void *data{};
|
||||
internal::meta_type_node (*key_type_node)(const internal::meta_context &){};
|
||||
internal::meta_type_node (*mapped_type_node)(const internal::meta_context &){};
|
||||
internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
|
||||
const internal::meta_type_node &(*key_type_node)(const internal::meta_context &){};
|
||||
const internal::meta_type_node &(*mapped_type_node)(const internal::meta_context &){};
|
||||
const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
|
||||
size_type (*size_fn)(const void *){};
|
||||
bool (*clear_fn)(void *){};
|
||||
bool (*reserve_fn)(void *, const size_type){};
|
||||
@@ -629,7 +629,7 @@ public:
|
||||
private:
|
||||
any storage;
|
||||
const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
|
||||
internal::meta_type_node (*resolve)(const internal::meta_context &) noexcept {};
|
||||
const internal::meta_type_node &(*resolve)(const internal::meta_context &) noexcept {};
|
||||
mutable internal::meta_type_node lazy_node{};
|
||||
vtable_type *vtable{};
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ struct meta_custom_node {
|
||||
|
||||
struct meta_base_node {
|
||||
id_type type{};
|
||||
meta_type_node (*resolve)(const meta_context &) noexcept {};
|
||||
const meta_type_node &(*resolve)(const meta_context &) noexcept {};
|
||||
const void *(*cast)(const void *) noexcept {};
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@ struct meta_data_node {
|
||||
const char *name{};
|
||||
meta_traits traits{meta_traits::is_none};
|
||||
size_type arity{0u};
|
||||
meta_type_node (*type)(const meta_context &) noexcept {};
|
||||
const meta_type_node &(*type)(const meta_context &) noexcept {};
|
||||
meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
|
||||
bool (*set)(meta_handle, meta_any){};
|
||||
meta_any (*get)(meta_handle){};
|
||||
@@ -108,7 +108,7 @@ struct meta_func_node {
|
||||
const char *name{};
|
||||
meta_traits traits{meta_traits::is_none};
|
||||
size_type arity{0u};
|
||||
meta_type_node (*ret)(const meta_context &) noexcept {};
|
||||
const meta_type_node &(*ret)(const meta_context &) noexcept {};
|
||||
meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
|
||||
meta_any (*invoke)(meta_handle, meta_any *const){};
|
||||
std::unique_ptr<meta_func_node> next;
|
||||
@@ -119,8 +119,8 @@ struct meta_template_node {
|
||||
using size_type = std::size_t;
|
||||
|
||||
size_type arity{0u};
|
||||
meta_type_node (*resolve)(const meta_context &) noexcept {};
|
||||
meta_type_node (*arg)(const meta_context &, const size_type) noexcept {};
|
||||
const meta_type_node &(*resolve)(const meta_context &) noexcept {};
|
||||
const meta_type_node &(*arg)(const meta_context &, const size_type) noexcept {};
|
||||
};
|
||||
|
||||
struct meta_type_descriptor {
|
||||
@@ -140,7 +140,7 @@ struct meta_type_node {
|
||||
const char *name{};
|
||||
meta_traits traits{meta_traits::is_none};
|
||||
size_type size_of{0u};
|
||||
meta_type_node (*remove_pointer)(const meta_context &) noexcept {};
|
||||
const meta_type_node &(*remove_pointer)(const meta_context &) noexcept {};
|
||||
meta_any (*default_constructor)(const meta_ctx &){};
|
||||
double (*conversion_helper)(void *, const void *){};
|
||||
meta_any (*from_void)(const meta_ctx &, void *, const void *){};
|
||||
@@ -184,11 +184,11 @@ template<auto Member>
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
meta_type_node resolve(const meta_context &) noexcept;
|
||||
const meta_type_node &resolve(const meta_context &) noexcept;
|
||||
|
||||
template<typename... Args>
|
||||
[[nodiscard]] auto meta_arg_node(const meta_context &context, type_list<Args...>, [[maybe_unused]] const std::size_t index) noexcept {
|
||||
meta_type_node (*value)(const meta_context &) noexcept = nullptr;
|
||||
[[nodiscard]] const meta_type_node &meta_arg_node(const meta_context &context, type_list<Args...>, [[maybe_unused]] const std::size_t index) noexcept {
|
||||
const meta_type_node &(*value)(const meta_context &) noexcept = nullptr;
|
||||
|
||||
if constexpr(sizeof...(Args) != 0u) {
|
||||
std::size_t pos{};
|
||||
@@ -294,7 +294,7 @@ auto setup_node_for() noexcept {
|
||||
node.templ = meta_template_node{
|
||||
meta_template_traits<Type>::args_type::size,
|
||||
&resolve<typename meta_template_traits<Type>::class_type>,
|
||||
+[](const meta_context &area, const std::size_t index) noexcept { return meta_arg_node(area, typename meta_template_traits<Type>::args_type{}, index); }};
|
||||
+[](const meta_context &area, const std::size_t index) noexcept -> decltype(auto) { return meta_arg_node(area, typename meta_template_traits<Type>::args_type{}, index); }};
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -306,10 +306,11 @@ auto setup_node_for() noexcept {
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] meta_type_node resolve(const meta_context &context) noexcept {
|
||||
[[nodiscard]] const meta_type_node &resolve(const meta_context &context) noexcept {
|
||||
static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Invalid type");
|
||||
const auto *elem = try_resolve(context, type_id<Type>());
|
||||
return (elem == nullptr) ? setup_node_for<Type>() : *elem;
|
||||
static const meta_type_node node = setup_node_for<Type>();
|
||||
const auto *elem = try_resolve(context, *node.info);
|
||||
return (elem == nullptr) ? node : *elem;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
Reference in New Issue
Block a user