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

meta: allow attaching const values of non-Type type to meta types

Michele Caini 1 год назад
Родитель
Сommit
65bf5cfe2d
3 измененных файлов с 37 добавлено и 22 удалено
  1. 1 1
      src/entt/meta/factory.hpp
  2. 19 21
      src/entt/meta/utility.hpp
  3. 17 0
      test/entt/meta/meta_data.cpp

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

@@ -353,7 +353,7 @@ public:
             base_type::data(
                 internal::meta_data_node{
                     id,
-                    ((std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<data_type>>> || std::is_const_v<std::remove_reference_t<data_type>>) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static,
+                    ((!std::is_pointer_v<decltype(Data)> || std::is_const_v<data_type>) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static,
                     1u,
                     &internal::resolve<std::remove_cv_t<std::remove_reference_t<data_type>>>,
                     &meta_arg<type_list<std::remove_cv_t<std::remove_reference_t<data_type>>>>,

+ 19 - 21
src/entt/meta/utility.hpp

@@ -224,32 +224,30 @@ template<typename Type>
  */
 template<typename Type, auto Data>
 [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
-    if constexpr(!std::is_same_v<decltype(Data), Type> && !std::is_same_v<decltype(Data), std::nullptr_t>) {
-        if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
-            using descriptor = meta_function_helper_t<Type, decltype(Data)>;
-            using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
+    if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
+        using descriptor = meta_function_helper_t<Type, decltype(Data)>;
+        using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
 
+        if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
+            std::invoke(Data, *clazz, value.cast<data_type>());
+            return true;
+        }
+    } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
+        using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
+
+        if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
             if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
-                std::invoke(Data, *clazz, value.cast<data_type>());
+                std::invoke(Data, *clazz) = value.cast<data_type>();
                 return true;
             }
-        } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
-            using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
-
-            if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
-                if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
-                    std::invoke(Data, *clazz) = value.cast<data_type>();
-                    return true;
-                }
-            }
-        } else {
-            using data_type = std::remove_reference_t<decltype(*Data)>;
+        }
+    } else if constexpr(std::is_pointer_v<decltype(Data)>) {
+        using data_type = std::remove_reference_t<decltype(*Data)>;
 
-            if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
-                if(value.allow_cast<data_type>()) {
-                    *Data = value.cast<data_type>();
-                    return true;
-                }
+        if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
+            if(value.allow_cast<data_type>()) {
+                *Data = value.cast<data_type>();
+                return true;
             }
         }
     }

+ 17 - 0
test/entt/meta/meta_data.cpp

@@ -114,6 +114,7 @@ struct MetaData: ::testing::Test {
             .traits(test::meta_traits::two)
             .data<&clazz::k>("k"_hs)
             .traits(test::meta_traits::three)
+            .data<'c'>("l"_hs)
             .data<&clazz::instance>("base"_hs)
             .data<&clazz::i, entt::as_void_t>("void"_hs)
             .conv<int>();
@@ -278,6 +279,22 @@ TEST_F(MetaData, ConstStatic) {
     ASSERT_EQ(data.get({}).cast<int>(), 3);
 }
 
+TEST_F(MetaData, Literal) {
+    using namespace entt::literals;
+
+    auto data = entt::resolve<clazz>().data("l"_hs);
+
+    ASSERT_TRUE(data);
+    ASSERT_EQ(data.arity(), 1u);
+    ASSERT_EQ(data.type(), entt::resolve<char>());
+    ASSERT_EQ(data.arg(0u), entt::resolve<char>());
+    ASSERT_TRUE(data.is_const());
+    ASSERT_TRUE(data.is_static());
+    ASSERT_EQ(data.get({}).cast<char>(), 'c');
+    ASSERT_FALSE(data.set({}, 'a'));
+    ASSERT_EQ(data.get({}).cast<char>(), 'c');
+}
+
 TEST_F(MetaData, GetMetaAnyArg) {
     using namespace entt::literals;