1#ifndef DICE_HASH_DICEHASHPOLICIES_HPP
2#define DICE_HASH_DICEHASHPOLICIES_HPP
4#include "martinus_robinhood_hash.hpp"
9namespace dice::hash::Policies {
12 std::is_convertible_v<
decltype(T::ErrorValue), std::size_t>
13 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<int>),
int>
14 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<long>),
long>
15 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::template hash_fundamental<std::size_t>), std::size_t>
16 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_bytes),
void const *, std::size_t>
17 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_combine), std::initializer_list<std::size_t>>
18 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(T::hash_invertible_combine), std::initializer_list<std::size_t>>
19 &&std::is_nothrow_constructible_v<typename T::HashState, std::size_t>
20 &&std::is_nothrow_invocable_r_v<
void,
decltype(&T::HashState::add),
typename T::HashState &, std::size_t>
21 &&std::is_nothrow_invocable_r_v<std::size_t,
decltype(&T::HashState::digest),
typename T::HashState &>;
24 inline static constexpr uint64_t kSeed = 0xe17a1465UL;
25 inline static constexpr uint64_t kWyhashSalt[4] = {
26 dice::hash::wyhash::_wyp[0],
27 dice::hash::wyhash::_wyp[1],
28 dice::hash::wyhash::_wyp[2],
29 dice::hash::wyhash::_wyp[3]
31 inline static constexpr std::size_t ErrorValue = kSeed;
34 static std::size_t hash_fundamental(T x)
noexcept {
35 if constexpr (std::is_integral_v<T>) {
36 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash64(kSeed, x));
38 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash(&x,
sizeof(T), kSeed, kWyhashSalt));
41 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
42 return static_cast<std::size_t
>(dice::hash::wyhash::wyhash(ptr, len, kSeed, kWyhashSalt));
45 static std::size_t hash_combine(std::initializer_list<size_t> hashes)
noexcept {
46 uint64_t state = kSeed;
47 for (
auto hash : hashes) {
48 state = dice::hash::wyhash::_wymix(state, hash);
50 return static_cast<std::size_t
>(state);
53 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
54 std::size_t result = 0;
55 for (
auto hash : hashes) {
56 result = result xor hash;
63 uint64_t state = kSeed;
65 explicit HashState(std::size_t)
noexcept {}
66 void add (std::size_t hash)
noexcept {
67 state = dice::hash::wyhash::_wymix(state,
static_cast<uint64_t
>(hash));
69 [[nodiscard]] std::size_t digest()
noexcept {
70 return static_cast<std::size_t
>(state);
76 inline static constexpr std::size_t size_t_bits = 8 *
sizeof(std::size_t);
77 inline static constexpr std::size_t seed = std::size_t(0xA24BAED4963EE407UL);
78 inline static constexpr std::size_t ErrorValue = seed;
81 static std::size_t hash_fundamental(T x)
noexcept {
82 return hash_bytes(&x,
sizeof(x));
84 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
85 return xxh::xxhash3<size_t_bits>(ptr, len, seed);
87 static std::size_t hash_combine(std::initializer_list<std::size_t> hashes)
noexcept {
88 return xxh::xxhash3<size_t_bits>(hashes, seed);
90 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
91 std::size_t result = 0;
92 for (
auto hash : hashes) {
93 result = result xor hash;
102 explicit HashState(std::size_t)
noexcept {}
104 void add(std::size_t hash)
noexcept {
105 hash_state.update(&hash,
sizeof(std::size_t));
107 [[nodiscard]] std::size_t digest()
noexcept {
108 return hash_state.digest();
114 static constexpr std::size_t ErrorValue = dice::hash::martinus::seed;
116 static std::size_t hash_fundamental(T x)
noexcept {
117 if constexpr (
sizeof(std::decay_t<T>) ==
sizeof(
size_t)) {
118 return dice::hash::martinus::hash_int(*
reinterpret_cast<size_t const *
>(&x));
119 }
else if constexpr (
sizeof(std::decay_t<T>) >
sizeof(
size_t) or std::is_floating_point_v<std::decay_t<T>>) {
120 return hash_bytes(&x,
sizeof(x));
122 return dice::hash::martinus::hash_int(
static_cast<size_t>(x));
125 static std::size_t hash_bytes(
void const *ptr, std::size_t len)
noexcept {
126 return dice::hash::martinus::hash_bytes(ptr, len);
128 static std::size_t hash_combine(std::initializer_list<size_t> hashes)
noexcept {
129 return dice::hash::martinus::hash_combine(hashes);
131 static std::size_t hash_invertible_combine(std::initializer_list<size_t> hashes)
noexcept {
132 std::size_t result = 0;
133 for (
auto hash : hashes) {
134 result = result xor hash;
143 explicit HashState(std::size_t size) noexcept : state(size) {}
144 void add(std::size_t hash)
noexcept {
147 [[nodiscard]] std::size_t digest()
noexcept {
148 return state.digest();
Definition DiceHashPolicies.hpp:138
Definition DiceHashPolicies.hpp:61
Definition DiceHashPolicies.hpp:97
Definition martinus_robinhood_hash.hpp:136
Definition xxhash.hpp:1744
Definition DiceHashPolicies.hpp:11
Definition DiceHashPolicies.hpp:113
Definition DiceHashPolicies.hpp:23
Definition DiceHashPolicies.hpp:75