diff options
author | Abseil Team <absl-team@google.com> | 2024-01-31 13:45:52 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-01-31 13:46:58 -0800 |
commit | 4c7e7c7d94eaaa3bff3142c257d880a468a35934 (patch) | |
tree | b8418ca1620a45c7c772945194e9537165ac13f4 /absl/container/internal/hash_policy_traits_test.cc | |
parent | 780bfc194d807dbd56363635ca40bf96743aa00b (diff) |
Type erased hash_slot_fn that depends only on key types (and hash function).
PiperOrigin-RevId: 603148301
Change-Id: Ie2e5702995c9e1ef4d5aaab23bc89a1eb5007a86
Diffstat (limited to 'absl/container/internal/hash_policy_traits_test.cc')
-rw-r--r-- | absl/container/internal/hash_policy_traits_test.cc | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/absl/container/internal/hash_policy_traits_test.cc b/absl/container/internal/hash_policy_traits_test.cc index 82d7cc3a..2d2c7c2c 100644 --- a/absl/container/internal/hash_policy_traits_test.cc +++ b/absl/container/internal/hash_policy_traits_test.cc @@ -14,12 +14,14 @@ #include "absl/container/internal/hash_policy_traits.h" +#include <cstddef> #include <functional> #include <memory> #include <new> #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/container/internal/container_memory.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -42,6 +44,11 @@ struct PolicyWithoutOptionalOps { static int apply(int v) { return apply_impl(v); } static std::function<int(int)> apply_impl; static std::function<Slot&(Slot*)> value; + + template <class Hash> + static constexpr HashSlotFn get_hash_slot_fn() { + return nullptr; + } }; std::function<int(int)> PolicyWithoutOptionalOps::apply_impl; @@ -74,6 +81,63 @@ TEST_F(Test, value) { EXPECT_EQ(&b, &hash_policy_traits<PolicyWithoutOptionalOps>::value(&a)); } +struct Hash { + size_t operator()(Slot a) const { return static_cast<size_t>(a) * 5; } +}; + +struct PolicyNoHashFn { + using slot_type = Slot; + using key_type = Slot; + using init_type = Slot; + + static size_t* apply_called_count; + + static Slot& element(Slot* slot) { return *slot; } + template <typename Fn> + static size_t apply(const Fn& fn, int v) { + ++(*apply_called_count); + return fn(v); + } + + template <class Hash> + static constexpr HashSlotFn get_hash_slot_fn() { + return nullptr; + } +}; + +size_t* PolicyNoHashFn::apply_called_count; + +struct PolicyCustomHashFn : PolicyNoHashFn { + template <class Hash> + static constexpr HashSlotFn get_hash_slot_fn() { + return &TypeErasedApplyToSlotFn<Hash, int>; + } +}; + +TEST(HashTest, PolicyNoHashFn_get_hash_slot_fn) { + size_t apply_called_count = 0; + PolicyNoHashFn::apply_called_count = &apply_called_count; + + Hash hasher; + Slot value = 7; + auto* fn = hash_policy_traits<PolicyNoHashFn>::get_hash_slot_fn<Hash>(); + EXPECT_NE(fn, nullptr); + EXPECT_EQ(fn(&hasher, &value), hasher(value)); + EXPECT_EQ(apply_called_count, 1); +} + +TEST(HashTest, PolicyCustomHashFn_get_hash_slot_fn) { + size_t apply_called_count = 0; + PolicyNoHashFn::apply_called_count = &apply_called_count; + + Hash hasher; + Slot value = 7; + auto* fn = hash_policy_traits<PolicyCustomHashFn>::get_hash_slot_fn<Hash>(); + EXPECT_EQ(fn, PolicyCustomHashFn::get_hash_slot_fn<Hash>()); + EXPECT_EQ(fn(&hasher, &value), hasher(value)); + EXPECT_EQ(apply_called_count, 0); +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END |