From 945e61d668fcb4f618e7a93fc39ef70c1bf40e54 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Mon, 22 Aug 2022 18:20:37 +0200 Subject: [PATCH] meta: * meta_prop_node is no longer static * we can attach multiple properties at different times * meta property keys are of type id_type only * removed meta_factory::props (use prop instead) * meta range returns id and meta object pairs now * removed mera_prop::key (id returned by meta ranges) --- src/entt/meta/factory.hpp | 136 ++++++++--------------------------- src/entt/meta/meta.hpp | 52 +++++++------- src/entt/meta/node.hpp | 14 ++-- test/entt/meta/meta_data.cpp | 42 +++++------ test/entt/meta/meta_func.cpp | 46 ++++++------ test/entt/meta/meta_prop.cpp | 20 +++--- test/entt/meta/meta_type.cpp | 64 +++++++++-------- 7 files changed, 144 insertions(+), 230 deletions(-) diff --git a/src/entt/meta/factory.hpp b/src/entt/meta/factory.hpp index e04eb2b04..c0160bfdd 100644 --- a/src/entt/meta/factory.hpp +++ b/src/entt/meta/factory.hpp @@ -26,18 +26,6 @@ namespace entt { namespace internal { -inline void link_prop_if_required(internal::meta_prop_node **ref, internal::meta_prop_node &node) noexcept { - for(auto it = *ref; it; it = it->next) { - if(it == &node) { - return; - } - ENTT_ASSERT(it->id != node.id, "Duplicate identifier"); - } - - node.next = *ref; - *ref = &node; -} - inline void link_type_if_required(meta_type_node *owner, const id_type id) noexcept { ENTT_ASSERT((owner->id = {}, !resolve(id)), "Duplicate identifier"); owner->id = id; @@ -82,95 +70,39 @@ class meta_factory; /** * @brief Extended meta factory to be used for reflection purposes. * @tparam Type Reflected type for which the factory was created. - * @tparam Spec Property specialization pack used to disambiguate overloads. + * @tparam Prop Type of container to store properties. */ -template -class meta_factory: public meta_factory { - template - void unroll(choice_t<2>, std::tuple property, Other &&...other) noexcept { - std::apply([this](auto &&...curr) { (this->unroll(choice<2>, std::forward(curr)...)); }, property); - unroll(choice<2>, std::forward(other)...); - } - - template - void unroll(choice_t<1>, std::pair property, Other &&...other) noexcept { - assign(std::move(property.first), std::move(property.second)); - unroll(choice<2>, std::forward(other)...); - } - - template - void unroll(choice_t<0>, Property &&property, Other &&...other) noexcept { - assign(std::forward(property)); - unroll(choice<2>, std::forward(other)...); - } - - template - void unroll(choice_t<0>) noexcept {} - - template - void assign(meta_any key, meta_any value = {}) { - static meta_any property[2u]{}; - - static internal::meta_prop_node node{ - nullptr, - property[0u], - property[1u] - // tricks clang-format - }; - - property[0u] = std::move(key); - property[1u] = std::move(value); - - internal::link_prop_if_required(ref, node); - } - +template +class meta_factory: public meta_factory { public: /** * @brief Constructs an extended factory from a given node. - * @param target The underlying node to which to assign the properties. + * @param target The underlying container to store properties. */ - meta_factory(internal::meta_prop_node **target) noexcept - : ref{target} {} + meta_factory(Prop &target) noexcept + : container{&target} {} /** * @brief Assigns a property to the last meta object created. * * Both the key and the value (if any) must be at least copy constructible. * - * @tparam PropertyOrKey Type of the property or property key. * @tparam Value Optional type of the property value. - * @param property_or_key Property or property key. + * @param key Property key. * @param value Optional property value. - * @return A meta factory for the parent type. + * @return An extended meta factory for the given type. */ - template - meta_factory prop(PropertyOrKey &&property_or_key, Value &&...value) { - if constexpr(sizeof...(Value) == 0) { - unroll(choice<2>, std::forward(property_or_key)); - } else { - assign(std::forward(property_or_key), std::forward(value)...); - } + template + meta_factory prop(id_type key, Value &&...value) { + (*container)[key] = internal::meta_prop_node{ + internal::meta_node>::resolve()..., + std::forward(value)...}; - return {}; - } - - /** - * @brief Assigns properties to the last meta object created. - * - * Both key and value (if any) must be at least copy constructible. - * - * @tparam Property Types of the properties. - * @param property Properties to assign to the last meta object created. - * @return A meta factory for the parent type. - */ - template - meta_factory props(Property... property) { - unroll(choice<2>, std::forward(property)...); - return {}; + return *this; } private: - internal::meta_prop_node **ref; + Prop *container; }; /** @@ -188,14 +120,13 @@ class meta_factory { owner->data[id] = internal::meta_data_node{ /* this is never static */ (std::is_member_object_pointer_v)> && ... && std::is_const_v>) ? internal::meta_traits::is_const : internal::meta_traits::is_none, - nullptr, Setter::size, internal::meta_node>>::resolve(), &meta_arg::size != 1u, type_list_element_t>...>>, [](meta_handle instance, meta_any value) -> bool { return (meta_setter>(*instance.operator->(), value.as_ref()) || ...); }, &meta_getter}; - return meta_factory>{&owner->data[id].prop}; + return meta_factory{owner->data[id].prop}; } public: @@ -210,7 +141,7 @@ public: */ auto type(const id_type id = type_hash::value()) noexcept { internal::link_type_if_required(owner, id); - return meta_factory{&owner->prop}; + return meta_factory{owner->prop}; } /** @@ -378,27 +309,25 @@ public: owner->data[id] = internal::meta_data_node{ /* this is never static */ std::is_const_v ? internal::meta_traits::is_const : internal::meta_traits::is_none, - nullptr, 1u, internal::meta_node>::resolve(), &meta_arg>>, &meta_setter, &meta_getter}; - return meta_factory, std::integral_constant>{&owner->data[id].prop}; + return meta_factory{owner->data[id].prop}; } else { using data_type = std::remove_reference_t>; owner->data[id] = internal::meta_data_node{ ((std::is_same_v> || std::is_const_v) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static, - nullptr, 1u, internal::meta_node>::resolve(), &meta_arg>>, &meta_setter, &meta_getter}; - return meta_factory>{&owner->data[id].prop}; + return meta_factory{owner->data[id].prop}; } } @@ -431,28 +360,26 @@ public: owner->data[id] = internal::meta_data_node{ /* this is never static */ internal::meta_traits::is_const, - nullptr, 0u, internal::meta_node>>::resolve(), &meta_arg>, &meta_setter, &meta_getter}; - return meta_factory, std::integral_constant>{&owner->data[id].prop}; + return meta_factory{owner->data[id].prop}; } else { using args_type = typename meta_function_helper_t::args_type; owner->data[id] = internal::meta_data_node{ /* this is never static nor const */ internal::meta_traits::is_none, - nullptr, 1u, internal::meta_node>>::resolve(), &meta_arg>>, &meta_setter, &meta_getter}; - return meta_factory, std::integral_constant>{&owner->data[id].prop}; + return meta_factory{owner->data[id].prop}; } } @@ -500,7 +427,6 @@ public: {}, (descriptor::is_const ? internal::meta_traits::is_const : internal::meta_traits::is_none) | (descriptor::is_static ? internal::meta_traits::is_static : internal::meta_traits::is_none), nullptr, - nullptr, descriptor::args_type::size, internal::meta_node, void, std::remove_cv_t>>>::resolve(), &meta_arg, @@ -509,7 +435,7 @@ public: }; internal::link_func_if_required(owner, id, node); - return meta_factory>{&node.prop}; + return meta_factory{node.prop}; } private: @@ -531,7 +457,7 @@ template [[nodiscard]] auto meta() noexcept { auto *const node = internal::meta_node::resolve(); // extended meta factory to allow assigning properties to opaque meta types - return meta_factory{&node->prop}; + return meta_factory{node->prop}; } /** @@ -546,26 +472,20 @@ template * @param id Unique identifier. */ inline void meta_reset(const id_type id) noexcept { - auto clear_chain = [](auto **curr, auto... member) { - for(; *curr; *curr = std::exchange((*curr)->next, nullptr)) { - if constexpr(sizeof...(member) != 0u) { - static_assert(sizeof...(member) == 1u, "Assert in defense of the future me"); - for(auto **sub = (&((*curr)->*member), ...); *sub; *sub = std::exchange((*sub)->next, nullptr)) {} - } - } - }; - 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->func, &internal::meta_func_node::prop); + for(auto **curr = &node->func; *curr; *curr = std::exchange((*curr)->next, nullptr)) { + (*curr)->prop.clear(); + } node->id = {}; + node->prop.clear(); node->ctor.clear(); node->base.clear(); node->conv.clear(); node->data.clear(); node->dtor.dtor = nullptr; + *it = std::exchange(node->next, nullptr); break; diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index b6eff921b..422f6428f 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -664,20 +664,12 @@ struct meta_prop { meta_prop(const node_type *curr = nullptr) noexcept : node{curr} {} - /** - * @brief Returns the stored key as a const reference. - * @return A wrapper containing the key stored with the property. - */ - [[nodiscard]] meta_any key() const { - return node->id.as_ref(); - } - /** * @brief Returns the stored value by copy. * @return A wrapper containing the value stored with the property. */ [[nodiscard]] meta_any value() const { - return node->value; + return (node && node->type) ? node->type->from_void(nullptr, node->value.data()) : meta_any{}; } /** @@ -772,8 +764,8 @@ struct meta_data { * @brief Returns a range to visit registered meta properties. * @return An iterable range to visit registered meta properties. */ - [[nodiscard]] old_meta_range prop() const noexcept { - return {node->prop, nullptr}; + [[nodiscard]] meta_range prop() const noexcept { + return {node->prop.cbegin(), node->prop.cend()}; } /** @@ -781,11 +773,9 @@ struct meta_data { * @param key The key to use to search for a property. * @return The registered meta property for the given key, if any. */ - [[nodiscard]] meta_prop prop(meta_any key) const { - for(auto curr: prop()) { - if(curr.key() == key) { - return curr; - } + [[nodiscard]] meta_prop prop(const id_type key) const { + if(auto it = node->prop.find(key); it != node->prop.cend()) { + return &it->second; } return nullptr; @@ -891,8 +881,8 @@ struct meta_func { } /*! @copydoc meta_data::prop */ - [[nodiscard]] old_meta_range prop() const noexcept { - return {node->prop, nullptr}; + [[nodiscard]] meta_range prop() const noexcept { + return {node->prop.cbegin(), node->prop.cend()}; } /** @@ -900,11 +890,9 @@ struct meta_func { * @param key The key to use to search for a property. * @return The registered meta property for the given key, if any. */ - [[nodiscard]] meta_prop prop(meta_any key) const { - for(auto curr: prop()) { - if(curr.key() == key) { - return curr; - } + [[nodiscard]] meta_prop prop(const id_type key) const { + if(auto it = node->prop.find(key); it != node->prop.cend()) { + return &it->second; } return nullptr; @@ -1364,8 +1352,8 @@ public: * @brief Returns a range to visit registered top-level meta properties. * @return An iterable range to visit registered top-level meta properties. */ - [[nodiscard]] old_meta_range prop() const noexcept { - return {node->prop, nullptr}; + [[nodiscard]] meta_range prop() const noexcept { + return {node->prop.cbegin(), node->prop.cend()}; } /** @@ -1376,8 +1364,18 @@ public: * @param key The key to use to search for a property. * @return The registered meta property for the given key, if any. */ - [[nodiscard]] meta_prop prop(meta_any key) const { - return internal::find_by<&internal::meta_type_node::prop>(key, node); + [[nodiscard]] meta_prop prop(const id_type key) const { + if(auto it = node->prop.find(key); it != node->prop.cend()) { + return &it->second; + } + + for(auto &&curr: base()) { + if(auto elem = curr.second.prop(key); elem) { + return elem; + } + } + + return nullptr; } /** diff --git a/src/entt/meta/node.hpp b/src/entt/meta/node.hpp index df6fd8c0b..6f63e224d 100644 --- a/src/entt/meta/node.hpp +++ b/src/entt/meta/node.hpp @@ -46,9 +46,8 @@ enum class meta_traits : std::uint32_t { struct meta_type_node; struct meta_prop_node { - meta_prop_node *next; - const meta_any &id; - meta_any &value; + meta_type_node *type{nullptr}; + basic_any<0u> value{}; }; struct meta_base_node { @@ -76,12 +75,12 @@ struct meta_data_node { using size_type = std::size_t; meta_traits traits; - meta_prop_node *prop; size_type arity; meta_type_node *type; meta_type (*arg)(const size_type) noexcept; bool (*set)(meta_handle, meta_any); meta_any (*get)(meta_handle); + dense_map prop{}; }; struct meta_func_node { @@ -90,11 +89,11 @@ struct meta_func_node { id_type id; const meta_traits traits; meta_func_node *next; - meta_prop_node *prop; const size_type arity; meta_type_node *const ret; meta_type (*const arg)(const size_type) noexcept; meta_any (*const invoke)(meta_handle, meta_any *const); + dense_map prop{}; }; struct meta_template_node { @@ -112,13 +111,13 @@ struct meta_type_node { id_type id; const meta_traits traits; meta_type_node *next; - meta_prop_node *prop; const size_type size_of; meta_type_node *(*const remove_pointer)() noexcept; meta_any (*const default_constructor)(); double (*const conversion_helper)(void *, const void *); meta_any (*const from_void)(void *, const void *); meta_template_node templ; + dense_map prop{}; dense_map ctor{}; dense_map base{}; dense_map conv{}; @@ -132,7 +131,7 @@ meta_type_node *meta_arg_node(type_list, const std::size_t index) noexc template class ENTT_API meta_node { - static_assert(std::is_same_v>>, "Invalid type"); + static_assert(std::is_same_v>>, "Invalid type"); [[nodiscard]] static auto *meta_default_constructor() noexcept { if constexpr(std::is_default_constructible_v) { @@ -195,7 +194,6 @@ public: | (is_complete_v> ? internal::meta_traits::is_meta_sequence_container : internal::meta_traits::is_none) | (is_complete_v> ? internal::meta_traits::is_meta_associative_container : internal::meta_traits::is_none), nullptr, - nullptr, size_of_v, &meta_node>>::resolve, meta_default_constructor(), diff --git a/test/entt/meta/meta_data.cpp b/test/entt/meta/meta_data.cpp index cf28249a6..2c7f6bc5d 100644 --- a/test/entt/meta/meta_data.cpp +++ b/test/entt/meta/meta_data.cpp @@ -93,7 +93,7 @@ struct array_t { int local[5]; }; -enum class property_t { +enum class property_t : entt::id_type { random, value }; @@ -119,14 +119,14 @@ struct MetaData: ::testing::Test { entt::meta() .type("clazz"_hs) .data<&clazz_t::i, entt::as_ref_t>("i"_hs) - .prop(3, 0) + .prop(3u, 0) .data<&clazz_t::i, entt::as_cref_t>("ci"_hs) .data<&clazz_t::j>("j"_hs) - .prop(true, 1) + .prop("true"_hs, 1) .data<&clazz_t::h>("h"_hs) - .prop(property_t::random, 2) + .prop(static_cast(property_t::random), 2) .data<&clazz_t::k>("k"_hs) - .prop(property_t::value, 3) + .prop(static_cast(property_t::value), 3) .data<&clazz_t::base>("base"_hs) .data<&clazz_t::i, entt::as_void_t>("void"_hs) .conv(); @@ -176,17 +176,16 @@ TEST_F(MetaData, Functionalities) { ASSERT_EQ(data.get(instance).cast(), 42); for(auto curr: data.prop()) { - ASSERT_EQ(curr.key(), 3); - ASSERT_EQ(curr.value(), 0); + ASSERT_EQ(curr.first, 3u); + ASSERT_EQ(curr.second.value(), 0); } ASSERT_FALSE(data.prop(2)); ASSERT_FALSE(data.prop('c')); - auto prop = data.prop(3); + auto prop = data.prop(3u); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), 3); ASSERT_EQ(prop.value(), 0); } @@ -207,17 +206,16 @@ TEST_F(MetaData, Const) { ASSERT_EQ(data.get(instance).cast(), 1); for(auto curr: data.prop()) { - ASSERT_EQ(curr.key(), true); - ASSERT_EQ(curr.value(), 1); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_EQ(curr.second.value(), 1); } ASSERT_FALSE(data.prop(false)); ASSERT_FALSE(data.prop('c')); - auto prop = data.prop(true); + auto prop = data.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_EQ(prop.value(), 1); } @@ -237,17 +235,16 @@ TEST_F(MetaData, Static) { ASSERT_EQ(data.get({}).cast(), 42); for(auto curr: data.prop()) { - ASSERT_EQ(curr.key(), property_t::random); - ASSERT_EQ(curr.value(), 2); + ASSERT_EQ(curr.first, static_cast(property_t::random)); + ASSERT_EQ(curr.second.value(), 2); } - ASSERT_FALSE(data.prop(property_t::value)); + ASSERT_FALSE(data.prop(static_cast(property_t::value))); ASSERT_FALSE(data.prop('c')); - auto prop = data.prop(property_t::random); + auto prop = data.prop(static_cast(property_t::random)); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), property_t::random); ASSERT_EQ(prop.value(), 2); } @@ -267,17 +264,16 @@ TEST_F(MetaData, ConstStatic) { ASSERT_EQ(data.get({}).cast(), 3); for(auto curr: data.prop()) { - ASSERT_EQ(curr.key(), property_t::value); - ASSERT_EQ(curr.value(), 3); + ASSERT_EQ(curr.first, static_cast(property_t::value)); + ASSERT_EQ(curr.second.value(), 3); } - ASSERT_FALSE(data.prop(property_t::random)); + ASSERT_FALSE(data.prop(static_cast(property_t::random))); ASSERT_FALSE(data.prop('c')); - auto prop = data.prop(property_t::value); + auto prop = data.prop(static_cast(property_t::value)); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), property_t::value); ASSERT_EQ(prop.value(), 3); } diff --git a/test/entt/meta/meta_func.cpp b/test/entt/meta/meta_func.cpp index d0b229143..45dc6c026 100644 --- a/test/entt/meta/meta_func.cpp +++ b/test/entt/meta/meta_func.cpp @@ -114,15 +114,15 @@ struct MetaFunc: ::testing::Test { .func<&entt::registry::emplace_or_replace>("emplace"_hs) .func(&func_t::f)>("f3"_hs) .func(&func_t::f)>("f2"_hs) - .prop(true, false) + .prop("true"_hs, false) .func(&func_t::f)>("f1"_hs) - .prop(true, false) + .prop("true"_hs, false) .func<&func_t::g>("g"_hs) - .prop(true, false) + .prop("true"_hs, false) .func("h"_hs) - .prop(true, false) + .prop("true"_hs, false) .func("k"_hs) - .prop(true, false) + .prop("true"_hs, false) .func<&func_t::v, entt::as_void_t>("v"_hs) .func<&func_t::a, entt::as_ref_t>("a"_hs) .func<&func_t::a, entt::as_cref_t>("ca"_hs) @@ -180,17 +180,16 @@ TEST_F(MetaFunc, Functionalities) { ASSERT_EQ(func_t::value, 3); for(auto curr: func.prop()) { - ASSERT_EQ(curr.key(), true); - ASSERT_FALSE(curr.value().template cast()); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_FALSE(curr.second.value().template cast()); } ASSERT_FALSE(func.prop(false)); ASSERT_FALSE(func.prop('c')); - auto prop = func.prop(true); + auto prop = func.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_FALSE(prop.value().cast()); } @@ -218,17 +217,16 @@ TEST_F(MetaFunc, Const) { ASSERT_EQ(any.cast(), 16); for(auto curr: func.prop()) { - ASSERT_EQ(curr.key(), true); - ASSERT_FALSE(curr.value().template cast()); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_FALSE(curr.second.value().template cast()); } ASSERT_FALSE(func.prop(false)); ASSERT_FALSE(func.prop('c')); - auto prop = func.prop(true); + auto prop = func.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_FALSE(prop.value().cast()); } @@ -254,17 +252,16 @@ TEST_F(MetaFunc, RetVoid) { ASSERT_EQ(func_t::value, 25); for(auto curr: func.prop()) { - ASSERT_EQ(curr.key(), true); - ASSERT_FALSE(curr.value().template cast()); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_FALSE(curr.second.value().template cast()); } ASSERT_FALSE(func.prop(false)); ASSERT_FALSE(func.prop('c')); - auto prop = func.prop(true); + auto prop = func.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_FALSE(prop.value().cast()); } @@ -292,17 +289,16 @@ TEST_F(MetaFunc, Static) { ASSERT_EQ(any.cast(), 6); for(auto curr: func.prop()) { - ASSERT_EQ(curr.key(), true); - ASSERT_FALSE(curr.value().template cast()); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_FALSE(curr.second.value().template cast()); } ASSERT_FALSE(func.prop(false)); ASSERT_FALSE(func.prop('c')); - auto prop = func.prop(true); + auto prop = func.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_FALSE(prop.value().cast()); } @@ -327,18 +323,16 @@ TEST_F(MetaFunc, StaticRetVoid) { ASSERT_EQ(func_t::value, 42); for(auto curr: func.prop()) { - ASSERT_TRUE(curr); - ASSERT_EQ(curr.key(), true); - ASSERT_FALSE(curr.value().template cast()); + ASSERT_EQ(curr.first, "true"_hs); + ASSERT_FALSE(curr.second.value().template cast()); } ASSERT_FALSE(func.prop(false)); ASSERT_FALSE(func.prop('c')); - auto prop = func.prop(true); + auto prop = func.prop("true"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), true); ASSERT_FALSE(prop.value().cast()); } diff --git a/test/entt/meta/meta_prop.cpp b/test/entt/meta/meta_prop.cpp index 48fef1526..e917df119 100644 --- a/test/entt/meta/meta_prop.cpp +++ b/test/entt/meta/meta_prop.cpp @@ -22,11 +22,13 @@ struct MetaProp: ::testing::Test { entt::meta() .type("base_2"_hs) - .props(std::make_pair("bool"_hs, false), std::make_pair("char[]"_hs, "char[]")); + .prop("bool"_hs, false) + .prop("char[]"_hs, "char[]"); entt::meta() .type("base_3"_hs) - .prop(std::make_tuple("key_only"_hs, std::make_pair("key"_hs, 42))); + .prop("key_only"_hs) + .prop("key"_hs, 42); entt::meta() .type("derived"_hs) @@ -46,7 +48,6 @@ TEST_F(MetaProp, Functionalities) { auto prop = entt::resolve().prop("int"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), "int"_hs); ASSERT_EQ(prop.value(), 42); } @@ -76,7 +77,6 @@ TEST_F(MetaProp, DeducedArrayType) { auto prop = entt::resolve().prop("char[]"_hs); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), "char[]"_hs); ASSERT_EQ(prop.value().type(), entt::resolve()); ASSERT_EQ(strcmp(prop.value().cast(), "char[]"), 0); } @@ -89,18 +89,20 @@ TEST_F(MetaProp, ReRegistration) { auto *node = entt::internal::meta_node::resolve(); auto type = entt::resolve(); - ASSERT_NE(node->prop, nullptr); - ASSERT_EQ(node->prop->next, nullptr); + ASSERT_FALSE(node->prop.empty()); + ASSERT_EQ(node->prop.size(), 1u); ASSERT_TRUE(type.prop("int"_hs)); ASSERT_EQ(type.prop("int"_hs).value().cast(), 42); + entt::meta().prop("int"_hs, 0); entt::meta().prop("double"_hs, 3.); - ASSERT_NE(node->prop, nullptr); - ASSERT_EQ(node->prop->next, nullptr); + ASSERT_FALSE(node->prop.empty()); + ASSERT_EQ(node->prop.size(), 2u); - ASSERT_FALSE(type.prop("int"_hs)); + ASSERT_TRUE(type.prop("int"_hs)); ASSERT_TRUE(type.prop("double"_hs)); + ASSERT_EQ(type.prop("int"_hs).value().cast(), 0); ASSERT_EQ(type.prop("double"_hs).value().cast(), 3.); } diff --git a/test/entt/meta/meta_type.cpp b/test/entt/meta/meta_type.cpp index 769a8acae..20c6db618 100644 --- a/test/entt/meta/meta_type.cpp +++ b/test/entt/meta/meta_type.cpp @@ -100,7 +100,7 @@ struct overloaded_func_t { inline static int value = 0; }; -enum class property_t { +enum class property_t : entt::id_type { random, value, key_only, @@ -150,18 +150,24 @@ struct MetaType: ::testing::Test { entt::meta() .type("property"_hs) .data("random"_hs) - .props(std::make_pair(property_t::random, 0), std::make_pair(property_t::value, 3)) + .prop(static_cast(property_t::random), 0) + .prop(static_cast(property_t::value), 3) .data("value"_hs) - .props(std::make_pair(property_t::random, true), std::make_pair(property_t::value, 0), property_t::key_only, property_t::list) + .prop(static_cast(property_t::random), true) + .prop(static_cast(property_t::value), 0) + .prop(static_cast(property_t::key_only)) + .prop(static_cast(property_t::list)) .data("key_only"_hs) - .prop(property_t::key_only) + .prop(static_cast(property_t::key_only)) .data("list"_hs) - .props(std::make_pair(property_t::random, false), std::make_pair(property_t::value, 0), property_t::key_only) + .prop(static_cast(property_t::random), false) + .prop(static_cast(property_t::value), 0) + .prop(static_cast(property_t::key_only)) .data, get>("var"_hs); entt::meta() .type("clazz"_hs) - .prop(property_t::value, 42) + .prop(static_cast(property_t::value), 42) .ctor() .data<&clazz_t::value>("value"_hs) .func<&clazz_t::member>("member"_hs) @@ -210,17 +216,16 @@ TEST_F(MetaType, Functionalities) { ASSERT_EQ(type.info(), entt::type_id()); for(auto curr: type.prop()) { - ASSERT_EQ(curr.key(), property_t::value); - ASSERT_EQ(curr.value(), 42); + ASSERT_EQ(curr.first, static_cast(property_t::value)); + ASSERT_EQ(curr.second.value(), 42); } - ASSERT_FALSE(type.prop(property_t::key_only)); + ASSERT_FALSE(type.prop(static_cast(property_t::key_only))); ASSERT_FALSE(type.prop("property"_hs)); - auto prop = type.prop(property_t::value); + auto prop = type.prop(static_cast(property_t::value)); ASSERT_TRUE(prop); - ASSERT_EQ(prop.key(), property_t::value); ASSERT_EQ(prop.value(), 42); } @@ -498,7 +503,7 @@ TEST_F(MetaType, Reset) { ASSERT_TRUE(entt::resolve("clazz"_hs)); ASSERT_EQ(entt::resolve().id(), "clazz"_hs); - ASSERT_TRUE(entt::resolve().prop(property_t::value)); + ASSERT_TRUE(entt::resolve().prop(static_cast(property_t::value))); ASSERT_TRUE(entt::resolve().data("value"_hs)); ASSERT_TRUE((entt::resolve().construct(derived_t{}, clazz_t{}))); // implicitly generated default constructor @@ -508,7 +513,7 @@ TEST_F(MetaType, Reset) { ASSERT_FALSE(entt::resolve("clazz"_hs)); ASSERT_NE(entt::resolve().id(), "clazz"_hs); - ASSERT_FALSE(entt::resolve().prop(property_t::value)); + ASSERT_FALSE(entt::resolve().prop(static_cast(property_t::value))); ASSERT_FALSE(entt::resolve().data("value"_hs)); ASSERT_FALSE((entt::resolve().construct(derived_t{}, clazz_t{}))); // implicitly generated default constructor is not cleared @@ -612,21 +617,21 @@ TEST_F(MetaType, PropertiesAndCornerCases) { auto type = entt::resolve(); - ASSERT_EQ(type.data("random"_hs).prop(property_t::random).value().cast(), 0); - ASSERT_EQ(type.data("random"_hs).prop(property_t::value).value().cast(), 3); + ASSERT_EQ(type.data("random"_hs).prop(static_cast(property_t::random)).value().cast(), 0); + ASSERT_EQ(type.data("random"_hs).prop(static_cast(property_t::value)).value().cast(), 3); - ASSERT_EQ(type.data("value"_hs).prop(property_t::random).value().cast(), true); - ASSERT_EQ(type.data("value"_hs).prop(property_t::value).value().cast(), 0); - ASSERT_TRUE(type.data("value"_hs).prop(property_t::key_only)); - ASSERT_FALSE(type.data("value"_hs).prop(property_t::key_only).value()); + ASSERT_EQ(type.data("value"_hs).prop(static_cast(property_t::random)).value().cast(), true); + ASSERT_EQ(type.data("value"_hs).prop(static_cast(property_t::value)).value().cast(), 0); + ASSERT_TRUE(type.data("value"_hs).prop(static_cast(property_t::key_only))); + ASSERT_FALSE(type.data("value"_hs).prop(static_cast(property_t::key_only)).value()); - ASSERT_TRUE(type.data("key_only"_hs).prop(property_t::key_only)); - ASSERT_FALSE(type.data("key_only"_hs).prop(property_t::key_only).value()); + ASSERT_TRUE(type.data("key_only"_hs).prop(static_cast(property_t::key_only))); + ASSERT_FALSE(type.data("key_only"_hs).prop(static_cast(property_t::key_only)).value()); - ASSERT_EQ(type.data("list"_hs).prop(property_t::random).value().cast(), false); - ASSERT_EQ(type.data("list"_hs).prop(property_t::value).value().cast(), 0); - ASSERT_TRUE(type.data("list"_hs).prop(property_t::key_only)); - ASSERT_FALSE(type.data("list"_hs).prop(property_t::key_only).value()); + ASSERT_EQ(type.data("list"_hs).prop(static_cast(property_t::random)).value().cast(), false); + ASSERT_EQ(type.data("list"_hs).prop(static_cast(property_t::value)).value().cast(), 0); + ASSERT_TRUE(type.data("list"_hs).prop(static_cast(property_t::key_only))); + ASSERT_FALSE(type.data("list"_hs).prop(static_cast(property_t::key_only)).value()); } TEST_F(MetaType, ResetAndReRegistrationAfterReset) { @@ -651,7 +656,7 @@ TEST_F(MetaType, ResetAndReRegistrationAfterReset) { ASSERT_EQ(*entt::internal::meta_context::global(), nullptr); - ASSERT_FALSE(entt::resolve().prop(property_t::value)); + ASSERT_FALSE(entt::resolve().prop(static_cast(property_t::value))); // implicitly generated default constructor is not cleared ASSERT_TRUE(entt::resolve().construct()); ASSERT_FALSE(entt::resolve().data("value"_hs)); @@ -670,10 +675,11 @@ TEST_F(MetaType, ResetAndReRegistrationAfterReset) { entt::meta() .type("property"_hs) .data("rand"_hs) - .props(std::make_pair(property_t::value, 42), std::make_pair(property_t::random, 3)); + .prop(static_cast(property_t::value), 42) + .prop(static_cast(property_t::random), 3); - ASSERT_TRUE(entt::resolve().data("rand"_hs).prop(property_t::value)); - ASSERT_TRUE(entt::resolve().data("rand"_hs).prop(property_t::random)); + ASSERT_TRUE(entt::resolve().data("rand"_hs).prop(static_cast(property_t::value))); + ASSERT_TRUE(entt::resolve().data("rand"_hs).prop(static_cast(property_t::random))); } TEST_F(MetaType, ReRegistration) {