Explorar o código

meta: fixed an issue with meta_factory::conv when used with member functions + code coverage

Michele Caini %!s(int64=4) %!d(string=hai) anos
pai
achega
97500dff57
Modificáronse 2 ficheiros con 29 adicións e 24 borrados
  1. 18 22
      src/entt/meta/factory.hpp
  2. 11 2
      test/entt/meta/meta_conv.cpp

+ 18 - 22
src/entt/meta/factory.hpp

@@ -266,33 +266,29 @@ public:
      * @return A meta factory for the parent type.
      */
     template<auto Candidate>
-    std::enable_if_t<std::is_member_function_pointer_v<decltype(Candidate)>, meta_factory<Type>> conv() ENTT_NOEXCEPT {
+    auto conv() ENTT_NOEXCEPT {
         using conv_type = std::remove_const_t<std::remove_reference_t<std::invoke_result_t<decltype(Candidate), Type &>>>;
 
-        static internal::meta_conv_node node{
-            nullptr,
-            internal::meta_node<conv_type>::resolve(),
-            [](const meta_any &instance) -> meta_any { return forward_as_meta(static_cast<const Type *>(instance.data())->*Candidate)(); }
-            // tricks clang-format
-        };
-
-        link_conv_if_required(node);
-        return meta_factory<Type>{};
-    }
+        if constexpr(std::is_member_function_pointer_v<decltype(Candidate)>) {
+            static internal::meta_conv_node node{
+                nullptr,
+                internal::meta_node<conv_type>::resolve(),
+                [](const meta_any &instance) -> meta_any { return forward_as_meta((static_cast<const Type *>(instance.data())->*Candidate)()); }
+                // tricks clang-format
+            };
 
-    /*! @copydoc conv */
-    template<auto Candidate>
-    std::enable_if_t<!std::is_member_function_pointer_v<decltype(Candidate)>, meta_factory<Type>> conv() ENTT_NOEXCEPT {
-        using conv_type = std::remove_const_t<std::remove_reference_t<std::invoke_result_t<decltype(Candidate), Type &>>>;
+            link_conv_if_required(node);
+        } else {
+            static internal::meta_conv_node node{
+                nullptr,
+                internal::meta_node<conv_type>::resolve(),
+                [](const meta_any &instance) -> meta_any { return forward_as_meta(Candidate(*static_cast<const Type *>(instance.data()))); }
+                // tricks clang-format
+            };
 
-        static internal::meta_conv_node node{
-            nullptr,
-            internal::meta_node<conv_type>::resolve(),
-            [](const meta_any &instance) -> meta_any { return forward_as_meta(Candidate(*static_cast<const Type *>(instance.data()))); }
-            // tricks clang-format
-        };
+            link_conv_if_required(node);
+        }
 
-        link_conv_if_required(node);
         return meta_factory<Type>{};
     }
 

+ 11 - 2
test/entt/meta/meta_conv.cpp

@@ -12,6 +12,10 @@ struct clazz_t {
         return value;
     }
 
+    bool to_bool() const {
+        return (value != 0);
+    }
+
     int value;
 };
 
@@ -26,6 +30,7 @@ struct MetaConv: ::testing::Test {
         entt::meta<clazz_t>()
             .type("clazz"_hs)
             .conv<int>()
+            .conv<&clazz_t::to_bool>()
             .conv<conv_to_double>();
     }
 
@@ -39,14 +44,17 @@ TEST_F(MetaConv, Functionalities) {
     any.cast<clazz_t &>().value = 42;
 
     const auto as_int = std::as_const(any).allow_cast<int>();
+    const auto as_bool = std::as_const(any).allow_cast<bool>();
     const auto as_double = std::as_const(any).allow_cast<double>();
 
     ASSERT_FALSE(any.allow_cast<char>());
 
     ASSERT_TRUE(as_int);
+    ASSERT_TRUE(as_bool);
     ASSERT_TRUE(as_double);
 
-    ASSERT_EQ(as_int.cast<int>(), any.cast<clazz_t &>().value);
+    ASSERT_EQ(as_int.cast<int>(), any.cast<clazz_t &>().operator int());
+    ASSERT_EQ(as_bool.cast<bool>(), any.cast<clazz_t &>().to_bool());
     ASSERT_EQ(as_double.cast<double>(), conv_to_double(any.cast<clazz_t &>()));
 }
 
@@ -57,5 +65,6 @@ TEST_F(MetaConv, ReRegistration) {
 
     ASSERT_NE(node->conv, nullptr);
     ASSERT_NE(node->conv->next, nullptr);
-    ASSERT_EQ(node->conv->next->next, nullptr);
+    ASSERT_NE(node->conv->next->next, nullptr);
+    ASSERT_EQ(node->conv->next->next->next, nullptr);
 }