diff --git a/src/entt/core/any.hpp b/src/entt/core/any.hpp index af8a1a6c2..38735a88b 100644 --- a/src/entt/core/any.hpp +++ b/src/entt/core/any.hpp @@ -71,62 +71,65 @@ class basic_any: private internal::basic_any_storage { template static const void *basic_vtable(const request req, const basic_any &value, const void *other) { - static_assert(!std::is_void_v && std::is_same_v>, Type>, "Invalid type"); - const Type *elem = nullptr; + static_assert(std::is_same_v>, Type>, "Invalid type"); - if constexpr(in_situ) { - elem = (value.mode == any_policy::embedded) ? reinterpret_cast(&value.buffer) : static_cast(value.instance); - } else { - elem = static_cast(value.instance); - } + if constexpr(!std::is_void_v) { + const Type *elem = nullptr; - switch(req) { - case request::transfer: - if constexpr(std::is_move_assignable_v) { - // NOLINTNEXTLINE(bugprone-casting-through-void) - *const_cast(elem) = std::move(*static_cast(const_cast(other))); - return other; - } - [[fallthrough]]; - case request::assign: - if constexpr(std::is_copy_assignable_v) { - *const_cast(elem) = *static_cast(other); - return other; - } - break; - case request::destroy: if constexpr(in_situ) { - (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); - } else if constexpr(std::is_array_v) { - delete[] elem; + elem = (value.mode == any_policy::embedded) ? reinterpret_cast(&value.buffer) : static_cast(value.instance); } else { - delete elem; + elem = static_cast(value.instance); } - break; - case request::compare: - if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { - return (*elem == *static_cast(other)) ? other : nullptr; - } else { - return (elem == other) ? other : nullptr; - } - case request::copy: - if constexpr(std::is_copy_constructible_v) { - // NOLINTNEXTLINE(bugprone-casting-through-void) - static_cast(const_cast(other))->initialize(*elem); - } - break; - case request::move: - ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); - if constexpr(in_situ) { - // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) - return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; - } - [[fallthrough]]; - case request::get: - ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); - if constexpr(in_situ) { - // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) - return elem; + + switch(req) { + case request::transfer: + if constexpr(std::is_move_assignable_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + *const_cast(elem) = std::move(*static_cast(const_cast(other))); + return other; + } + [[fallthrough]]; + case request::assign: + if constexpr(std::is_copy_assignable_v) { + *const_cast(elem) = *static_cast(other); + return other; + } + break; + case request::destroy: + if constexpr(in_situ) { + (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem); + } else if constexpr(std::is_array_v) { + delete[] elem; + } else { + delete elem; + } + break; + case request::compare: + if constexpr(!std::is_function_v && !std::is_array_v && is_equality_comparable_v) { + return (*elem == *static_cast(other)) ? other : nullptr; + } else { + return (elem == other) ? other : nullptr; + } + case request::copy: + if constexpr(std::is_copy_constructible_v) { + // NOLINTNEXTLINE(bugprone-casting-through-void) + static_cast(const_cast(other))->initialize(*elem); + } + break; + case request::move: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ) { + // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion) + return ::new(&static_cast(const_cast(other))->buffer) Type{std::move(*const_cast(elem))}; + } + [[fallthrough]]; + case request::get: + ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy"); + if constexpr(in_situ) { + // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) + return elem; + } } } @@ -342,9 +345,9 @@ public: template [[nodiscard]] bool has_value() const noexcept { static_assert(std::is_same_v, Type>, "Invalid type"); - constexpr const type_info &(*other)() noexcept = &type_id; + static constexpr auto *other = &basic_vtable; // it could be a call across boundaries, but still for the same type - return (descriptor == other) || has_value(other()); + return (vtable == other) || has_value(type_id()); } /**