Kaynağa Gözat

meta: reduce cost of meta conv

Michele Caini 1 yıl önce
ebeveyn
işleme
9c6780c0a3
3 değiştirilmiş dosya ile 22 ekleme ve 6 silme
  1. 3 1
      src/entt/meta/factory.hpp
  2. 14 2
      src/entt/meta/meta.hpp
  3. 5 3
      src/entt/meta/node.hpp

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

@@ -61,7 +61,9 @@ protected:
         if constexpr(std::is_same_v<Type, meta_base_node>) {
             details->base.insert_or_assign(node.id, node);
         } else if constexpr(std::is_same_v<Type, meta_conv_node>) {
-            details->conv.insert_or_assign(node.type, node);
+            std::size_t pos{};
+            for(const std::size_t last = details->conv.size(); (pos != last) && (details->conv[pos].type != node.type); ++pos) {}
+            (pos == details->conv.size()) ? details->conv.emplace_back(node) : (details->conv[pos] = node);
         } else {
             static_assert(std::is_same_v<Type, meta_ctor_node>, "Unexpected type");
             std::size_t pos{};

+ 14 - 2
src/entt/meta/meta.hpp

@@ -1165,8 +1165,20 @@ class meta_type {
 
                     if(const auto &info = other.info(); info == type.info()) {
                         ++match;
-                    } else if(!((type.node.details && (type.node.details->base.contains(info.hash()) || type.node.details->conv.contains(info.hash()))) || (type.node.conversion_helper && other.node.conversion_helper))) {
-                        break;
+                    } else {
+                        bool can_continue = type.node.conversion_helper && other.node.conversion_helper;
+
+                        if(!can_continue && type.node.details) {
+                            can_continue = type.node.details->base.contains(info.hash());
+
+                            for(std::size_t idx{}, last = type.node.details->conv.size(); !can_continue && idx != last; ++idx) {
+                                can_continue = (type.node.details->conv[idx].type == info.hash());
+                            }
+                        }
+
+                        if(!can_continue) {
+                            break;
+                        }
                     }
                 }
                 // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)

+ 5 - 3
src/entt/meta/node.hpp

@@ -137,7 +137,7 @@ struct meta_template_node {
 struct meta_type_descriptor {
     std::vector<meta_ctor_node> ctor{};
     dense_map<id_type, meta_base_node, identity> base{};
-    dense_map<id_type, meta_conv_node, identity> conv{};
+    std::vector<meta_conv_node> conv{};
     dense_map<id_type, meta_data_node, identity> data{};
     dense_map<id_type, meta_func_node, identity> func{};
     dense_map<id_type, meta_prop_node, identity> prop{};
@@ -213,8 +213,10 @@ template<typename Func>
     }
 
     if(from.details) {
-        if(auto it = from.details->conv.find(to.hash()); it != from.details->conv.cend()) {
-            return func(instance, it->second);
+        for(auto &&elem: from.details->conv) {
+            if(elem.type == to.hash()) {
+                return func(instance, elem);
+            }
         }
 
         for(auto &&curr: from.details->base) {