Browse Source

meta: make meta_any::assign work with mutating this pointers

Michele Caini 4 years ago
parent
commit
9afde31f97
2 changed files with 31 additions and 17 deletions
  1. 5 17
      src/entt/meta/meta.hpp
  2. 26 0
      test/entt/meta/meta_base.cpp

+ 5 - 17
src/entt/meta/meta.hpp

@@ -1424,28 +1424,16 @@ bool meta_any::set(const id_type id, Type &&value) {
 }
 
 inline bool meta_any::assign(const meta_any &other) {
-    if(const auto value = other.allow_cast(node); value) {
-        if(*value.node->info == *node->info) {
-            return storage.assign(value.storage);
-        } else if(auto *base = internal::find_by<&internal::meta_type_node::base>(*node->info, value.node); base) {
-            const auto as_const_base = base->cast(as_ref());
-            return storage.assign(as_const_base.storage);
-        }
-    }
-
-    return false;
+    auto value = other.allow_cast(node);
+    return value && storage.assign(std::move(value.storage));
 }
 
 inline bool meta_any::assign(meta_any &&other) {
-    if(other.allow_cast(node)) {
-        if(*other.node->info == *node->info) {
-            return storage.assign(std::move(other.storage));
-        } else if(auto *base = internal::find_by<&internal::meta_type_node::base>(*node->info, other.node); base) {
-            return storage.assign(base->cast(other.as_ref()).storage);
-        }
+    if(*node->info == *other.node->info) {
+        return storage.assign(std::move(other.storage));
     }
 
-    return false;
+    return assign(std::as_const(other));
 }
 
 [[nodiscard]] inline meta_type meta_data::type() const ENTT_NOEXCEPT {

+ 26 - 0
test/entt/meta/meta_base.cpp

@@ -150,6 +150,32 @@ TEST_F(MetaBase, OpaqueConvWithMutatingThis) {
     ASSERT_EQ(as_cref.cast<int>(), 42);
 }
 
+TEST_F(MetaBase, AssignWithMutatingThis) {
+    using namespace entt::literals;
+
+    entt::meta_any dst{base_2_t{}};
+    entt::meta_any src{derived_t{}};
+
+    dst.cast<base_2_t &>().value_2 = 0;
+    src.cast<derived_t &>().value_2 = 42;
+
+    ASSERT_TRUE(dst.assign(src));
+    ASSERT_EQ(dst.get("value_2"_hs).cast<int>(), 42);
+}
+
+TEST_F(MetaBase, TransferWithMutatingThis) {
+    using namespace entt::literals;
+
+    entt::meta_any dst{base_2_t{}};
+    entt::meta_any src{derived_t{}};
+
+    dst.cast<base_2_t &>().value_2 = 0;
+    src.cast<derived_t &>().value_2 = 42;
+
+    ASSERT_TRUE(dst.assign(std::move(src)));
+    ASSERT_EQ(dst.get("value_2"_hs).cast<int>(), 42);
+}
+
 TEST_F(MetaBase, ReRegistration) {
     SetUp();