|
@@ -32,14 +32,18 @@ namespace internal {
|
|
|
class basic_meta_factory {
|
|
class basic_meta_factory {
|
|
|
using invoke_type = std::remove_pointer_t<decltype(meta_func_node::invoke)>;
|
|
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 *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");
|
|
ENTT_ASSERT(member != nullptr, "Cannot find member");
|
|
|
return member;
|
|
return member;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
auto *find_overload_or_assert() {
|
|
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");
|
|
ENTT_ASSERT(overload != nullptr, "Cannot find overload");
|
|
|
return overload;
|
|
return overload;
|
|
|
}
|
|
}
|
|
@@ -52,7 +56,7 @@ class basic_meta_factory {
|
|
|
protected:
|
|
protected:
|
|
|
void type(const id_type id, const char *name) noexcept {
|
|
void type(const id_type id, const char *name) noexcept {
|
|
|
reset_bucket(parent);
|
|
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");
|
|
ENTT_ASSERT(elem.id == id || !resolve(*ctx, id), "Duplicate identifier");
|
|
|
elem.name = name;
|
|
elem.name = name;
|
|
|
elem.id = id;
|
|
elem.id = id;
|
|
@@ -60,36 +64,42 @@ protected:
|
|
|
|
|
|
|
|
template<typename Type>
|
|
template<typename Type>
|
|
|
void insert_or_assign(Type node) {
|
|
void insert_or_assign(Type node) {
|
|
|
|
|
+ auto &elem = fetch_node();
|
|
|
|
|
+
|
|
|
reset_bucket(parent);
|
|
reset_bucket(parent);
|
|
|
|
|
|
|
|
if constexpr(std::is_same_v<Type, meta_base_node>) {
|
|
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>) {
|
|
} 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 {
|
|
} else {
|
|
|
static_assert(std::is_same_v<Type, meta_ctor_node>, "Unexpected type");
|
|
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) {
|
|
void data(meta_data_node node) {
|
|
|
|
|
+ auto &elem = fetch_node();
|
|
|
|
|
+
|
|
|
reset_bucket(node.id);
|
|
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) {
|
|
} else if(member->set != node.set || member->get != node.get) {
|
|
|
*member = std::move(node);
|
|
*member = std::move(node);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void func(meta_func_node node) {
|
|
void func(meta_func_node node) {
|
|
|
|
|
+ auto &elem = fetch_node();
|
|
|
|
|
+
|
|
|
reset_bucket(node.id, node.invoke);
|
|
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) {
|
|
} else if(auto *overload = find_overload(member, node.invoke); overload == nullptr) {
|
|
|
while(member->next != nullptr) { member = member->next.get(); }
|
|
while(member->next != nullptr) { member = member->next.get(); }
|
|
|
member->next = std::make_unique<meta_func_node>(std::move(node));
|
|
member->next = std::make_unique<meta_func_node>(std::move(node));
|
|
@@ -98,7 +108,7 @@ protected:
|
|
|
|
|
|
|
|
void traits(const meta_traits value) {
|
|
void traits(const meta_traits value) {
|
|
|
if(bucket == parent) {
|
|
if(bucket == parent) {
|
|
|
- meta_context::from(*ctx).value[bucket].traits |= value;
|
|
|
|
|
|
|
+ fetch_node().traits |= value;
|
|
|
} else if(invoke == nullptr) {
|
|
} else if(invoke == nullptr) {
|
|
|
find_member_or_assert()->traits |= value;
|
|
find_member_or_assert()->traits |= value;
|
|
|
} else {
|
|
} else {
|
|
@@ -108,7 +118,7 @@ protected:
|
|
|
|
|
|
|
|
void custom(meta_custom_node node) {
|
|
void custom(meta_custom_node node) {
|
|
|
if(bucket == parent) {
|
|
if(bucket == parent) {
|
|
|
- details->custom = std::move(node);
|
|
|
|
|
|
|
+ fetch_node().details->custom = std::move(node);
|
|
|
} else if(invoke == nullptr) {
|
|
} else if(invoke == nullptr) {
|
|
|
find_member_or_assert()->custom = std::move(node);
|
|
find_member_or_assert()->custom = std::move(node);
|
|
|
} else {
|
|
} else {
|
|
@@ -117,15 +127,12 @@ protected:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
public:
|
|
|
- basic_meta_factory(meta_ctx &area, meta_type_node node)
|
|
|
|
|
|
|
+ basic_meta_factory(meta_ctx &area, const meta_type_node &node)
|
|
|
: ctx{&area},
|
|
: ctx{&area},
|
|
|
parent{node.info->hash()},
|
|
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 parent{};
|
|
|
id_type bucket{};
|
|
id_type bucket{};
|
|
|
invoke_type *invoke{};
|
|
invoke_type *invoke{};
|
|
|
- meta_type_descriptor *details{};
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
} // namespace internal
|