Browse Source

meta: ::reset doesn't remove the implicitly generated default constructors

Michele Caini 5 years ago
parent
commit
fad3bdeed4
2 changed files with 35 additions and 32 deletions
  1. 22 31
      src/entt/meta/meta.hpp
  2. 13 1
      test/entt/meta/meta_type.cpp

+ 22 - 31
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<typename Type>
-meta_ctor_node * meta_default_constructor(meta_type_node *);
-
-
 template<typename Type>
 class ENTT_API meta_node {
     static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>, "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<Type>) {
+            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<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<Type>(),
             {},
@@ -198,7 +212,8 @@ public:
             [](meta_type_node::size_type dim) { return extent(dim, std::make_index_sequence<std::rank_v<Type>>{}); },
             &meta_node<std::remove_cv_t<std::remove_pointer_t<Type>>>::resolve,
             &meta_node<std::remove_cv_t<std::remove_extent_t<Type>>>::resolve,
-            meta_default_constructor<Type>(&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<typename Type>
-meta_ctor_node * meta_default_constructor(meta_type_node *type) {
-    if constexpr(std::is_default_constructible_v<Type>) {
-        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<Type>}; }
-        };
-
-        return &node;
-    } else {
-        return nullptr;
-    }
-}
-
-
-}
-
-
 }
 
 

+ 13 - 1
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<clazz_t>().id(), "clazz"_hs);
+    ASSERT_TRUE(entt::resolve<clazz_t>().prop(property_t::value));
+    ASSERT_TRUE(entt::resolve<clazz_t>().data("value"_hs));
+    ASSERT_TRUE((entt::resolve<clazz_t>().ctor<const base_t &, int>()));
+    // implicitly generated default constructor
+    ASSERT_TRUE(entt::resolve<clazz_t>().ctor<>());
 
     entt::resolve("clazz"_hs).reset();
 
@@ -445,10 +451,15 @@ TEST_F(MetaType, Reset) {
     ASSERT_NE(entt::resolve<clazz_t>().id(), "clazz"_hs);
     ASSERT_FALSE(entt::resolve<clazz_t>().prop(property_t::value));
     ASSERT_FALSE(entt::resolve<clazz_t>().data("value"_hs));
+    ASSERT_FALSE((entt::resolve<clazz_t>().ctor<const base_t &, int>()));
+    // the implicitly generated default constructor is there after a reset
+    ASSERT_TRUE(entt::resolve<clazz_t>().ctor<>());
 
     entt::meta<clazz_t>().type("clazz"_hs);
 
     ASSERT_TRUE(entt::resolve("clazz"_hs));
+    // the implicitly generated default constructor must be there in any case
+    ASSERT_TRUE(entt::resolve<clazz_t>().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<clazz_t>().prop(property_t::value));
-    ASSERT_FALSE(entt::resolve<clazz_t>().ctor<>());
+    // the implicitly generated default constructor is there after a reset
+    ASSERT_TRUE(entt::resolve<clazz_t>().ctor<>());
     ASSERT_FALSE(entt::resolve<clazz_t>().data("value"_hs));
     ASSERT_FALSE(entt::resolve<clazz_t>().func("member"_hs));