1#ifndef DICE_HASH_DICEHASHPOLICIES_HPP
2#define DICE_HASH_DICEHASHPOLICIES_HPP
4#include "martinus_robinhood_hash.hpp"
11namespace dice::hash::Policies {
14 std::is_convertible_v<
decltype(T::ErrorValue), std::size_t>
15 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<int>),
int>
16 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<long>),
long>
17 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<std::size_t>), std::size_t>
18 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_bytes),
void const *, std::size_t>
19 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_combine), std::initializer_list<std::size_t>>
20 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_invertible_combine), std::initializer_list<std::size_t>>
21 &&std::is_nothrow_constructible_v<typename T::HashState, std::size_t>
22 &&std::is_nothrow_invocable_r_v<
void,
decltype(&T::HashState::add),
typename T::HashState &, std::size_t>
23 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(&T::HashState::digest),
typename T::HashState &>;
26 inline static constexpr uint64_t kSeed = 0xe17a1465UL;
27 inline static constexpr uint64_t kWyhashSalt[4] = {
28 dice::hash::wyhash::_wyp[0],
29 dice::hash::wyhash::_wyp[1],
30 dice::hash::wyhash::_wyp[2],
31 dice::hash::wyhash::_wyp[3]
33 inline static constexpr std::size_t ErrorValue = kSeed;
36 static std::size_t hash_fundamental(T x)
noexcept {
37 if constexpr (std::is_integral_v<T>) {
38 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash64(kSeed, x));
40 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash(&x,
sizeof(T), kSeed, kWyhashSalt));
43 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
44 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash(ptr, len, kSeed, kWyhashSalt));
47 static std::size_t hash_combine(std::initializer_list<size_t> hashes)
noexcept {
48 uint64_t state = kSeed;
49 for (
auto hash : hashes) {
50 state = dice::hash::wyhash::_wymix(state, hash);
52 return static_cast<std::size_t
>(state);
55 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
56 std::size_t result = 0;
57 for (
auto hash : hashes) {
58 result = result xor hash;
65 uint64_t state = kSeed;
67 explicit HashState(std::size_t)
noexcept {}
68 void add (std::size_t hash)
noexcept {
69 state = dice::hash::wyhash::_wymix(state,
static_cast<uint64_t
>(hash));
71 [[nodiscard]] std::size_t digest()
noexcept {
72 return static_cast<std::size_t
>(state);
79 inline static constexpr std::size_t size_t_bits = 8 *
sizeof(std::size_t);
80 inline static constexpr std::size_t seed = std::size_t(0xA24BAED4963EE407UL);
81 inline static constexpr std::size_t ErrorValue = seed;
84 static std::size_t hash_fundamental(T x)
noexcept {
85 return hash_bytes(&x,
sizeof(x));
87 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
88 return xxh::xxhash3<size_t_bits>(ptr, len, seed);
90 static std::size_t hash_combine(std::initializer_list<std::size_t> hashes)
noexcept {
91 return xxh::xxhash3<size_t_bits>(hashes, seed);
93 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
94 std::size_t result = 0;
95 for (
auto hash : hashes) {
96 result = result xor hash;
105 explicit HashState(std::size_t)
noexcept {}
107 void add(std::size_t hash)
noexcept {
108 hash_state.update(&hash,
sizeof(std::size_t));
110 [[nodiscard]] std::size_t digest() noexcept {
111 return hash_state.digest();
118 static constexpr std::size_t ErrorValue = dice::hash::martinus::seed;
120 static std::size_t hash_fundamental(T x)
noexcept {
121 if constexpr (
sizeof(std::decay_t<T>) ==
sizeof(
size_t)) {
122 return dice::hash::martinus::hash_int(*
reinterpret_cast<size_t const *
>(&x));
123 }
else if constexpr (
sizeof(std::decay_t<T>) >
sizeof(
size_t) or std::is_floating_point_v<std::decay_t<T>>) {
124 return hash_bytes(&x,
sizeof(x));
126 return dice::hash::martinus::hash_int(
static_cast<size_t>(x));
129 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
130 return dice::hash::martinus::hash_bytes(ptr, len);
132 static std::size_t hash_combine(std::initializer_list<size_t> hashes)
noexcept {
133 return dice::hash::martinus::hash_combine(hashes);
135 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
136 std::size_t result = 0;
137 for (
auto hash : hashes) {
138 result = result xor hash;
147 explicit HashState(std::size_t size) noexcept : state(size) {}
148 void add(std::size_t hash)
noexcept {
151 [[nodiscard]] std::size_t digest()
noexcept {
152 return state.digest();
Definition DiceHashPolicies.hpp:142
Definition DiceHashPolicies.hpp:63
Definition martinus_robinhood_hash.hpp:136
Definition xxhash.hpp:1744
Definition DiceHashPolicies.hpp:13
Definition DiceHashPolicies.hpp:117
Definition DiceHashPolicies.hpp:25