Просмотр исходного кода

meta_any: support for pointer-like types to non-const, non-copyable types (close #556)

Michele Caini 5 лет назад
Родитель
Сommit
a816ccf6ee
3 измененных файлов с 23 добавлено и 4 удалено
  1. 7 3
      src/entt/meta/meta.hpp
  2. 0 1
      test/entt/meta/meta_any.cpp
  3. 16 0
      test/entt/meta/meta_pointer.cpp

+ 7 - 3
src/entt/meta/meta.hpp

@@ -167,10 +167,14 @@ class meta_any {
     template<typename Type>
     [[nodiscard]] static meta_any dereference_operator(meta_any &any) {
         if constexpr(is_meta_pointer_like_v<Type>) {
-            if constexpr(std::is_const_v<std::remove_reference_t<decltype(*std::declval<Type>())>>) {
-                return *any.cast<Type>();
-            } else {
+            using pointed_type = std::remove_reference_t<decltype(*std::declval<Type>())>;
+
+            if constexpr(std::is_const_v<pointed_type> && std::is_copy_constructible_v<pointed_type>) {
+                return std::as_const(*any.cast<Type>());
+            } else if constexpr(!std::is_const_v<pointed_type>) {
                 return std::ref(*any.cast<Type>());
+            } else {
+                return {};
             }
         } else {
             return {};

+ 0 - 1
test/entt/meta/meta_any.cpp

@@ -5,7 +5,6 @@
 #include <entt/meta/meta.hpp>
 #include <entt/meta/resolve.hpp>
 
-
 struct clazz_t {
     void member(int i) { value = i; }
     static void func() { c = 'd'; }

+ 16 - 0
test/entt/meta/meta_pointer.cpp

@@ -4,6 +4,14 @@
 #include <entt/meta/pointer.hpp>
 #include <entt/meta/resolve.hpp>
 
+struct not_copyable_t {
+    not_copyable_t() = default;
+    not_copyable_t(const not_copyable_t &) = delete;
+    not_copyable_t(not_copyable_t &&) = default;
+    not_copyable_t & operator=(const not_copyable_t &) = delete;
+    not_copyable_t & operator=(not_copyable_t &&) = default;
+};
+
 TEST(MetaPointerLike, DereferenceOperatorInvalidType) {
     int value = 0;
     entt::meta_any any{value};
@@ -79,3 +87,11 @@ TEST(MetaPointerLike, DereferenceOperatorSmartPointer) {
     ASSERT_EQ(*any.cast<std::shared_ptr<int>>(), 42);
     ASSERT_EQ(*value, 42);
 }
+
+TEST(MetaPointerLike, PointerToMoveOnlyType) {
+    const not_copyable_t instance;
+    entt::meta_any any{&instance};
+
+    ASSERT_TRUE(any);
+    ASSERT_FALSE(*any);
+}