diff --git a/include/tsl/robin_growth_policy.h b/include/tsl/robin_growth_policy.h index b100bfc..6cb6b81 100644 --- a/include/tsl/robin_growth_policy.h +++ b/include/tsl/robin_growth_policy.h @@ -413,4 +413,35 @@ class prime_growth_policy { } // namespace rh } // namespace tsl +namespace tsl { + +/** + * Wrapper around std::hash which adds hash finalizer missing in libstd-c++ and + * libc++. It should be used with power_of_two_growth_policy. + */ +template +struct hash : public std::hash { + std::size_t operator()(const Key& key) const { + std::size_t h = std::hash::operator()(key); + +#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +#if SIZE_MAX >= ULLONG_MAX + // 64-bit finalizer from MurmurHash2 + h ^= h >> 47; + h *= 0xc6a4a7935bd1e995ull; + h ^= h >> 47; +#else + // 32-bit finalizer from MurmurHash2 + h ^= h >> 13; + h *= 0x5bd1e995u; + h ^= h >> 15; +#endif +#endif + + return h; + } +}; + +} // namespace tsl + #endif diff --git a/include/tsl/robin_hash.h b/include/tsl/robin_hash.h index 03d23a9..d60b21a 100644 --- a/include/tsl/robin_hash.h +++ b/include/tsl/robin_hash.h @@ -403,7 +403,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy { is_power_of_two_policy::value) && // Don't store the hash for primitive types with default hash. (!std::is_arithmetic::value || - !std::is_same>::value)); + !std::is_same>::value)); /** * Only use the stored hash on lookup if we are explicitly asked. We are not diff --git a/include/tsl/robin_map.h b/include/tsl/robin_map.h index b594810..1ce02f8 100644 --- a/include/tsl/robin_map.h +++ b/include/tsl/robin_map.h @@ -83,7 +83,7 @@ namespace tsl { * insert, invalidate the iterators. * - erase: always invalidate the iterators. */ -template , +template , class KeyEqual = std::equal_to, class Allocator = std::allocator>, bool StoreHash = false, @@ -803,7 +803,7 @@ class robin_map { * Same as `tsl::robin_map`. */ -template , +template , class KeyEqual = std::equal_to, class Allocator = std::allocator>, bool StoreHash = false> diff --git a/include/tsl/robin_set.h b/include/tsl/robin_set.h index e115007..03c9c78 100644 --- a/include/tsl/robin_set.h +++ b/include/tsl/robin_set.h @@ -83,7 +83,7 @@ namespace tsl { * insert, invalidate the iterators. * - erase: always invalidate the iterators. */ -template , +template , class KeyEqual = std::equal_to, class Allocator = std::allocator, bool StoreHash = false, class GrowthPolicy = tsl::rh::power_of_two_growth_policy<2>> @@ -657,7 +657,7 @@ class robin_set { * Same as `tsl::robin_set`. */ -template , +template , class KeyEqual = std::equal_to, class Allocator = std::allocator, bool StoreHash = false> using robin_pg_set = robin_set; + Set set; + + for (uint64_t i = 0; i < nb_values; i++) { + uint64_t hash = set.hash_function()(uint64_t(i) << shift); + set.insert(hash & 0xFFFFFF); + } + + double imageRatio = double(set.size()) / nb_values; + BOOST_CHECK(imageRatio >= 0.9); +} + BOOST_AUTO_TEST_SUITE_END()