Преглед изворни кода

meta: cleanup, prep for hook point

Michele Caini пре 4 година
родитељ
комит
8566c58f2b
1 измењених фајлова са 40 додато и 81 уклоњено
  1. 40 81
      src/entt/meta/factory.hpp

+ 40 - 81
src/entt/meta/factory.hpp

@@ -2,6 +2,7 @@
 #define ENTT_META_FACTORY_HPP
 
 
+#include <algorithm>
 #include <cstddef>
 #include <tuple>
 #include <type_traits>
@@ -13,70 +14,13 @@
 #include "meta.hpp"
 #include "node.hpp"
 #include "policy.hpp"
+#include "range.hpp"
 #include "utility.hpp"
 
 
 namespace entt {
 
 
-/**
- * @cond TURN_OFF_DOXYGEN
- * Internal details not to be documented.
- */
-
-
-namespace internal {
-
-
-template<typename Node>
-[[nodiscard]] bool find_if(const Node *candidate, const Node *node) ENTT_NOEXCEPT {
-    return node && (node == candidate || find_if(candidate, node->next));
-}
-
-
-template<typename Id, typename Node>
-[[nodiscard]] bool find_if_not(const Id id, Node *node, const Node *owner) ENTT_NOEXCEPT {
-    if constexpr(std::is_pointer_v<Id>) {
-        return node && ((*node->id == *id && node != owner) || find_if_not(id, node->next, owner));
-    } else {
-        return node && ((node->id == id && node != owner) || find_if_not(id, node->next, owner));
-    }
-}
-
-
-template<auto... Member, typename Node>
-void meta_reset(Node **curr) {
-    while(*curr) {
-        (meta_reset(&((*curr)->*Member)), ...);
-        *curr = std::exchange((*curr)->next, nullptr);
-    }
-}
-
-
-inline void meta_reset(internal::meta_type_node *node) ENTT_NOEXCEPT {
-    meta_reset(&node->prop);
-    meta_reset(&node->base);
-    meta_reset(&node->conv);
-    meta_reset<&internal::meta_ctor_node::prop>(&node->ctor);
-    meta_reset<&internal::meta_data_node::prop>(&node->data);
-    meta_reset<&internal::meta_func_node::prop>(&node->func);
-
-    node->id = {};
-    node->ctor = node->def_ctor;
-    node->dtor = nullptr;
-    node->next = nullptr;
-}
-
-
-}
-
-
-/**
- * Internal details not to be documented.
- * @endcond
- */
-
-
 /**
  * @brief Meta factory to be used for reflection purposes.
  *
@@ -139,11 +83,11 @@ private:
         };
 
         entt::meta_any instance{std::forward<Key>(key)};
-        ENTT_ASSERT(!internal::find_if_not(&instance, *curr, &node), "Duplicate key");
         property[0u] = std::move(instance);
         property[1u] = std::move(value);
 
-        if(!internal::find_if(&node, *curr)) {
+        if(meta_range<internal::meta_prop_node *, internal::meta_prop_node> range{*curr}; 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 = *curr;
             *curr = &node;
         }
@@ -215,10 +159,10 @@ struct meta_factory<Type> {
     auto type(const id_type id = type_hash<Type>::value()) {
         auto * const node = internal::meta_info<Type>::resolve();
 
-        ENTT_ASSERT(!internal::find_if_not(id, *internal::meta_context::global(), node), "Duplicate identifier");
         node->id = id;
 
-        if(!internal::find_if(node, *internal::meta_context::global())) {
+        if(meta_range<internal::meta_type_node *, internal::meta_type_node> range{*internal::meta_context::global()}; std::find(range.cbegin(), range.cend(), node) == range.cend()) {
+            ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
             node->next = *internal::meta_context::global();
             *internal::meta_context::global() = node;
         }
@@ -247,7 +191,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(!internal::find_if(&node, type->base)) {
+        if(meta_range<internal::meta_base_node *, internal::meta_base_node> range{type->base}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->base;
             type->base = &node;
         }
@@ -280,7 +224,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(!internal::find_if(&node, type->conv)) {
+        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{type->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->conv;
             type->conv = &node;
         }
@@ -302,7 +246,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(!internal::find_if(&node, type->conv)) {
+        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{type->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->conv;
             type->conv = &node;
         }
@@ -332,7 +276,7 @@ struct meta_factory<Type> {
             }
         };
 
-        if(!internal::find_if(&node, type->conv)) {
+        if(meta_range<internal::meta_conv_node *, internal::meta_conv_node> range{type->conv}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->conv;
             type->conv = &node;
         }
@@ -367,7 +311,7 @@ struct meta_factory<Type> {
             &meta_construct<Type, Candidate, Policy>
         };
 
-        if(!internal::find_if(&node, type->ctor)) {
+        if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{type->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->ctor;
             type->ctor = &node;
         }
@@ -398,7 +342,7 @@ struct meta_factory<Type> {
             &meta_construct<Type, Args...>
         };
 
-        if(!internal::find_if(&node, type->ctor)) {
+        if(meta_range<internal::meta_ctor_node *, internal::meta_ctor_node> range{type->ctor}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
             node.next = type->ctor;
             type->ctor = &node;
         }
@@ -466,10 +410,10 @@ struct meta_factory<Type> {
                 &meta_getter<Type, Data, Policy>
             };
 
-            ENTT_ASSERT(!internal::find_if_not(id, type->data, &node), "Duplicate identifier");
             node.id = id;
 
-            if(!internal::find_if(&node, type->data)) {
+            if(meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+                ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
                 node.next = type->data;
                 type->data = &node;
             }
@@ -514,10 +458,10 @@ struct meta_factory<Type> {
             &meta_getter<Type, Getter, Policy>
         };
 
-        ENTT_ASSERT(!internal::find_if_not(id, type->data, &node), "Duplicate identifier");
         node.id = id;
 
-        if(!internal::find_if(&node, type->data)) {
+        if(meta_range<internal::meta_data_node *, internal::meta_data_node> range{type->data}; std::find(range.cbegin(), range.cend(), &node) == range.cend()) {
+            ENTT_ASSERT(std::find_if(range.cbegin(), range.cend(), [id](const auto *curr) { return curr->id == id; }) == range.cend(), "Duplicate identifier");
             node.next = type->data;
             type->data = &node;
         }
@@ -617,28 +561,43 @@ void meta_reset() ENTT_NOEXCEPT {
  * @param id Unique identifier.
  */
 inline void meta_reset(const id_type id) ENTT_NOEXCEPT {
+    auto clear_chain = [](auto **curr, auto... member) {
+        for(; *curr; *curr = std::exchange((*curr)->next, nullptr)) {
+            if constexpr(sizeof...(member) != 0u) {
+                static_assert(sizeof...(member) == 1u, "Assert in defense of the future me");
+                for(auto **it = (&((*curr)->*member), ...); *it; *it = std::exchange((*it)->next, nullptr));
+            }
+        }
+    };
+
     for(auto** it = internal::meta_context::global(); *it; it = &(*it)->next) {
-        if((*it)->id == id) {
-            internal::meta_type_node *node = *it;
-            *it = (*it)->next;
-            internal::meta_reset(node);
+        if(auto *node = *it; node->id == id) {
+            clear_chain(&node->prop);
+            clear_chain(&node->base);
+            clear_chain(&node->conv);
+            clear_chain(&node->ctor, &internal::meta_ctor_node::prop);
+            clear_chain(&node->data, &internal::meta_data_node::prop);
+            clear_chain(&node->func, &internal::meta_func_node::prop);
+
+            node->id = {};
+            node->ctor = node->def_ctor;
+            node->dtor = nullptr;
+            *it = std::exchange(node->next, nullptr);
+
             break;
         }
     }
 }
 
-
 /**
  * @brief Resets all searchable types.
  *
  * @sa meta_reset
  */
 inline void meta_reset() ENTT_NOEXCEPT {
-    for(auto** it = internal::meta_context::global(); *it; it = &(*it)->next) {
-        internal::meta_reset(*it);
+    while(*internal::meta_context::global()) {
+        meta_reset((*internal::meta_context::global())->id);
     }
-
-    *internal::meta_context::global() = nullptr;
 }