Przeglądaj źródła

meta: meta_any support for non-copyable types (close #336)

Michele Caini 6 lat temu
rodzic
commit
f17b975fb9
2 zmienionych plików z 31 dodań i 6 usunięć
  1. 1 6
      src/entt/meta/meta.hpp
  2. 30 0
      test/entt/meta/meta.cpp

+ 1 - 6
src/entt/meta/meta.hpp

@@ -262,11 +262,6 @@ private:
  *
  * This class uses a technique called small buffer optimization (SBO) to get rid
  * of memory allocations if possible. This should improve overall performance.
- *
- * @warning
- * Only copy constructible types are suitable for use with this class.<br/>
- * A static assertion will abort the compilation when the type isn't copy
- * constructible.
  */
 class meta_any {
     using storage_type = std::aligned_storage_t<sizeof(void *), alignof(void *)>;
@@ -513,7 +508,7 @@ public:
         meta_any any{};
 
         if(const auto id = internal::meta_info<Type>::resolve()->id; node && node->id == id) {
-            any = *static_cast<const Type *>(instance);
+            any = *this;
         } else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([id](const auto *curr) { return curr->type()->id == id; }, node); conv) {
             any = conv->conv(instance);
         }

+ 30 - 0
test/entt/meta/meta.cpp

@@ -123,6 +123,14 @@ struct not_comparable_type {
     bool operator==(const not_comparable_type &) const = delete;
 };
 
+struct unmanageable_type {
+    unmanageable_type() = default;
+    unmanageable_type(const unmanageable_type &) = delete;
+    unmanageable_type(unmanageable_type &&) = delete;
+    unmanageable_type & operator=(const unmanageable_type &) = delete;
+    unmanageable_type & operator=(unmanageable_type &&) = delete;
+};
+
 bool operator!=(const not_comparable_type &, const not_comparable_type &) = delete;
 
 struct an_abstract_type {
@@ -885,6 +893,28 @@ TEST_F(Meta, MetaAnyConstConvert) {
     ASSERT_EQ(other.cast<int>(), 42);
 }
 
+TEST_F(Meta, MetaAnyUnmanageableType) {
+    unmanageable_type instance;
+    entt::meta_any any{std::ref(instance)};
+    entt::meta_any other = any;
+
+    std::swap(any, other);
+
+    ASSERT_TRUE(any);
+    ASSERT_TRUE(other);
+
+    ASSERT_EQ(any.type(), entt::resolve<unmanageable_type>());
+    ASSERT_NE(any.data(), nullptr);
+    ASSERT_EQ(any.try_cast<int>(), nullptr);
+    ASSERT_NE(any.try_cast<unmanageable_type>(), nullptr);
+
+    ASSERT_TRUE(any.convert<unmanageable_type>());
+    ASSERT_FALSE(any.convert<int>());
+
+    ASSERT_TRUE(std::as_const(any).convert<unmanageable_type>());
+    ASSERT_FALSE(std::as_const(any).convert<int>());
+}
+
 TEST_F(Meta, MetaProp) {
     auto prop = entt::resolve<char>().prop(props::prop_int);