Kaynağa Gözat

meta: added support for convertible types to meta containers ::insert functions

Michele Caini 5 yıl önce
ebeveyn
işleme
5d42a76fe5
3 değiştirilmiş dosya ile 29 ekleme ve 18 silme
  1. 1 2
      TODO
  2. 11 7
      src/entt/meta/meta.hpp
  3. 17 9
      test/entt/meta/meta_container.cpp

+ 1 - 2
TODO

@@ -26,5 +26,4 @@ Next:
 
 * WIP:
  - remove internal::find_if
- - add const meta container support to meta any
- - review _t
+ - add cast_or_convert to meta_any, clean up codebase

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

@@ -1619,11 +1619,12 @@ struct meta_sequence_container::meta_sequence_container_proxy {
         return iterator{std::in_place_type<Type>, meta_sequence_container_traits<Type>::end(*static_cast<Type *>(container))};
     }
 
-    [[nodiscard]] static std::pair<iterator, bool> insert(void *container, iterator it, meta_any any) {
+    [[nodiscard]] static std::pair<iterator, bool> insert(void *container, iterator it, meta_any value) {
+        using v_type = typename meta_sequence_container_traits<Type>::value_type;
         std::pair<typename meta_sequence_container_traits<Type>::iterator, bool> ret{{}, false};
 
-        if(const auto *value = any.try_cast<typename meta_sequence_container_traits<Type>::value_type>(); value) {
-            ret = meta_sequence_container_traits<Type>::insert(*static_cast<Type *>(container), it.handle.cast<typename meta_sequence_container_traits<Type>::iterator>(), *value);
+        if(const auto *v_ptr = value.try_cast<v_type>(); v_ptr || value.convert<v_type>()) {
+            ret = meta_sequence_container_traits<Type>::insert(*static_cast<Type *>(container), it.handle.cast<typename meta_sequence_container_traits<Type>::iterator>(), v_ptr ? *v_ptr : value.cast<v_type>());
         }
 
         return {iterator{std::in_place_type<Type>, std::move(ret.first)}, ret.second};
@@ -1928,14 +1929,17 @@ struct meta_associative_container::meta_associative_container_proxy {
     }
 
     [[nodiscard]] static bool insert(void *container, meta_any key, meta_any value) {
+        using k_type = typename meta_associative_container_traits<Type>::key_type;
         bool ret = false;
 
-        if(const auto *k_ptr = key.try_cast<typename meta_associative_container_traits<Type>::key_type>(); k_ptr) {
+        if(const auto *k_ptr = key.try_cast<k_type>(); k_ptr || key.convert<k_type>()) {
             if constexpr(is_key_only_meta_associative_container_v<Type>) {
-                ret = meta_associative_container_traits<Type>::insert(*static_cast<Type *>(container), *k_ptr);
+                ret = meta_associative_container_traits<Type>::insert(*static_cast<Type *>(container), k_ptr ? *k_ptr : key.cast<k_type>());
             } else {
-                if(auto *m_ptr = value.try_cast<typename meta_associative_container_traits<Type>::mapped_type>(); m_ptr) {
-                    ret = meta_associative_container_traits<Type>::insert(*static_cast<Type *>(container), *k_ptr, *m_ptr);
+                using m_type = typename meta_associative_container_traits<Type>::mapped_type;
+
+                if(auto *m_ptr = value.try_cast<m_type>(); m_ptr || value.convert<m_type>()) {
+                    ret = meta_associative_container_traits<Type>::insert(*static_cast<Type *>(container), k_ptr ? *k_ptr : key.cast<k_type>(), m_ptr ? *m_ptr : value.cast<m_type>());
                 }
             }
         }

+ 17 - 9
test/entt/meta/meta_container.cpp

@@ -1,10 +1,18 @@
 #include <gtest/gtest.h>
 #include <entt/core/hashed_string.hpp>
 #include <entt/meta/container.hpp>
+#include <entt/meta/factory.hpp>
 #include <entt/meta/meta.hpp>
 #include <entt/meta/resolve.hpp>
 
-TEST(MetaSequenceContainer, Empty) {
+struct MetaContainer: ::testing::Test {
+    static void SetUpTestCase() {
+        entt::meta<double>().conv<int>();
+        entt::meta<int>().conv<char>();
+    }
+};
+
+TEST_F(MetaContainer, EmptySequenceContainer) {
     entt::meta_sequence_container container{};
 
     ASSERT_FALSE(container);
@@ -15,7 +23,7 @@ TEST(MetaSequenceContainer, Empty) {
     ASSERT_TRUE(container);
 }
 
-TEST(MetaSequenceContainer, StdVector) {
+TEST_F(MetaContainer, StdVector) {
     std::vector<int> vec{};
     entt::meta_any any{std::ref(vec)};
 
@@ -54,7 +62,7 @@ TEST(MetaSequenceContainer, StdVector) {
 
     ASSERT_TRUE(ret.second);
     ASSERT_FALSE(view.insert(ret.first, 'c').second);
-    ASSERT_TRUE(view.insert(++ret.first, 1).second);
+    ASSERT_TRUE(view.insert(++ret.first, 1.).second);
 
     ASSERT_EQ(view.size(), 5u);
     ASSERT_EQ((*view.begin()).cast<int>(), 0);
@@ -71,7 +79,7 @@ TEST(MetaSequenceContainer, StdVector) {
     ASSERT_EQ(view.size(), 0u);
 }
 
-TEST(MetaSequenceContainer, StdArray) {
+TEST_F(MetaContainer, StdArray) {
     std::array<int, 3> arr{};
     entt::meta_any any{std::ref(arr)};
 
@@ -127,7 +135,7 @@ TEST(MetaSequenceContainer, StdArray) {
     ASSERT_EQ(view.size(), 3u);
 }
 
-TEST(MetaAssociativeContainer, Empty) {
+TEST_F(MetaContainer, EmptyAssociativeContainer) {
     entt::meta_associative_container container{};
 
     ASSERT_FALSE(container);
@@ -138,7 +146,7 @@ TEST(MetaAssociativeContainer, Empty) {
     ASSERT_TRUE(container);
 }
 
-TEST(MetaAssociativeContainer, StdMap) {
+TEST_F(MetaContainer, StdMap) {
     std::map<int, char> map{{2, 'c'}, {3, 'd'}, {4, 'e'}};
     entt::meta_any any{std::ref(map)};
 
@@ -169,10 +177,10 @@ TEST(MetaAssociativeContainer, StdMap) {
     ASSERT_EQ((*view.find(3)).second.cast<char>(), 'd');
 
     ASSERT_FALSE(view.insert('a', 'a'));
-    ASSERT_FALSE(view.insert(1, 1));
+    ASSERT_FALSE(view.insert(1, 1.));
 
     ASSERT_TRUE(view.insert(0, 'a'));
-    ASSERT_TRUE(view.insert(1, 'b'));
+    ASSERT_TRUE(view.insert(1., static_cast<int>('b')));
 
     ASSERT_EQ(view.size(), 5u);
     ASSERT_EQ((*view.find(0)).second.cast<char>(), 'a');
@@ -190,7 +198,7 @@ TEST(MetaAssociativeContainer, StdMap) {
     ASSERT_EQ(view.size(), 0u);
 }
 
-TEST(MetaAssociativeContainer, StdSet) {
+TEST_F(MetaContainer, StdSet) {
     std::set<int> set{2, 3, 4};
     entt::meta_any any{std::ref(set)};