Переглянути джерело

meta: reduce the size of instantiated symbols in meta_factory

Michele Caini 4 роки тому
батько
коміт
00dadfe14d
1 змінених файлів з 75 додано та 82 видалено
  1. 75 82
      src/entt/meta/factory.hpp

+ 75 - 82
src/entt/meta/factory.hpp

@@ -30,7 +30,7 @@ namespace entt {
  * there are no subtle errors at runtime.
  */
 template<typename...>
-struct meta_factory;
+class meta_factory;
 
 
 /**
@@ -39,8 +39,15 @@ struct meta_factory;
  * @tparam Spec Property specialization pack used to disambiguate overloads.
  */
 template<typename Type, typename... Spec>
-struct meta_factory<Type, Spec...>: public meta_factory<Type> {
-private:
+class meta_factory<Type, Spec...>: public meta_factory<Type> {
+    void link_prop_if_required(internal::meta_prop_node &node, const meta_any &instance) {
+        if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&instance](const auto *curr) { return curr->id == instance; }) == range.cend(), "Duplicate identifier");
+            node.next = *ref;
+            *ref = &node;
+        }
+    }
+
     template<std::size_t Step = 0, typename... Property, typename... Other>
     void unroll(choice_t<2>, std::tuple<Property...> property, Other &&... other) {
         std::apply([this](auto &&... curr) { (unroll<Step>(choice<2>, std::forward<Property>(curr)), ...); }, property);
@@ -62,8 +69,8 @@ private:
     template<std::size_t>
     void unroll(choice_t<0>) {}
 
-    template<std::size_t = 0, typename Key>
-    void assign(Key &&key, meta_any value = {}) {
+    template<std::size_t = 0>
+    void assign(meta_any key, meta_any value = {}) {
         static meta_any property[2u]{};
 
         static internal::meta_prop_node node{
@@ -72,15 +79,9 @@ private:
             property[1u]
         };
 
-        meta_any instance{std::forward<Key>(key)};
-        property[0u] = std::move(instance);
+        property[0u] = std::move(key);
         property[1u] = std::move(value);
-
-        if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*ref}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [&instance](const auto *curr) { return curr->id == instance; }) == range.cend(), "Duplicate identifier");
-            node.next = *ref;
-            *ref = &node;
-        }
+        link_prop_if_required(node, property[0u]);
     }
 
 public:
@@ -139,7 +140,57 @@ private:
  * @tparam Type Reflected type for which the factory was created.
  */
 template<typename Type>
-struct meta_factory<Type> {
+class meta_factory<Type> {
+    void link_base_if_required(internal::meta_base_node &node) {
+        if(meta_range<internal::meta_base_node *, internal::meta_base_node> range{owner->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            node.next = owner->base;
+            owner->base = &node;
+        }
+    }
+
+    void link_conv_if_required(internal::meta_conv_node &node) {
+        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            node.next = owner->conv;
+            owner->conv = &node;
+        }
+    }
+
+    void link_ctor_if_required(internal::meta_ctor_node &node) {
+        if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            node.next = owner->ctor;
+            owner->ctor = &node;
+        }
+    }
+
+    void link_data_if_required(const id_type id, internal::meta_data_node &node) {
+        meta_range<internal::meta_data_node *, internal::meta_data_node> range{owner->data};
+        ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id, &node](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
+        node.id = id;
+
+        if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            node.next = owner->data;
+            owner->data = &node;
+        }
+    }
+
+    void link_func_if_required(const id_type id, internal::meta_func_node &node) {
+        for(auto *it = &owner->func; *it; it = &(*it)->next) {
+            if(*it == &node) {
+                *it = node.next;
+                break;
+            }
+        }
+
+        internal::meta_func_node **it = &owner->func;
+        for(; *it && (*it)->id != id; it = &(*it)->next);
+        for(; *it && (*it)->id == id && (*it)->arity < node.arity; it = &(*it)->next);
+
+        node.id = id;
+        node.next = *it;
+        *it = &node;
+    }
+
+public:
     /*! @brief Default constructor. */
     meta_factory()
         : owner{internal::meta_node<Type>::resolve()}
@@ -183,11 +234,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(meta_range<internal::meta_base_node *, internal::meta_base_node> range{owner->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->base;
-            owner->base = &node;
-        }
-
+        link_base_if_required(node);
         return meta_factory<Type>{};
     }
 
@@ -215,11 +262,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->conv;
-            owner->conv = &node;
-        }
-
+        link_conv_if_required(node);
         return meta_factory<Type>{};
     }
 
@@ -236,11 +279,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->conv;
-            owner->conv = &node;
-        }
-
+        link_conv_if_required(node);
         return meta_factory<Type>{};
     }
 
@@ -265,11 +304,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{owner->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->conv;
-            owner->conv = &node;
-        }
-
+        link_conv_if_required(node);
         return meta_factory<Type>{};
     }
 
@@ -299,11 +334,7 @@ struct meta_factory<Type> {
             &meta_construct<Type, Candidate, Policy>
         };
 
-        if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->ctor;
-            owner->ctor = &node;
-        }
-
+        link_ctor_if_required(node);
         return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
     }
 
@@ -329,11 +360,7 @@ struct meta_factory<Type> {
             &meta_construct<Type, Args...>
         };
 
-        if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{owner->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->ctor;
-            owner->ctor = &node;
-        }
-
+        link_ctor_if_required(node);
         return meta_factory<Type, Type(Args...)>{&node.prop};
     }
 
@@ -356,11 +383,7 @@ struct meta_factory<Type> {
     template<auto Func>
     auto dtor() ENTT_NOEXCEPT {
         static_assert(std::is_invocable_v<decltype(Func), Type &>, "The function doesn't accept an object of the type provided");
-
-        owner->dtor = [](void *instance) {
-            Func(*static_cast<Type *>(instance));
-        };
-
+        owner->dtor = [](void *instance) { Func(*static_cast<Type *>(instance)); };
         return meta_factory<Type>{};
     }
 
@@ -396,15 +419,7 @@ struct meta_factory<Type> {
                 &meta_getter<Type, Data, Policy>
             };
 
-            meta_range<internal::meta_data_node *, internal::meta_data_node> range{owner->data};
-            ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
-            node.id = id;
-
-            if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-                node.next = owner->data;
-                owner->data = &node;
-            }
-
+            link_data_if_required(id, node);
             return meta_factory<Type, std::integral_constant<decltype(Data), Data>>{&node.prop};
         }
     }
@@ -445,15 +460,7 @@ struct meta_factory<Type> {
             &meta_getter<Type, Getter, Policy>
         };
 
-        meta_range<internal::meta_data_node *, internal::meta_data_node> range{owner->data};
-        ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr != &node && curr->id == id; }) == range.cend(), "Duplicate identifier");
-        node.id = id;
-
-        if(std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
-            node.next = owner->data;
-            owner->data = &node;
-        }
-
+        link_data_if_required(id, node);
         return meta_factory<Type, std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>{&node.prop};
     }
 
@@ -487,21 +494,7 @@ struct meta_factory<Type> {
             &meta_invoke<Type, Candidate, Policy>
         };
 
-        for(auto *it = &owner->func; *it; it = &(*it)->next) {
-            if(*it == &node) {
-                *it = node.next;
-                break;
-            }
-        }
-
-        internal::meta_func_node **it = &owner->func;
-        for(; *it && (*it)->id != id; it = &(*it)->next);
-        for(; *it && (*it)->id == id && (*it)->arity < node.arity; it = &(*it)->next);
-
-        node.id = id;
-        node.next = *it;
-        *it = &node;
-
+        link_func_if_required(id, node);
         return meta_factory<Type, std::integral_constant<decltype(Candidate), Candidate>>{&node.prop};
     }