Browse Source

meta: avoid passing contexts to meta containers' vtables

Michele Caini 2 years ago
parent
commit
ce6a04ae5a
2 changed files with 69 additions and 60 deletions
  1. 14 15
      src/entt/meta/container.hpp
  2. 55 45
      src/entt/meta/meta.hpp

+ 14 - 15
src/entt/meta/container.hpp

@@ -13,7 +13,6 @@
 #include <vector>
 #include <vector>
 #include "../container/dense_map.hpp"
 #include "../container/dense_map.hpp"
 #include "../container/dense_set.hpp"
 #include "../container/dense_set.hpp"
-#include "context.hpp"
 #include "meta.hpp"
 #include "meta.hpp"
 #include "type_traits.hpp"
 #include "type_traits.hpp"
 
 
@@ -65,7 +64,7 @@ class basic_meta_sequence_container_traits {
     using size_type = typename meta_sequence_container::size_type;
     using size_type = typename meta_sequence_container::size_type;
     using iterator = typename meta_sequence_container::iterator;
     using iterator = typename meta_sequence_container::iterator;
 
 
-    static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *cvalue, void *value, iterator *it) {
+    static size_type basic_vtable(const operation op, const void *cvalue, void *value, iterator *it) {
         switch(op) {
         switch(op) {
         case operation::size:
         case operation::size:
             return static_cast<const Type *>(cvalue)->size();
             return static_cast<const Type *>(cvalue)->size();
@@ -92,17 +91,17 @@ class basic_meta_sequence_container_traits {
             }
             }
         case operation::begin:
         case operation::begin:
             if(value) {
             if(value) {
-                *it = iterator{ctx, static_cast<Type *>(value)->begin()};
+                it->rebind(static_cast<Type *>(value)->begin());
             } else {
             } else {
-                *it = iterator{ctx, static_cast<const Type *>(cvalue)->begin()};
+                it->rebind(static_cast<const Type *>(cvalue)->begin());
             }
             }
 
 
             return true;
             return true;
         case operation::end:
         case operation::end:
             if(value) {
             if(value) {
-                *it = iterator{ctx, static_cast<Type *>(value)->end()};
+                it->rebind(static_cast<Type *>(value)->end());
             } else {
             } else {
-                *it = iterator{ctx, static_cast<const Type *>(cvalue)->end()};
+                it->rebind(static_cast<const Type *>(cvalue)->end());
             }
             }
 
 
             return true;
             return true;
@@ -116,11 +115,11 @@ class basic_meta_sequence_container_traits {
                     // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
                     // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
                     if(auto &as_any = *static_cast<meta_any *>(const_cast<void *>(cvalue)); as_any.allow_cast<typename Type::const_reference>() || as_any.allow_cast<typename Type::value_type>()) {
                     if(auto &as_any = *static_cast<meta_any *>(const_cast<void *>(cvalue)); as_any.allow_cast<typename Type::const_reference>() || as_any.allow_cast<typename Type::value_type>()) {
                         const auto *element = as_any.try_cast<std::remove_reference_t<typename Type::const_reference>>();
                         const auto *element = as_any.try_cast<std::remove_reference_t<typename Type::const_reference>>();
-                        *it = iterator{ctx, static_cast<Type *>(value)->insert(underlying, element ? *element : as_any.cast<typename Type::value_type>())};
+                        it->rebind(static_cast<Type *>(value)->insert(underlying, element ? *element : as_any.cast<typename Type::value_type>()));
                         return true;
                         return true;
                     }
                     }
                 } else {
                 } else {
-                    *it = iterator{ctx, static_cast<Type *>(value)->erase(underlying)};
+                    it->rebind(static_cast<Type *>(value)->erase(underlying));
                     return true;
                     return true;
                 }
                 }
             }
             }
@@ -151,7 +150,7 @@ class basic_meta_associative_container_traits {
     using size_type = typename meta_associative_container::size_type;
     using size_type = typename meta_associative_container::size_type;
     using iterator = typename meta_associative_container::iterator;
     using iterator = typename meta_associative_container::iterator;
 
 
-    static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *cvalue, void *value, meta_any *key, iterator *it) {
+    static size_type basic_vtable(const operation op, const void *cvalue, void *value, meta_any *key, iterator *it) {
         switch(op) {
         switch(op) {
         case operation::size:
         case operation::size:
             return static_cast<const Type *>(cvalue)->size();
             return static_cast<const Type *>(cvalue)->size();
@@ -167,17 +166,17 @@ class basic_meta_associative_container_traits {
             }
             }
         case operation::begin:
         case operation::begin:
             if(value) {
             if(value) {
-                *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->begin()};
+                it->rebind<key_only>(static_cast<Type *>(value)->begin());
             } else {
             } else {
-                *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->begin()};
+                it->rebind<key_only>(static_cast<const Type *>(cvalue)->begin());
             }
             }
 
 
             return true;
             return true;
         case operation::end:
         case operation::end:
             if(value) {
             if(value) {
-                *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->end()};
+                it->rebind<key_only>(static_cast<Type *>(value)->end());
             } else {
             } else {
-                *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->end()};
+                it->rebind<key_only>(static_cast<const Type *>(cvalue)->end());
             }
             }
 
 
             return true;
             return true;
@@ -201,9 +200,9 @@ class basic_meta_associative_container_traits {
         case operation::find:
         case operation::find:
             if(key->allow_cast<const typename Type::key_type &>()) {
             if(key->allow_cast<const typename Type::key_type &>()) {
                 if(value) {
                 if(value) {
-                    *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->find(key->cast<const typename Type::key_type &>())};
+                    it->rebind<key_only>(static_cast<Type *>(value)->find(key->cast<const typename Type::key_type &>()));
                 } else {
                 } else {
-                    *it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->find(key->cast<const typename Type::key_type &>())};
+                    it->rebind<key_only>(static_cast<const Type *>(cvalue)->find(key->cast<const typename Type::key_type &>()));
                 }
                 }
 
 
                 return true;
                 return true;

+ 55 - 45
src/entt/meta/meta.hpp

@@ -63,11 +63,15 @@ public:
     /*! @brief Meta iterator type. */
     /*! @brief Meta iterator type. */
     using iterator = meta_iterator;
     using iterator = meta_iterator;
 
 
+    /*! @brief Default constructor. */
+    meta_sequence_container() noexcept
+        : meta_sequence_container{locator<meta_ctx>::value_or()} {}
+
     /**
     /**
      * @brief Context aware constructor.
      * @brief Context aware constructor.
      * @param area The context from which to search for meta types.
      * @param area The context from which to search for meta types.
      */
      */
-    meta_sequence_container(const meta_ctx &area = locator<meta_ctx>::value_or()) noexcept
+    meta_sequence_container(const meta_ctx &area) noexcept
         : ctx{&area} {}
         : ctx{&area} {}
 
 
     /**
     /**
@@ -98,7 +102,7 @@ public:
 private:
 private:
     const meta_ctx *ctx{};
     const meta_ctx *ctx{};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
-    size_type (*vtable)(const operation, const meta_ctx &, const void *, void *, iterator *){};
+    size_type (*vtable)(const operation, const void *, void *, iterator *){};
     any storage{};
     any storage{};
 };
 };
 
 
@@ -113,11 +117,15 @@ public:
     /*! @brief Meta iterator type. */
     /*! @brief Meta iterator type. */
     using iterator = meta_iterator;
     using iterator = meta_iterator;
 
 
+    /*! @brief Default constructor. */
+    meta_associative_container() noexcept
+        : meta_associative_container{locator<meta_ctx>::value_or()} {}
+
     /**
     /**
      * @brief Context aware constructor.
      * @brief Context aware constructor.
      * @param area The context from which to search for meta types.
      * @param area The context from which to search for meta types.
      */
      */
-    meta_associative_container(const meta_ctx &area = locator<meta_ctx>::value_or()) noexcept
+    meta_associative_container(const meta_ctx &area) noexcept
         : ctx{&area} {}
         : ctx{&area} {}
 
 
     /**
     /**
@@ -157,7 +165,7 @@ private:
     internal::meta_type_node (*key_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*key_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*mapped_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*mapped_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
     internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
-    size_type (*vtable)(const operation, const meta_ctx &, const void *, void *, meta_any *, iterator *){};
+    size_type (*vtable)(const operation, const void *, void *, meta_any *, iterator *){};
     any storage{};
     any storage{};
 };
 };
 
 
@@ -1704,15 +1712,16 @@ public:
     using iterator_category = std::input_iterator_tag;
     using iterator_category = std::input_iterator_tag;
 
 
     constexpr meta_iterator() noexcept
     constexpr meta_iterator() noexcept
-        : ctx{},
-          vtable{},
-          handle{} {}
+        : meta_iterator{locator<meta_ctx>::value_or()} {}
+
+    constexpr meta_iterator(const meta_ctx &area) noexcept
+        : ctx{&area} {}
 
 
     template<typename It>
     template<typename It>
-    explicit meta_iterator(const meta_ctx &area, It iter) noexcept
-        : ctx{&area},
-          vtable{&basic_vtable<It>},
-          handle{iter} {}
+    void rebind(It iter) noexcept {
+        vtable = &basic_vtable<It>;
+        handle = iter;
+    }
 
 
     meta_iterator &operator++() noexcept {
     meta_iterator &operator++() noexcept {
         vtable(handle.data(), 1, nullptr);
         vtable(handle.data(), 1, nullptr);
@@ -1763,9 +1772,9 @@ public:
     }
     }
 
 
 private:
 private:
-    const meta_ctx *ctx;
-    vtable_type *vtable;
-    any handle;
+    const meta_ctx *ctx{};
+    vtable_type *vtable{};
+    any handle{};
 };
 };
 
 
 class meta_associative_container::meta_iterator final {
 class meta_associative_container::meta_iterator final {
@@ -1793,15 +1802,16 @@ public:
     using iterator_category = std::input_iterator_tag;
     using iterator_category = std::input_iterator_tag;
 
 
     constexpr meta_iterator() noexcept
     constexpr meta_iterator() noexcept
-        : ctx{},
-          vtable{},
-          handle{} {}
+        : meta_iterator{locator<meta_ctx>::value_or()} {}
+
+    constexpr meta_iterator(const meta_ctx &area) noexcept
+        : ctx{&area} {}
 
 
     template<bool KeyOnly, typename It>
     template<bool KeyOnly, typename It>
-    meta_iterator(const meta_ctx &area, std::integral_constant<bool, KeyOnly>, It iter) noexcept
-        : ctx{&area},
-          vtable{&basic_vtable<KeyOnly, It>},
-          handle{iter} {}
+    void rebind(It iter) noexcept {
+        vtable = &basic_vtable<KeyOnly, It>;
+        handle = iter;
+    }
 
 
     meta_iterator &operator++() noexcept {
     meta_iterator &operator++() noexcept {
         vtable(handle.data(), nullptr);
         vtable(handle.data(), nullptr);
@@ -1836,9 +1846,9 @@ public:
     }
     }
 
 
 private:
 private:
-    const meta_ctx *ctx;
-    vtable_type *vtable;
-    any handle;
+    const meta_ctx *ctx{};
+    vtable_type *vtable{};
+    any handle{};
 };
 };
 
 
 /**
 /**
@@ -1859,7 +1869,7 @@ private:
  * @return The size of the container.
  * @return The size of the container.
  */
  */
 [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept {
 [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept {
-    return vtable(operation::size, *ctx, std::as_const(storage).data(), nullptr, nullptr);
+    return vtable(operation::size, std::as_const(storage).data(), nullptr, nullptr);
 }
 }
 
 
 /**
 /**
@@ -1868,7 +1878,7 @@ private:
  * @return True in case of success, false otherwise.
  * @return True in case of success, false otherwise.
  */
  */
 inline bool meta_sequence_container::resize(const size_type sz) {
 inline bool meta_sequence_container::resize(const size_type sz) {
-    return (storage.policy() != any_policy::cref) && vtable(operation::resize, *ctx, &sz, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::resize, &sz, storage.data(), nullptr);
 }
 }
 
 
 /**
 /**
@@ -1876,7 +1886,7 @@ inline bool meta_sequence_container::resize(const size_type sz) {
  * @return True in case of success, false otherwise.
  * @return True in case of success, false otherwise.
  */
  */
 inline bool meta_sequence_container::clear() {
 inline bool meta_sequence_container::clear() {
-    return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, nullptr, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::clear, nullptr, storage.data(), nullptr);
 }
 }
 
 
 /**
 /**
@@ -1885,7 +1895,7 @@ inline bool meta_sequence_container::clear() {
  * @return True in case of success, false otherwise.
  * @return True in case of success, false otherwise.
  */
  */
 inline bool meta_sequence_container::reserve(const size_type sz) {
 inline bool meta_sequence_container::reserve(const size_type sz) {
-    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, &sz, storage.data(), nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, &sz, storage.data(), nullptr);
 }
 }
 
 
 /**
 /**
@@ -1893,9 +1903,9 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  * @return An iterator to the first element of the container.
  * @return An iterator to the first element of the container.
  */
  */
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
-    iterator it{};
+    iterator it{*ctx};
     const void *data = std::as_const(storage).data();
     const void *data = std::as_const(storage).data();
-    vtable(operation::begin, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
+    vtable(operation::begin, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
     return it;
     return it;
 }
 }
 
 
@@ -1904,9 +1914,9 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  * @return An iterator that is past the last element of the container.
  * @return An iterator that is past the last element of the container.
  */
  */
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
 [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
-    iterator it{};
+    iterator it{*ctx};
     const void *data = std::as_const(storage).data();
     const void *data = std::as_const(storage).data();
-    vtable(operation::end, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
+    vtable(operation::end, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
     return it;
     return it;
 }
 }
 
 
@@ -1917,7 +1927,7 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
  * @return A possibly invalid iterator to the inserted element.
  * @return A possibly invalid iterator to the inserted element.
  */
  */
 inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
 inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
-    return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, &value, storage.data(), &it)) ? it : iterator{};
+    return ((storage.policy() != any_policy::cref) && vtable(operation::insert, &value, storage.data(), &it)) ? it : iterator{*ctx};
 }
 }
 
 
 /**
 /**
@@ -1926,7 +1936,7 @@ inline meta_sequence_container::iterator meta_sequence_container::insert(iterato
  * @return A possibly invalid iterator following the last removed element.
  * @return A possibly invalid iterator following the last removed element.
  */
  */
 inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
 inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
-    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, *ctx, nullptr, storage.data(), &it)) ? it : iterator{};
+    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, nullptr, storage.data(), &it)) ? it : iterator{*ctx};
 }
 }
 
 
 /**
 /**
@@ -1972,32 +1982,32 @@ inline meta_sequence_container::iterator meta_sequence_container::erase(iterator
 
 
 /*! @copydoc meta_sequence_container::size */
 /*! @copydoc meta_sequence_container::size */
 [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept {
 [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept {
-    return vtable(operation::size, *ctx, std::as_const(storage).data(), nullptr, nullptr, nullptr);
+    return vtable(operation::size, std::as_const(storage).data(), nullptr, nullptr, nullptr);
 }
 }
 
 
 /*! @copydoc meta_sequence_container::clear */
 /*! @copydoc meta_sequence_container::clear */
 inline bool meta_associative_container::clear() {
 inline bool meta_associative_container::clear() {
-    return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, nullptr, storage.data(), nullptr, nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::clear, nullptr, storage.data(), nullptr, nullptr);
 }
 }
 
 
 /*! @copydoc meta_sequence_container::reserve */
 /*! @copydoc meta_sequence_container::reserve */
 inline bool meta_associative_container::reserve(const size_type sz) {
 inline bool meta_associative_container::reserve(const size_type sz) {
-    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, &sz, storage.data(), nullptr, nullptr);
+    return (storage.policy() != any_policy::cref) && vtable(operation::reserve, &sz, storage.data(), nullptr, nullptr);
 }
 }
 
 
 /*! @copydoc meta_sequence_container::begin */
 /*! @copydoc meta_sequence_container::begin */
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
-    iterator it{};
+    iterator it{*ctx};
     const void *data = std::as_const(storage).data();
     const void *data = std::as_const(storage).data();
-    vtable(operation::begin, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
+    vtable(operation::begin, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
     return it;
     return it;
 }
 }
 
 
 /*! @copydoc meta_sequence_container::end */
 /*! @copydoc meta_sequence_container::end */
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
-    iterator it{};
+    iterator it{*ctx};
     const void *data = std::as_const(storage).data();
     const void *data = std::as_const(storage).data();
-    vtable(operation::end, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
+    vtable(operation::end, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
     return it;
     return it;
 }
 }
 
 
@@ -2008,7 +2018,7 @@ inline bool meta_associative_container::reserve(const size_type sz) {
  * @return A bool denoting whether the insertion took place.
  * @return A bool denoting whether the insertion took place.
  */
  */
 inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
 inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
-    return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, &value, storage.data(), &key, nullptr));
+    return ((storage.policy() != any_policy::cref) && vtable(operation::insert, &value, storage.data(), &key, nullptr));
 }
 }
 
 
 /**
 /**
@@ -2017,7 +2027,7 @@ inline bool meta_associative_container::insert(meta_any key, meta_any value = {}
  * @return A bool denoting whether the removal took place.
  * @return A bool denoting whether the removal took place.
  */
  */
 inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) {
 inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) {
-    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, *ctx, nullptr, storage.data(), &key, nullptr));
+    return ((storage.policy() != any_policy::cref) && vtable(operation::erase, nullptr, storage.data(), &key, nullptr));
 }
 }
 
 
 /**
 /**
@@ -2026,9 +2036,9 @@ inline meta_associative_container::size_type meta_associative_container::erase(m
  * @return An iterator to the element with the given key, if any.
  * @return An iterator to the element with the given key, if any.
  */
  */
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
 [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
-    iterator it{};
+    iterator it{*ctx};
     const void *data = std::as_const(storage).data();
     const void *data = std::as_const(storage).data();
-    vtable(operation::find, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &key, &it);
+    vtable(operation::find, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &key, &it);
     return it;
     return it;
 }
 }