Browse Source

meta: removed internal::meta_range

Michele Caini 5 years ago
parent
commit
53e951d96d
4 changed files with 44 additions and 102 deletions
  1. 10 74
      src/entt/meta/internal.hpp
  2. 16 20
      src/entt/meta/meta.hpp
  3. 4 4
      src/entt/meta/range.hpp
  4. 14 4
      src/entt/meta/resolve.hpp

+ 10 - 74
src/entt/meta/internal.hpp

@@ -129,84 +129,20 @@ struct meta_type_node {
 };
 
 
-template<typename Node>
-class meta_range {
-    struct range_iterator {
-        using difference_type = std::ptrdiff_t;
-        using value_type = Node;
-        using pointer = value_type *;
-        using reference = value_type &;
-        using iterator_category = std::forward_iterator_tag;
-
-        range_iterator() ENTT_NOEXCEPT = default;
-
-        range_iterator(Node *head) ENTT_NOEXCEPT
-            : node{head}
-        {}
-
-        range_iterator & operator++() ENTT_NOEXCEPT {
-            return node = node->next, *this;
-        }
-
-        range_iterator operator++(int) ENTT_NOEXCEPT {
-            range_iterator orig = *this;
-            return ++(*this), orig;
-        }
-
-        [[nodiscard]] bool operator==(const range_iterator &other) const ENTT_NOEXCEPT {
-            return other.node == node;
-        }
-
-        [[nodiscard]] bool operator!=(const range_iterator &other) const ENTT_NOEXCEPT {
-            return !(*this == other);
-        }
-
-        [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
-            return node;
-        }
-
-        [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
-            return *operator->();
-        }
-
-    private:
-        Node *node{nullptr};
-    };
-
-public:
-    using iterator = range_iterator;
-
-    meta_range() ENTT_NOEXCEPT = default;
-
-    meta_range(Node *head)
-        : node{head}
-    {}
-
-    [[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
-        return iterator{node};
-    }
-
-    [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
-        return iterator{};
-    }
-
-private:
-    Node *node{nullptr};
-};
-
-
-template<auto Member, typename Op>
-auto find_if(const Op &op, const meta_type_node *node)
+template<auto Member, typename Op, typename Node>
+auto meta_visit(const Op &op, const Node *node)
 -> std::decay_t<decltype(node->*Member)> {
-    for(auto &&curr: meta_range{node->*Member}) {
-        if(op(&curr)) {
-            return &curr;
+    for(auto *curr = node->*Member; curr; curr = curr->next) {
+        if(op(curr)) {
+            return curr;
         }
     }
 
-    for(auto &&curr: meta_range{node->base}) {
-        if(auto *ret = find_if<Member>(op, curr.type()); ret) {
-            return ret;
+    if constexpr(std::is_same_v<Node, meta_type_node>) {
+        for(auto *curr = node->base; curr; curr = curr->next) {
+            if(auto *ret = meta_visit<Member>(op, curr->type()); ret) {
+                return ret;
+            }
         }
     }
 

+ 16 - 20
src/entt/meta/meta.hpp

@@ -2,7 +2,6 @@
 #define ENTT_META_META_HPP
 
 
-#include <algorithm>
 #include <array>
 #include <cstddef>
 #include <iterator>
@@ -329,7 +328,7 @@ public:
         if(node) {
             if(const auto info = internal::meta_info<Type>::resolve()->info; node->info == info) {
                 return any_cast<Type>(&storage);
-            } else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type()->info == info; }, node); base) {
+            } else if(const auto *base = internal::meta_visit<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type()->info == info; }, node); base) {
                 return static_cast<const Type *>(base->cast(storage.data()));
             }
         }
@@ -343,7 +342,7 @@ public:
         if(node) {
             if(const auto info = internal::meta_info<Type>::resolve()->info; node->info == info) {
                 return any_cast<Type>(&storage);
-            } else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type()->info == info; }, node); base) {
+            } else if(const auto *base = internal::meta_visit<&internal::meta_type_node::base>([info](const auto *curr) { return curr->type()->info == info; }, node); base) {
                 return static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(base->cast(static_cast<constness_as_t<any, Type> &>(storage).data())));
             }
         }
@@ -389,7 +388,7 @@ public:
         if(try_cast<std::remove_reference_t<Type>>() != nullptr) {
             return as_ref(*this);
         } else if(node) {
-            if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([info = internal::meta_info<Type>::resolve()->info](const auto *curr) {
+            if(const auto * const conv = internal::meta_visit<&internal::meta_type_node::conv>([info = internal::meta_info<Type>::resolve()->info](const auto *curr) {
                 return curr->type()->info == info;
             }, node); conv) {
                 return conv->conv(storage.data());
@@ -410,7 +409,7 @@ public:
         if(try_cast<std::conditional_t<std::is_reference_v<Type>, std::remove_reference_t<Type>, const Type>>() != nullptr) {
             return true;
         } else if(node) {
-            if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([info = internal::meta_info<Type>::resolve()->info](const auto *curr) {
+            if(const auto * const conv = internal::meta_visit<&internal::meta_type_node::conv>([info = internal::meta_info<Type>::resolve()->info](const auto *curr) {
                 return curr->type()->info == info;
             }, node); conv) {
                 *this = conv->conv(std::as_const(storage).data());
@@ -725,8 +724,7 @@ struct meta_ctor {
      * @return The property associated with the given key, if any.
      */
     [[nodiscard]] meta_prop prop(meta_any key) const {
-        internal::meta_range range{node->prop};
-        return std::find_if(range.begin(), range.end(), [&key](const auto &curr) { return curr.key() == key; }).operator->();
+        return internal::meta_visit<&node_type::prop>([&key](const auto *curr) { return curr->key() == key; }, node);
     }
 
     /**
@@ -822,8 +820,7 @@ struct meta_data {
      * @return The property associated with the given key, if any.
      */
     [[nodiscard]] meta_prop prop(meta_any key) const {
-        internal::meta_range range{node->prop};
-        return std::find_if(range.begin(), range.end(), [&key](const auto &curr) { return curr.key() == key; }).operator->();
+        return internal::meta_visit<&node_type::prop>([&key](const auto *curr) { return curr->key() == key; }, node);
     }
 
     /**
@@ -942,8 +939,7 @@ struct meta_func {
      * @return The property associated with the given key, if any.
      */
     [[nodiscard]] meta_prop prop(meta_any key) const {
-        internal::meta_range range{node->prop};
-        return std::find_if(range.begin(), range.end(), [&key](const auto &curr) { return curr.key() == key; }).operator->();
+        return internal::meta_visit<&node_type::prop>([&key](const auto *curr) { return curr->key() == key; }, node);
     }
 
     /**
@@ -978,10 +974,10 @@ class meta_type {
     }
 
     template<typename... Args, auto... Index>
-    [[nodiscard]] static const internal::meta_ctor_node * ctor(const internal::meta_ctor_node * const curr, std::index_sequence<Index...>) {
-        for(const auto &candidate: internal::meta_range{curr}) {
-            if(candidate.size == sizeof...(Args) && ([](auto *from, auto *to) { return from->info == to->info || can_cast_or_convert(from, to->info); }(internal::meta_info<Args>::resolve(), candidate.arg(Index)) && ...)) {
-                return &candidate;
+    [[nodiscard]] static const internal::meta_ctor_node * ctor(const internal::meta_ctor_node *curr, std::index_sequence<Index...>) {
+        for(; curr; curr = curr->next) {
+            if(curr->size == sizeof...(Args) && ([](auto *from, auto *to) { return from->info == to->info || can_cast_or_convert(from, to->info); }(internal::meta_info<Args>::resolve(), curr->arg(Index)) && ...)) {
+                return curr;
             }
         }
 
@@ -1216,7 +1212,7 @@ public:
      * @return The data associated with the given identifier, if any.
      */
     [[nodiscard]] meta_data data(const id_type id) const {
-        return internal::find_if<&node_type::data>([id](const auto *curr) {
+        return internal::meta_visit<&node_type::data>([id](const auto *curr) {
             return curr->id == id;
         }, node);
     }
@@ -1240,7 +1236,7 @@ public:
      * @return The function associated with the given identifier, if any.
      */
     [[nodiscard]] meta_func func(const id_type id) const {
-        return internal::find_if<&node_type::func>([id](const auto *curr) {
+        return internal::meta_visit<&node_type::func>([id](const auto *curr) {
             return curr->id == id;
         }, node);
     }
@@ -1258,7 +1254,7 @@ public:
     [[nodiscard]] meta_any construct(meta_any * const args, const size_type sz) const {
         meta_any any{};
 
-        internal::find_if<&node_type::ctor>([args, sz, &any](const auto *curr) {
+        internal::meta_visit<&node_type::ctor>([args, sz, &any](const auto *curr) {
             return (curr->size == sz) && (any = curr->invoke(args));
         }, node);
 
@@ -1300,7 +1296,7 @@ public:
         size_type extent{sz + 1u};
         bool ambiguous{};
 
-        for(auto *it = internal::find_if<&node_type::func>([id, sz](const auto *curr) { return curr->id == id && curr->size == sz; }, node); it && it->id == id && it->size == sz; it = it->next) {
+        for(auto *it = internal::meta_visit<&node_type::func>([id, sz](const auto *curr) { return curr->id == id && curr->size == sz; }, node); it && it->id == id && it->size == sz; it = it->next) {
             size_type direct{};
             size_type ext{};
 
@@ -1394,7 +1390,7 @@ public:
      * @return The property associated with the given key, if any.
      */
     [[nodiscard]] meta_prop prop(meta_any key) const {
-        return internal::find_if<&node_type::prop>([key = std::move(key)](const auto *curr) {
+        return internal::meta_visit<&node_type::prop>([key = std::move(key)](const auto *curr) {
             return curr->key() == key;
         }, node);
     }

+ 4 - 4
src/entt/meta/range.hpp

@@ -31,16 +31,16 @@ class meta_range {
         {}
 
         range_iterator & operator++() ENTT_NOEXCEPT {
-            return ++it, *this;
+            return (it = it->next), *this;
         }
 
         range_iterator operator++(int) ENTT_NOEXCEPT {
             range_iterator orig = *this;
-            return it++, orig;
+            return ++(*this), orig;
         }
 
         [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
-            return it.operator->();
+            return it;
         }
 
         [[nodiscard]] bool operator==(const range_iterator &other) const ENTT_NOEXCEPT {
@@ -52,7 +52,7 @@ class meta_range {
         }
 
     private:
-        typename internal::meta_range<node_type>::iterator it{};
+        node_type *it{};
     };
 
 public:

+ 14 - 4
src/entt/meta/resolve.hpp

@@ -38,8 +38,13 @@ template<typename Type>
  * @return The meta type associated with the given identifier, if any.
  */
 [[nodiscard]] inline meta_type resolve(const id_type id) ENTT_NOEXCEPT {
-    internal::meta_range range{*internal::meta_context::global()};
-    return std::find_if(range.begin(), range.end(), [id](const auto &curr) { return curr.id == id; }).operator->();
+    for(auto *curr = *internal::meta_context::global(); curr; curr = curr->next) {
+        if(curr->id == id) {
+            return curr;
+        }
+    }
+
+    return {};
 }
 
 
@@ -50,8 +55,13 @@ template<typename Type>
  * @return The meta type associated with the given type info object, if any.
  */
 [[nodiscard]] inline meta_type resolve(const type_info info) ENTT_NOEXCEPT {
-    internal::meta_range range{*internal::meta_context::global()};
-    return std::find_if(range.begin(), range.end(), [info](const auto &curr) { return curr.info == info; }).operator->();
+    for(auto *curr = *internal::meta_context::global(); curr; curr = curr->next) {
+        if(curr->info == info) {
+            return curr;
+        }
+    }
+
+    return {};
 }