aboutsummaryrefslogtreecommitdiff
path: root/absl/hash/internal/hash.h
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2021-11-17 10:01:24 -0800
committerdinord <dino.radakovich@gmail.com>2021-11-17 22:50:31 -0500
commit299f59cadda78dfaf71b2a35049b63911e8eff47 (patch)
tree1ae52c169d809eeaa6d91b996fd9f067c26a8f39 /absl/hash/internal/hash.h
parent9b924cedb6127dfb8f5d504a419dead2899fa777 (diff)
downloadabseil-299f59cadda78dfaf71b2a35049b63911e8eff47.tar.gz
abseil-299f59cadda78dfaf71b2a35049b63911e8eff47.tar.bz2
abseil-299f59cadda78dfaf71b2a35049b63911e8eff47.zip
Export of internal Abseil changes
-- 2130ba98c8359b08d97fb16d84dfd05687005dcf by Abseil Team <absl-team@google.com>: Tweaking the documentation of c_all_of to state the effect more directly. PiperOrigin-RevId: 410557900 -- 4732289bf4b56123fed113e36be4710b55c6a6c7 by Greg Falcon <gfalcon@google.com>: Improve the quality of absl::Hash<std::vector<bool>>. This previously dispatched to std::hash<vector<bool>>, which suffers from trivial collisions on many platforms. (They often hash the internal words but no size info, so that, e.g., {1, 1} and {1, 1, 0} collide.) Also extended the unit test to exercise this. PiperOrigin-RevId: 410329943 -- 1c5f3934230a7669f74c96b305251786a265e235 by Greg Falcon <gfalcon@google.com>: Add broader testing of absl hash contracts in the hash unit test. In particular, test that the hash erasure mechanism works. PiperOrigin-RevId: 410312738 -- 5e1923f527ed3d02f6752a5b38d5e1c17a4a146f by Derek Mauro <dmauro@google.com>: Internal change PiperOrigin-RevId: 410290663 -- 8c74bc962b3b98a5908017c345efc592393048ea by Martijn Vels <mvels@google.com>: Add Cord::CreateFlat() function PiperOrigin-RevId: 410260776 -- bd0de4e94c85620d3b8dd60fae367b730fc4cb34 by Evan Brown <ezb@google.com>: Rename node_hash_policy to node_slot_policy. Motivation: we can potentially reuse this code for node_btree_*. PiperOrigin-RevId: 410082271 GitOrigin-RevId: 2130ba98c8359b08d97fb16d84dfd05687005dcf Change-Id: Ie052084cf992dee250d8b2f388d39c4de0dcff40
Diffstat (limited to 'absl/hash/internal/hash.h')
-rw-r--r--absl/hash/internal/hash.h19
1 files changed, 17 insertions, 2 deletions
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index b1e33caf..97b68bad 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -502,10 +502,9 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
vector.size());
}
+// AbslHashValue special cases for hashing std::vector<bool>
#if defined(ABSL_IS_BIG_ENDIAN) && \
(defined(__GLIBCXX__) || defined(__GLIBCPP__))
-// AbslHashValue for hashing std::vector<bool>
-//
// std::hash in libstdc++ does not work correctly with vector<bool> on Big
// Endian platforms therefore we need to implement a custom AbslHashValue for
// it. More details on the bug:
@@ -521,6 +520,22 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
}
return H::combine(combiner.finalize(std::move(hash_state)), vector.size());
}
+#else
+// When not working around the libstdc++ bug above, we still have to contend
+// with the fact that std::hash<vector<bool>> is often poor quality, hashing
+// directly on the internal words and on no other state. On these platforms,
+// vector<bool>{1, 1} and vector<bool>{1, 1, 0} hash to the same value.
+//
+// Mixing in the size (as we do in our other vector<> implementations) on top
+// of the library-provided hash implementation avoids this QOI issue.
+template <typename H, typename T, typename Allocator>
+typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value,
+ H>::type
+AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
+ return H::combine(std::move(hash_state),
+ std::hash<std::vector<T, Allocator>>{}(vector),
+ vector.size());
+}
#endif
// -----------------------------------------------------------------------------