diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index f48d383d4..b0c3899c6 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -127,6 +127,7 @@ struct meta_type_node { size_type(* const extent)(size_type); meta_type_node *(* const remove_pointer)() ENTT_NOEXCEPT; meta_type_node *(* const remove_extent)() ENTT_NOEXCEPT; + meta_ctor_node *def_ctor{nullptr}; meta_ctor_node *ctor{nullptr}; meta_base_node *base{nullptr}; meta_conv_node *conv{nullptr}; @@ -157,10 +158,6 @@ auto meta_visit(const Op &op, const Node *node) } -template -meta_ctor_node * meta_default_constructor(meta_type_node *); - - template class ENTT_API meta_node { static_assert(std::is_same_v>>, "Invalid type"); @@ -172,8 +169,25 @@ class ENTT_API meta_node { return ext; } + [[nodiscard]] static meta_ctor_node * meta_default_constructor(meta_type_node *type) { + if constexpr(std::is_default_constructible_v) { + static internal::meta_ctor_node node{ + type, + nullptr, + nullptr, + 0u, + [](typename meta_ctor_node::size_type) ENTT_NOEXCEPT -> meta_type_node * { return nullptr; }, + [](meta_any * const) { return meta_any{std::in_place_type}; } + }; + + return &node; + } else { + return nullptr; + } + } + public: - [[nodiscard]] static internal::meta_type_node * resolve() ENTT_NOEXCEPT { + [[nodiscard]] static internal::meta_type_node * resolve() ENTT_NOEXCEPT { static meta_type_node node{ type_id(), {}, @@ -198,7 +212,8 @@ public: [](meta_type_node::size_type dim) { return extent(dim, std::make_index_sequence>{}); }, &meta_node>>::resolve, &meta_node>>::resolve, - meta_default_constructor(&node) + meta_default_constructor(&node), + meta_default_constructor(&node) }; return &node; @@ -1657,6 +1672,7 @@ public: unregister_all(&node->func, &internal::meta_func_node::prop); node->id = {}; + node->ctor = node->def_ctor; node->dtor = nullptr; } @@ -2288,31 +2304,6 @@ inline bool meta_associative_container::erase(meta_any key) { } -namespace internal { - - -template -meta_ctor_node * meta_default_constructor(meta_type_node *type) { - if constexpr(std::is_default_constructible_v) { - static internal::meta_ctor_node node{ - type, - nullptr, - nullptr, - 0u, - [](typename meta_ctor::size_type) ENTT_NOEXCEPT -> meta_type_node * { return nullptr; }, - [](meta_any * const) { return meta_any{std::in_place_type}; } - }; - - return &node; - } else { - return nullptr; - } -} - - -} - - } diff --git a/test/entt/meta/meta_type.cpp b/test/entt/meta/meta_type.cpp index 2b0750fb4..f129f1206 100644 --- a/test/entt/meta/meta_type.cpp +++ b/test/entt/meta/meta_type.cpp @@ -438,6 +438,12 @@ TEST_F(MetaType, Reset) { using namespace entt::literals; 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().data("value"_hs)); + ASSERT_TRUE((entt::resolve().ctor())); + // implicitly generated default constructor + ASSERT_TRUE(entt::resolve().ctor<>()); entt::resolve("clazz"_hs).reset(); @@ -445,10 +451,15 @@ TEST_F(MetaType, Reset) { ASSERT_NE(entt::resolve().id(), "clazz"_hs); ASSERT_FALSE(entt::resolve().prop(property_t::value)); ASSERT_FALSE(entt::resolve().data("value"_hs)); + ASSERT_FALSE((entt::resolve().ctor())); + // the implicitly generated default constructor is there after a reset + ASSERT_TRUE(entt::resolve().ctor<>()); entt::meta().type("clazz"_hs); ASSERT_TRUE(entt::resolve("clazz"_hs)); + // the implicitly generated default constructor must be there in any case + ASSERT_TRUE(entt::resolve().ctor<>()); } TEST_F(MetaType, AbstractClass) { @@ -566,7 +577,8 @@ TEST_F(MetaType, ResetAndReRegistrationAfterReset) { ASSERT_EQ(*entt::internal::meta_context::global(), nullptr); ASSERT_FALSE(entt::resolve().prop(property_t::value)); - ASSERT_FALSE(entt::resolve().ctor<>()); + // the implicitly generated default constructor is there after a reset + ASSERT_TRUE(entt::resolve().ctor<>()); ASSERT_FALSE(entt::resolve().data("value"_hs)); ASSERT_FALSE(entt::resolve().func("member"_hs));