aboutsummaryrefslogtreecommitdiff
path: root/absl/container/internal/hash_policy_traits.h
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2024-01-31 13:45:52 -0800
committerCopybara-Service <copybara-worker@google.com>2024-01-31 13:46:58 -0800
commit4c7e7c7d94eaaa3bff3142c257d880a468a35934 (patch)
treeb8418ca1620a45c7c772945194e9537165ac13f4 /absl/container/internal/hash_policy_traits.h
parent780bfc194d807dbd56363635ca40bf96743aa00b (diff)
downloadabseil-4c7e7c7d94eaaa3bff3142c257d880a468a35934.tar.gz
abseil-4c7e7c7d94eaaa3bff3142c257d880a468a35934.tar.bz2
abseil-4c7e7c7d94eaaa3bff3142c257d880a468a35934.zip
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.h')
-rw-r--r--absl/container/internal/hash_policy_traits.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h
index 164ec123..86ffd1be 100644
--- a/absl/container/internal/hash_policy_traits.h
+++ b/absl/container/internal/hash_policy_traits.h
@@ -148,6 +148,41 @@ struct hash_policy_traits : common_policy_traits<Policy> {
static auto value(T* elem) -> decltype(P::value(elem)) {
return P::value(elem);
}
+
+ using HashSlotFn = size_t (*)(const void* hash_fn, void* slot);
+
+ template <class Hash>
+ static constexpr HashSlotFn get_hash_slot_fn() {
+// get_hash_slot_fn may return nullptr to signal that non type erased function
+// should be used. GCC warns against comparing function address with nullptr.
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+// silent error: the address of * will never be NULL [-Werror=address]
+#pragma GCC diagnostic ignored "-Waddress"
+#endif
+ return Policy::template get_hash_slot_fn<Hash>() == nullptr
+ ? &hash_slot_fn_non_type_erased<Hash>
+ : Policy::template get_hash_slot_fn<Hash>();
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ }
+
+ private:
+ template <class Hash>
+ struct HashElement {
+ template <class K, class... Args>
+ size_t operator()(const K& key, Args&&...) const {
+ return h(key);
+ }
+ const Hash& h;
+ };
+
+ template <class Hash>
+ static size_t hash_slot_fn_non_type_erased(const void* hash_fn, void* slot) {
+ return Policy::apply(HashElement<Hash>{*static_cast<const Hash*>(hash_fn)},
+ Policy::element(static_cast<slot_type*>(slot)));
+ }
};
} // namespace container_internal