meta: meta_ctor_node is no longer static
This commit is contained in:
@@ -48,17 +48,6 @@ inline void link_type_if_required(meta_type_node *owner, const id_type id) noexc
|
||||
}
|
||||
}
|
||||
|
||||
inline void link_ctor_if_required(meta_type_node *owner, meta_ctor_node &node) noexcept {
|
||||
for(auto it = owner->ctor; it; it = it->next) {
|
||||
if(it == &node) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
node.next = owner->ctor;
|
||||
owner->ctor = &node;
|
||||
}
|
||||
|
||||
inline void link_func_if_required(meta_type_node *owner, const id_type id, meta_func_node &node) noexcept {
|
||||
node.id = id;
|
||||
|
||||
@@ -313,15 +302,11 @@ public:
|
||||
static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
|
||||
static_assert(std::is_same_v<std::remove_cv_t<std::remove_reference_t<typename descriptor::return_type>>, Type>, "The function doesn't return an object of the required type");
|
||||
|
||||
static internal::meta_ctor_node node{
|
||||
nullptr,
|
||||
owner->ctor[type_id<typename descriptor::args_type>().hash()] = internal::meta_ctor_node{
|
||||
descriptor::args_type::size,
|
||||
&meta_arg<typename descriptor::args_type>,
|
||||
&meta_construct<Type, Candidate, Policy>
|
||||
// tricks clang-format
|
||||
};
|
||||
&meta_construct<Type, Candidate, Policy>};
|
||||
|
||||
internal::link_ctor_if_required(owner, node);
|
||||
return meta_factory<Type>{};
|
||||
}
|
||||
|
||||
@@ -339,15 +324,11 @@ public:
|
||||
auto ctor() noexcept {
|
||||
using descriptor = meta_function_helper_t<Type, Type (*)(Args...)>;
|
||||
|
||||
static internal::meta_ctor_node node{
|
||||
nullptr,
|
||||
owner->ctor[type_id<typename descriptor::args_type>().hash()] = internal::meta_ctor_node{
|
||||
descriptor::args_type::size,
|
||||
&meta_arg<typename descriptor::args_type>,
|
||||
&meta_construct<Type, Args...>
|
||||
// tricks clang-format
|
||||
};
|
||||
&meta_construct<Type, Args...>};
|
||||
|
||||
internal::link_ctor_if_required(owner, node);
|
||||
return meta_factory<Type>{};
|
||||
}
|
||||
|
||||
@@ -577,10 +558,10 @@ inline void meta_reset(const id_type id) noexcept {
|
||||
for(auto **it = internal::meta_context::global(); *it; it = &(*it)->next) {
|
||||
if(auto *node = *it; node->id == id) {
|
||||
clear_chain(&node->prop);
|
||||
clear_chain(&node->ctor);
|
||||
clear_chain(&node->func, &internal::meta_func_node::prop);
|
||||
|
||||
node->id = {};
|
||||
node->ctor.clear();
|
||||
node->base.clear();
|
||||
node->conv.clear();
|
||||
node->data.clear();
|
||||
|
||||
@@ -924,8 +924,46 @@ private:
|
||||
|
||||
/*! @brief Opaque wrapper for types. */
|
||||
class meta_type {
|
||||
template<typename It>
|
||||
[[nodiscard]] auto lookup(It begin, It end, meta_any *const args, const typename internal::meta_type_node::size_type sz) const {
|
||||
size_type extent{sz + 1u};
|
||||
bool ambiguous{};
|
||||
auto candidate = end;
|
||||
|
||||
for(; begin != end; ++begin) {
|
||||
if(begin->second.arity == sz) {
|
||||
size_type direct{};
|
||||
size_type ext{};
|
||||
|
||||
for(size_type next{}; next < sz && next == (direct + ext) && args[next]; ++next) {
|
||||
const auto type = args[next].type();
|
||||
const auto other = begin->second.arg(next);
|
||||
|
||||
if(const auto &info = other.info(); info == type.info()) {
|
||||
++direct;
|
||||
} else {
|
||||
ext += type.node->base.contains(info.hash()) || type.node->conv.contains(info.hash())
|
||||
|| (type.node->conversion_helper && other.node->conversion_helper);
|
||||
}
|
||||
}
|
||||
|
||||
if((direct + ext) == sz) {
|
||||
if(ext < extent) {
|
||||
candidate = begin;
|
||||
extent = ext;
|
||||
ambiguous = false;
|
||||
} else if(ext == extent) {
|
||||
ambiguous = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ambiguous ? end : candidate;
|
||||
}
|
||||
|
||||
template<auto Member, typename... Check>
|
||||
[[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Check... check) const {
|
||||
[[nodiscard]] std::decay_t<decltype(std::declval<internal::meta_type_node>().*Member)> old_lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, Check... check) const {
|
||||
std::decay_t<decltype(node->*Member)> candidate{};
|
||||
size_type extent{sz + 1u};
|
||||
bool ambiguous{};
|
||||
@@ -1206,8 +1244,11 @@ public:
|
||||
* @return A wrapper containing the new instance, if any.
|
||||
*/
|
||||
[[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
|
||||
const auto *candidate = lookup<&node_type::ctor>(args, sz);
|
||||
return candidate ? candidate->invoke(args) : ((!sz && node->default_constructor) ? node->default_constructor() : meta_any{});
|
||||
if(auto it = lookup(node->ctor.cbegin(), node->ctor.cend(), args, sz); it != node->ctor.cend()) {
|
||||
return it->second.invoke(args);
|
||||
}
|
||||
|
||||
return (sz == 0u && node->default_constructor) ? node->default_constructor() : meta_any{};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1254,10 +1295,10 @@ public:
|
||||
* @return A wrapper containing the returned value, if any.
|
||||
*/
|
||||
meta_any invoke(const id_type id, meta_handle instance, meta_any *const args, const size_type sz) const {
|
||||
const auto *candidate = lookup<&node_type::func>(args, sz, id);
|
||||
const auto *candidate = old_lookup<&node_type::func>(args, sz, id);
|
||||
|
||||
for(auto it = base().begin(), last = base().end(); it != last && !candidate; ++it) {
|
||||
candidate = it->lookup<&node_type::func>(args, sz, id);
|
||||
candidate = it->old_lookup<&node_type::func>(args, sz, id);
|
||||
}
|
||||
|
||||
return candidate ? candidate->invoke(std::move(instance), args) : meta_any{};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../core/fwd.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../core/utility.hpp"
|
||||
#include "type_traits.hpp"
|
||||
|
||||
namespace entt {
|
||||
@@ -62,10 +63,9 @@ struct meta_conv_node {
|
||||
struct meta_ctor_node {
|
||||
using size_type = std::size_t;
|
||||
|
||||
meta_ctor_node *next;
|
||||
const size_type arity;
|
||||
meta_type (*const arg)(const size_type) noexcept;
|
||||
meta_any (*const invoke)(meta_any *const);
|
||||
size_type arity;
|
||||
meta_type (*arg)(const size_type) noexcept;
|
||||
meta_any (*invoke)(meta_any *const);
|
||||
};
|
||||
|
||||
struct meta_dtor_node {
|
||||
@@ -119,7 +119,7 @@ struct meta_type_node {
|
||||
double (*const conversion_helper)(void *, const void *);
|
||||
meta_any (*const from_void)(void *, const void *);
|
||||
meta_template_node templ;
|
||||
meta_ctor_node *ctor{nullptr};
|
||||
dense_map<id_type, meta_ctor_node, identity> ctor{};
|
||||
dense_map<id_type, meta_base_node, identity> base{};
|
||||
dense_map<id_type, meta_conv_node, identity> conv{};
|
||||
dense_map<id_type, meta_data_node, identity> data{};
|
||||
|
||||
Reference in New Issue
Block a user