summaryrefslogtreecommitdiff
path: root/absl/container/internal/hash_policy_traits_test.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2024-01-31 13:45:52 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2024-01-31 13:46:58 -0800
commit4c7e7c7d94eaaa3bff3142c257d880a468a35934 (patch)
treeb8418ca1620a45c7c772945194e9537165ac13f4 /absl/container/internal/hash_policy_traits_test.cc
parent780bfc194d807dbd56363635ca40bf96743aa00b (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.cc64
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