diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 7306e8614..8e71c76b5 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -312,14 +312,50 @@ class meta_any { return &lhs == &rhs; } + template + static bool compare(const void *lhs, const void *rhs) { + return compare(0, *static_cast(lhs), *static_cast(rhs)); + } + + template + static void * copy_storage(storage_type &storage, const void *instance) { + return new (&storage) Type{*static_cast(instance)}; + } + + template + static void * copy_object(storage_type &storage, const void *instance) { + using chunk_type = std::aligned_storage_t; + auto *chunk = new chunk_type; + new (&storage) chunk_type *{chunk}; + return new (chunk) Type{*static_cast(instance)}; + } + + template + static void destroy_storage(storage_type &storage) { + auto *node = internal::meta_info::resolve(); + auto *instance = reinterpret_cast(&storage); + node->dtor ? node->dtor->invoke(*instance) : node->destroy(*instance); + } + + template + static void destroy_object(storage_type &storage) { + using chunk_type = std::aligned_storage_t; + auto *node = internal::meta_info::resolve(); + auto *chunk = *reinterpret_cast(&storage); + auto *instance = reinterpret_cast(chunk); + node->dtor ? node->dtor->invoke(*instance) : node->destroy(*instance); + delete chunk; + } + public: /*! @brief Default constructor. */ meta_any() ENTT_NOEXCEPT : storage{}, instance{nullptr}, - destroy{nullptr}, node{nullptr}, - comparator{nullptr} + destroy_fn{nullptr}, + compare_fn{nullptr}, + copy_fn{nullptr} {} /** @@ -340,42 +376,23 @@ public: using actual_type = std::decay_t; node = internal::meta_info::resolve(); - comparator = [](const void *lhs, const void *rhs) { - return compare(0, *static_cast(lhs), *static_cast(rhs)); - }; + compare_fn = &compare; if constexpr(sizeof(actual_type) <= sizeof(void *)) { new (&storage) actual_type{std::forward(type)}; instance = &storage; - copy = [](storage_type &storage, const void *instance) -> void * { - return new (&storage) actual_type{*static_cast(instance)}; - }; - - destroy = [](storage_type &storage) { - auto *node = internal::meta_info::resolve(); - auto *instance = reinterpret_cast(&storage); - node->dtor ? node->dtor->invoke(*instance) : node->destroy(*instance); - }; + destroy_fn = &destroy_storage; + copy_fn = ©_storage; } else { using chunk_type = std::aligned_storage_t; + auto *chunk = new chunk_type; instance = new (chunk) actual_type{std::forward(type)}; new (&storage) chunk_type *{chunk}; - copy = [](storage_type &storage, const void *instance) -> void * { - auto *chunk = new chunk_type; - new (&storage) chunk_type *{chunk}; - return new (chunk) actual_type{*static_cast(instance)}; - }; - - destroy = [](storage_type &storage) { - auto *node = internal::meta_info::resolve(); - auto *chunk = *reinterpret_cast(&storage); - auto *instance = reinterpret_cast(chunk); - node->dtor ? node->dtor->invoke(*instance) : node->destroy(*instance); - delete chunk; - }; + destroy_fn = &destroy_object; + copy_fn = ©_object; } } @@ -387,11 +404,11 @@ public: : meta_any{} { if(other) { - instance = other.copy(storage, other.instance); - destroy = other.destroy; + instance = other.copy_fn(storage, other.instance); node = other.node; - comparator = other.comparator; - copy = other.copy; + destroy_fn = other.destroy_fn; + compare_fn = other.compare_fn; + copy_fn = other.copy_fn; } } @@ -412,8 +429,8 @@ public: /*! @brief Frees the internal storage, whatever it means. */ ~meta_any() { - if(destroy) { - destroy(storage); + if(destroy_fn) { + destroy_fn(storage); } } @@ -546,7 +563,7 @@ public: * @return False if the container is empty, true otherwise. */ inline explicit operator bool() const ENTT_NOEXCEPT { - return destroy; + return destroy_fn; } /** @@ -556,7 +573,7 @@ public: * otherwise. */ inline bool operator==(const meta_any &other) const ENTT_NOEXCEPT { - return (!instance && !other.instance) || (instance && other.instance && node == other.node && comparator(instance, other.instance)); + return (!instance && !other.instance) || (instance && other.instance && node == other.node && compare_fn(instance, other.instance)); } /** @@ -569,10 +586,10 @@ public: std::swap(lhs.storage, rhs.storage); std::swap(lhs.instance, rhs.instance); - std::swap(lhs.destroy, rhs.destroy); + std::swap(lhs.destroy_fn, rhs.destroy_fn); std::swap(lhs.node, rhs.node); - std::swap(lhs.comparator, rhs.comparator); - std::swap(lhs.copy, rhs.copy); + std::swap(lhs.compare_fn, rhs.compare_fn); + std::swap(lhs.copy_fn, rhs.copy_fn); if(lhs.instance == &rhs.storage) { lhs.instance = &lhs.storage; @@ -586,10 +603,10 @@ public: private: storage_type storage; void *instance; - destroy_fn_type destroy; internal::meta_type_node *node; - compare_fn_type comparator; - copy_fn_type copy; + destroy_fn_type destroy_fn; + compare_fn_type compare_fn; + copy_fn_type copy_fn; };