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

meta: support meta member functions on primitive types

Michele Caini 3 лет назад
Родитель
Сommit
3ef61fe014
2 измененных файлов с 38 добавлено и 3 удалено
  1. 6 3
      src/entt/meta/utility.hpp
  2. 32 0
      test/entt/meta/meta_func.cpp

+ 6 - 3
src/entt/meta/utility.hpp

@@ -92,9 +92,12 @@ template<typename Type, typename Ret, typename MaybeType, typename... Args>
 struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)>
     : meta_function_descriptor_traits<
           Ret,
-          std::conditional_t<std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>, type_list<Args...>, type_list<MaybeType, Args...>>,
-          !std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>,
-          std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> && std::is_const_v<std::remove_reference_t<MaybeType>>> {};
+          std::conditional_t<
+              std::is_same_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>,
+              type_list<Args...>,
+              type_list<MaybeType, Args...>>,
+          !(std::is_same_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>),
+          std::is_const_v<std::remove_reference_t<MaybeType>> && (std::is_same_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_cv_t<std::remove_reference_t<MaybeType>>, Type>)> {};
 
 /**
  * @brief Meta function descriptor.

+ 32 - 0
test/entt/meta/meta_func.cpp

@@ -87,10 +87,18 @@ struct func_t {
     inline static int value = 0;
 };
 
+double double_member(const double &value) {
+    return value * value;
+}
+
 struct MetaFunc: ::testing::Test {
     void SetUp() override {
         using namespace entt::literals;
 
+        entt::meta<double>()
+            .type("double"_hs)
+            .func<&double_member>("member"_hs);
+
         entt::meta<base_t>()
             .type("base"_hs)
             .dtor<base_t::destroy>()
@@ -381,6 +389,30 @@ TEST_F(MetaFunc, StaticAsConstMember) {
     ASSERT_EQ(any.cast<int>(), 3);
 }
 
+TEST_F(MetaFunc, NonClassTypeMember) {
+    using namespace entt::literals;
+
+    double instance = 3.;
+    auto func = entt::resolve<double>().func("member"_hs);
+    auto any = func.invoke(instance);
+
+    ASSERT_TRUE(func);
+    ASSERT_EQ(func.arity(), 0u);
+    ASSERT_TRUE(func.is_const());
+    ASSERT_FALSE(func.is_static());
+    ASSERT_EQ(func.ret(), entt::resolve<double>());
+    ASSERT_FALSE(func.arg(0u));
+
+    ASSERT_EQ(func.prop().cbegin(), func.prop().cend());
+
+    ASSERT_FALSE(func.invoke({}));
+    ASSERT_TRUE(func.invoke(instance));
+
+    ASSERT_TRUE(any);
+    ASSERT_EQ(any.type(), entt::resolve<double>());
+    ASSERT_EQ(any.cast<double>(), instance * instance);
+}
+
 TEST_F(MetaFunc, MetaAnyArgs) {
     using namespace entt::literals;