From 507bafdd9cd122f484cc328e977319ef9008c7f3 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Tue, 22 Feb 2022 12:15:09 +0100 Subject: [PATCH] any/meta_any: revert changes to introduce ::hash --- docs/md/core.md | 24 ------------------- src/entt/core/any.hpp | 42 ---------------------------------- src/entt/core/type_traits.hpp | 25 -------------------- src/entt/meta/meta.hpp | 23 ------------------- test/entt/core/any.cpp | 27 ---------------------- test/entt/core/type_traits.cpp | 9 -------- test/entt/meta/meta_any.cpp | 27 ---------------------- 7 files changed, 177 deletions(-) diff --git a/docs/md/core.md b/docs/md/core.md index b77012f1e..5e79e0723 100644 --- a/docs/md/core.md +++ b/docs/md/core.md @@ -7,7 +7,6 @@ * [Introduction](#introduction) * [Any as in any type](#any-as-in-any-type) - * [Hashing of any objects](#hashing-of-any-objects) * [Small buffer optimization](#small-buffer-optimization) * [Alignment requirement](#alignment-requirement) * [Compressed pair](#compressed-pair) @@ -168,29 +167,6 @@ The only difference is that, in the case of `EnTT`, these won't raise exceptions but will only trigger an assert in debug mode, otherwise resulting in undefined behavior in case of misuse in release mode. -## Hashing of any objects - -As for the `any` class, the hashing topic deserves a section of its own.
-It's indeed possible to extract the hash value (as in `std::hash`) of an object -managed by `any`: - -```cpp -const std::size_t hash = any.hash(); -``` - -However, there are some limitations: - -* The instance of `any` **must** not be empty, otherwise the returned value is - that of `std::hash{}(nullptr)`. - -* The underlying object **must** support this operation, otherwise the returned - value is that of `std::hash{}(nullptr)`. - -Unfortunately, it's not possible to trigger a compile-time error in these cases. -This would prevent users from using non-hashable types with `any`.
-A compromise has therefore been made that could change over time but which -appears to be acceptable today for the conceivable uses of this feature. - ## Small buffer optimization The `any` class uses a technique called _small buffer optimization_ to reduce diff --git a/src/entt/core/any.hpp b/src/entt/core/any.hpp index 4383766f3..9c595c0fb 100644 --- a/src/entt/core/any.hpp +++ b/src/entt/core/any.hpp @@ -2,7 +2,6 @@ #define ENTT_CORE_ANY_HPP #include -#include #include #include #include @@ -28,7 +27,6 @@ class basic_any { assign, destroy, compare, - hash, get }; @@ -96,12 +94,6 @@ class basic_any { } else { return (element == other) ? other : nullptr; } - case operation::hash: - if constexpr(is_std_hashable_v) { - *static_cast(const_cast(other)) = std::hash{}(*element); - return element; - } - break; case operation::get: return element; } @@ -388,23 +380,6 @@ public: return (mode == policy::owner); } - /** - * @brief Returns the hash value of the contained object. - * - * If the underlying object isn't _hashable_, the hash of its address is - * returned once converted to `const void *`. - * - * @return The hash value of the contained object or its address if any, - * `std::hash{}({})` otherwise. - */ - [[nodiscard]] std::size_t hash() const ENTT_NOEXCEPT { - if(std::size_t value{}; vtable && vtable(operation::hash, *this, &value)) { - return value; - } - - return std::hash{}(nullptr); - } - private: union { const void *instance; @@ -512,21 +487,4 @@ basic_any forward_as_any(Type &&value) { } // namespace entt -namespace std { - -/*! @brief `std::hash` specialization for `entt::any`. */ -template<> -struct hash { - /** - * @brief Returns the hash value of the parameter. - * @param any The object to return the hash for. - * @return The hash value of the parameter. - */ - [[nodiscard]] std::size_t operator()(const entt::any &any) const ENTT_NOEXCEPT { - return any.hash(); - } -}; - -} // namespace std - #endif diff --git a/src/entt/core/type_traits.hpp b/src/entt/core/type_traits.hpp index e2464d2ce..b8326d14f 100644 --- a/src/entt/core/type_traits.hpp +++ b/src/entt/core/type_traits.hpp @@ -2,7 +2,6 @@ #define ENTT_CORE_TYPE_TRAITS_HPP #include -#include #include #include #include @@ -592,30 +591,6 @@ struct is_equality_comparable() == template inline constexpr bool is_equality_comparable_v = is_equality_comparable::value; -/** - * @brief Provides the member constant `value` to true if a given type is - * _hashable_, false otherwise. - * @tparam Type The type to test. - */ -template -struct is_std_hashable: std::false_type {}; - -/*! @brief Specialization required to get around an issue with clang-cl. */ -template<> -struct is_std_hashable: std::false_type {}; - -/*! @copydoc is_std_hashable */ -template -struct is_std_hashable &>()(*std::declval())), std::size_t>>> - : std::true_type {}; - -/** - * @brief Helper variable template. - * @tparam Type The type to test. - */ -template -inline constexpr auto is_std_hashable_v = is_std_hashable::value; - /** * @brief Transcribes the constness of a type to another type. * @tparam To The type to which to transcribe the constness. diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 0840f7b93..7e1e50847 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -2,7 +2,6 @@ #define ENTT_META_META_HPP #include -#include #include #include #include @@ -564,11 +563,6 @@ public: return storage.owner(); } - /*! @copydoc any::hash */ - [[nodiscard]] std::size_t hash() const ENTT_NOEXCEPT { - return storage.hash(); - } - private: any storage; internal::meta_type_node *node; @@ -1844,21 +1838,4 @@ inline bool meta_associative_container::erase(meta_any key) { } // namespace entt -namespace std { - -/*! @brief `std::hash` specialization for `entt::meta_any`. */ -template<> -struct hash { - /** - * @brief Returns the hash value of the parameter. - * @param any The object to return the hash for. - * @return The hash value of the parameter. - */ - [[nodiscard]] std::size_t operator()(const entt::meta_any &any) const ENTT_NOEXCEPT { - return any.hash(); - } -}; - -} // namespace std - #endif diff --git a/test/entt/core/any.cpp b/test/entt/core/any.cpp index 218c8a75b..0fe8f81a2 100644 --- a/test/entt/core/any.cpp +++ b/test/entt/core/any.cpp @@ -1171,33 +1171,6 @@ TEST_F(Any, CompareVoid) { ASSERT_FALSE(entt::any{} != any); } -TEST_F(Any, Hashable) { - const int value = 42; - entt::any any{value}; - const entt::any ref{std::in_place_type, value}; - - ASSERT_TRUE(any); - ASSERT_TRUE(ref); - - ASSERT_EQ(any.hash(), std::hash{}(value)); - ASSERT_EQ(std::hash{}(value), std::hash{}(ref)); - ASSERT_EQ(ref.hash(), std::hash{}(any)); -} - -TEST_F(Any, NotHashable) { - const not_comparable value{}; - entt::any any{value}; - const entt::any ref{std::in_place_type, value}; - - ASSERT_TRUE(any); - ASSERT_TRUE(ref); - - ASSERT_EQ(any.hash(), std::hash{}(nullptr)); - ASSERT_EQ(std::hash{}(nullptr), std::hash{}(ref)); - ASSERT_EQ(ref.hash(), std::hash{}(any)); - ASSERT_EQ(any.hash(), entt::any{}.hash()); -} - TEST_F(Any, AnyCast) { entt::any any{42}; const auto &cany = any; diff --git a/test/entt/core/type_traits.cpp b/test/entt/core/type_traits.cpp index 8bd679b05..e85497ab2 100644 --- a/test/entt/core/type_traits.cpp +++ b/test/entt/core/type_traits.cpp @@ -165,15 +165,6 @@ TEST(IsEqualityComparable, Functionalities) { static_assert(!entt::is_equality_comparable_v); } -TEST(IsStdHashable, Functionalities) { - static_assert(entt::is_std_hashable_v); - static_assert(entt::is_std_hashable_v); - static_assert(entt::is_std_hashable_v); - static_assert(!entt::is_std_hashable_v); - static_assert(!entt::is_std_hashable_v); - static_assert(!entt::is_std_hashable_v); -} - TEST(ConstnessAs, Functionalities) { static_assert(std::is_same_v, int>); static_assert(std::is_same_v, int>); diff --git a/test/entt/meta/meta_any.cpp b/test/entt/meta/meta_any.cpp index 21d3399a8..1440b6073 100644 --- a/test/entt/meta/meta_any.cpp +++ b/test/entt/meta/meta_any.cpp @@ -1076,33 +1076,6 @@ TEST_F(MetaAny, CompareVoid) { ASSERT_TRUE(entt::meta_any{} != any); } -TEST_F(MetaAny, Hashable) { - const int value = 42; - entt::meta_any any{value}; - const entt::meta_any ref{std::in_place_type, value}; - - ASSERT_TRUE(any); - ASSERT_TRUE(ref); - - ASSERT_EQ(any.hash(), std::hash{}(value)); - ASSERT_EQ(std::hash{}(value), std::hash{}(ref)); - ASSERT_EQ(ref.hash(), std::hash{}(any)); -} - -TEST_F(MetaAny, NotHashable) { - const not_comparable_t value{}; - entt::meta_any any{value}; - const entt::meta_any ref{std::in_place_type, value}; - - ASSERT_TRUE(any); - ASSERT_TRUE(ref); - - ASSERT_EQ(any.hash(), std::hash{}(nullptr)); - ASSERT_EQ(std::hash{}(nullptr), std::hash{}(ref)); - ASSERT_EQ(ref.hash(), std::hash{}(any)); - ASSERT_EQ(any.hash(), entt::any{}.hash()); -} - TEST_F(MetaAny, TryCast) { entt::meta_any any{fat_t{}};