7#include <unordered_map>
8#include <unordered_set>
83inline uint32_t rotate(uint32_t value, uint32_t offset)
85 return (value << offset) | (value >> (32 - offset));
95 std::uint32_t a, b, c;
159 void feed(std::uint32_t value)
161 assert(pending_values != -1);
162 if (pending_values == 3) {
166 if (pending_values == 0) {
169 }
else if (pending_values == 1) {
172 }
else if (pending_values == 2) {
183 std::uint32_t get_hash32()
185 assert(pending_values != -1);
186 if (pending_values) {
202 std::uint64_t get_hash64()
204 assert(pending_values != -1);
205 if (pending_values) {
210 return (
static_cast<std::uint64_t
>(b) << 32) | c;
221 sizeof(int) ==
sizeof(std::uint32_t),
222 "int and uint32_t have different sizes");
225 sizeof(
unsigned int) ==
sizeof(std::uint32_t),
226 "unsigned int and uint32_t have different sizes");
229inline void feed_integer(HashState& hash_state, I value)
231 if constexpr (
sizeof(I) ==
sizeof(std::uint32_t)) {
232 hash_state.feed(
static_cast<std::uint32_t
>(value));
234 hash_state.feed(
static_cast<std::uint32_t
>(value));
236 hash_state.feed(
static_cast<std::uint32_t
>(value));
240inline void feed(HashState& hash_state,
int value)
242 feed_integer(hash_state, value);
245inline void feed(HashState& hash_state,
long int value)
247 feed_integer(hash_state, value);
250inline void feed(HashState& hash_state,
long long int value)
252 feed_integer(hash_state, value);
255inline void feed(HashState& hash_state,
unsigned int value)
257 feed_integer(hash_state, value);
260inline void feed(HashState& hash_state,
unsigned long int value)
262 feed_integer(hash_state, value);
265inline void feed(HashState& hash_state,
unsigned long long int value)
267 feed_integer(hash_state, value);
271void feed(HashState& hash_state,
const T* p)
275 feed(hash_state,
reinterpret_cast<std::uint64_t
>(p));
278template <
typename T1,
typename T2>
279void feed(HashState& hash_state,
const std::pair<T1, T2>& p)
281 feed(hash_state, p.first);
282 feed(hash_state, p.second);
286void feed(HashState& hash_state,
const std::vector<T>& vec)
295 feed(hash_state,
static_cast<uint64_t
>(vec.size()));
296 for (
const T& item : vec) {
297 feed(hash_state, item);
302void feed_iterable(HashState& hash_state, T begin, T end)
311 for (
auto it = begin; it != end; ++it) {
312 feed(hash_state, *it);
316template <
typename... T>
317void feed(HashState& hash_state,
const std::tuple<T...>& t)
320 [&](
auto&&... element) { ((feed(hash_state, element)), ...); },
332std::uint32_t get_hash32(
const T& value)
334 HashState hash_state;
335 feed(hash_state, value);
336 return hash_state.get_hash32();
340std::uint64_t get_hash64(
const T& value)
342 HashState hash_state;
343 feed(hash_state, value);
344 return hash_state.get_hash64();
348std::size_t get_hash(
const T& value)
350 return static_cast<std::size_t
>(get_hash64(value));
356 std::size_t operator()(
const T& val)
const {
return get_hash(val); }
367template <
typename T1,
typename T2>
368using HashMap = std::unordered_map<T1, T2, Hash<T1>>;
371using HashSet = std::unordered_set<T, Hash<T>>;