meta: meta_base 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_base_if_required(meta_type_node *owner, meta_base_node &node) noexcept {
|
||||
for(auto it = owner->base; it; it = it->next) {
|
||||
if(it == &node) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
node.next = owner->base;
|
||||
owner->base = &node;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -262,8 +251,7 @@ public:
|
||||
auto base() noexcept {
|
||||
static_assert(!std::is_same_v<Type, Base> && std::is_base_of_v<Base, Type>, "Invalid base type");
|
||||
|
||||
static internal::meta_base_node node{
|
||||
nullptr,
|
||||
owner->base[type_id<Base>().hash()] = internal::meta_base_node{
|
||||
internal::meta_node<Base>::resolve(),
|
||||
[](meta_any other) noexcept -> meta_any {
|
||||
if(auto *ptr = other.data(); ptr) {
|
||||
@@ -271,11 +259,8 @@ public:
|
||||
}
|
||||
|
||||
return forward_as_meta(*static_cast<const Base *>(static_cast<const Type *>(std::as_const(other).data())));
|
||||
}
|
||||
// tricks clang-format
|
||||
};
|
||||
}};
|
||||
|
||||
internal::link_base_if_required(owner, node);
|
||||
return meta_factory<Type>{};
|
||||
}
|
||||
|
||||
@@ -627,12 +612,12 @@ 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->base);
|
||||
clear_chain(&node->ctor);
|
||||
clear_chain(&node->data, &internal::meta_data_node::prop);
|
||||
clear_chain(&node->func, &internal::meta_func_node::prop);
|
||||
|
||||
node->id = {};
|
||||
node->base.clear();
|
||||
node->conv.clear();
|
||||
node->templ.reset();
|
||||
node->dtor = nullptr;
|
||||
|
||||
@@ -343,9 +343,11 @@ public:
|
||||
[[nodiscard]] const Type *try_cast() const {
|
||||
auto *self = any_cast<Type>(&storage);
|
||||
|
||||
for(auto *it = node ? node->base : nullptr; it && !self; it = it->next) {
|
||||
const auto &as_const = it->cast(as_ref());
|
||||
self = as_const.template try_cast<Type>();
|
||||
if(!self && node) {
|
||||
for(auto it = node->base.cbegin(), last = node->base.cend(); it != last && !self; ++it) {
|
||||
const auto &as_const = it->second.cast(as_ref());
|
||||
self = as_const.template try_cast<Type>();
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -356,8 +358,10 @@ public:
|
||||
[[nodiscard]] Type *try_cast() {
|
||||
auto *self = any_cast<Type>(&storage);
|
||||
|
||||
for(auto *it = node ? node->base : nullptr; it && !self; it = it->next) {
|
||||
self = it->cast(as_ref()).template try_cast<Type>();
|
||||
if(!self && node) {
|
||||
for(auto it = node->base.cbegin(), last = node->base.cend(); it != last && !self; ++it) {
|
||||
self = it->second.cast(as_ref()).template try_cast<Type>();
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -943,8 +947,7 @@ class meta_type {
|
||||
if(const auto &info = other.info(); info == type.info()) {
|
||||
++direct;
|
||||
} else {
|
||||
ext += internal::find_by<&node_type::base>(info, type.node)
|
||||
|| type.node->conv.contains(info.hash())
|
||||
ext += type.node->base.contains(info.hash()) || type.node->conv.contains(info.hash())
|
||||
|| (type.node->conversion_helper && other.node->conversion_helper);
|
||||
}
|
||||
}
|
||||
@@ -980,8 +983,8 @@ public:
|
||||
* @brief Constructs an instance from a given base node.
|
||||
* @param curr The base node with which to construct the instance.
|
||||
*/
|
||||
meta_type(const base_node_type *curr) noexcept
|
||||
: node{curr ? curr->type : nullptr} {}
|
||||
meta_type(const base_node_type &curr) noexcept
|
||||
: node{curr.type} {}
|
||||
|
||||
/**
|
||||
* @brief Returns the type info object of the underlying type.
|
||||
@@ -1140,8 +1143,8 @@ public:
|
||||
* @brief Returns a range to visit registered top-level base meta types.
|
||||
* @return An iterable range to visit registered top-level base meta types.
|
||||
*/
|
||||
[[nodiscard]] old_meta_range<meta_type, internal::meta_base_node> base() const noexcept {
|
||||
return {node->base, nullptr};
|
||||
[[nodiscard]] meta_range<meta_type, typename decltype(internal::meta_type_node::base)::const_iterator> base() const noexcept {
|
||||
return {node->base.cbegin(), node->base.cend()};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1402,8 +1405,8 @@ bool meta_any::set(const id_type id, Type &&value) {
|
||||
return other;
|
||||
}
|
||||
|
||||
for(auto *it = node->base; it; it = it->next) {
|
||||
const auto &as_const = it->cast(as_ref());
|
||||
for(auto &&curr: node->base) {
|
||||
const auto &as_const = curr.second.cast(as_ref());
|
||||
|
||||
if(auto other = as_const.allow_cast(type); other) {
|
||||
return other;
|
||||
|
||||
@@ -51,9 +51,8 @@ struct meta_prop_node {
|
||||
};
|
||||
|
||||
struct meta_base_node {
|
||||
meta_base_node *next;
|
||||
meta_type_node *const type;
|
||||
meta_any (*const cast)(meta_any) noexcept;
|
||||
meta_type_node *type;
|
||||
meta_any (*cast)(meta_any) noexcept;
|
||||
};
|
||||
|
||||
struct meta_conv_node {
|
||||
@@ -119,7 +118,7 @@ struct meta_type_node {
|
||||
meta_any (*const from_void)(void *, const void *);
|
||||
std::unique_ptr<meta_template_node> templ;
|
||||
meta_ctor_node *ctor{nullptr};
|
||||
meta_base_node *base{nullptr};
|
||||
dense_map<id_type, meta_base_node, identity> base{};
|
||||
dense_map<id_type, meta_conv_node, identity> conv{};
|
||||
meta_data_node *data{nullptr};
|
||||
meta_func_node *func{nullptr};
|
||||
@@ -236,8 +235,8 @@ template<auto Member, typename Type>
|
||||
}
|
||||
}
|
||||
|
||||
for(auto *curr = node->base; curr; curr = curr->next) {
|
||||
if(auto *ret = find_by<Member>(info_or_id, curr->type); ret) {
|
||||
for(auto &&curr: node->base) {
|
||||
if(auto *ret = find_by<Member>(info_or_id, curr.second.type); ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,49 @@ private:
|
||||
node_type *it;
|
||||
};
|
||||
|
||||
template<typename Type, typename It>
|
||||
struct meta_range_iterator final {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = Type;
|
||||
using pointer = input_iterator_pointer<value_type>;
|
||||
using reference = value_type;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
meta_range_iterator() noexcept
|
||||
: it{} {}
|
||||
|
||||
meta_range_iterator(It iter) noexcept
|
||||
: it{iter} {}
|
||||
|
||||
meta_range_iterator &operator++() noexcept {
|
||||
return ++it, *this;
|
||||
}
|
||||
|
||||
meta_range_iterator operator++(int) noexcept {
|
||||
meta_range_iterator orig = *this;
|
||||
return ++(*this), orig;
|
||||
}
|
||||
|
||||
[[nodiscard]] reference operator*() const noexcept {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] pointer operator->() const noexcept {
|
||||
return operator*();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const meta_range_iterator &other) const noexcept {
|
||||
return it == other.it;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const meta_range_iterator &other) const noexcept {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
It it;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/**
|
||||
@@ -73,6 +116,14 @@ private:
|
||||
template<typename Type, typename Node = typename Type::node_type>
|
||||
using old_meta_range = iterable_adaptor<internal::old_meta_range_iterator<Type, Node>>;
|
||||
|
||||
/**
|
||||
* @brief Iterable range to use to iterate all types of meta objects.
|
||||
* @tparam Type Type of meta objects returned.
|
||||
* @tparam It Type of forward iterator.
|
||||
*/
|
||||
template<typename Type, typename It>
|
||||
using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
|
||||
|
||||
} // namespace entt
|
||||
|
||||
#endif
|
||||
|
||||
@@ -183,13 +183,6 @@ TEST_F(MetaBase, ReRegistration) {
|
||||
|
||||
auto *node = entt::internal::meta_node<derived_t>::resolve();
|
||||
|
||||
ASSERT_NE(node->base, nullptr);
|
||||
ASSERT_NE(node->base->type->base, nullptr);
|
||||
ASSERT_EQ(node->base->type->base->next, nullptr);
|
||||
ASSERT_EQ(node->base->type->base->type->base, nullptr);
|
||||
|
||||
ASSERT_NE(node->base->next, nullptr);
|
||||
ASSERT_EQ(node->base->next->type->base, nullptr);
|
||||
|
||||
ASSERT_EQ(node->base->next->next, nullptr);
|
||||
ASSERT_FALSE(node->base.empty());
|
||||
ASSERT_EQ(node->base.size(), 2u);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user