dice-hash
Hash function for stl types and container
Loading...
Searching...
No Matches
DiceHash.hpp
Go to the documentation of this file.
1#ifndef DICE_HASH_DICEHASH_HPP
2#define DICE_HASH_DICEHASH_HPP
3
13#include "dice/hash/internal/DiceHashPolicies.hpp"
14#include <cstring>
15#include <map>
16#include <memory>
17#include <set>
18#include <span>
19#include <string>
20#include <string_view>
21#include <tuple>
22#include <unordered_map>
23#include <unordered_set>
24#include <utility>
25#include <variant>
26#include <vector>
27
31namespace dice::hash {
32
38 template<Policies::HashPolicy Policy, typename T>
46 template<typename>
47 struct AlwaysFalse : std::false_type {};
48
54 static std::size_t dice_hash(T const &) noexcept {
55 static_assert(AlwaysFalse<T>::value,
56 "The hash function is not defined for this type. You need to add an implementation yourself");
57 return 0;
58 }
59 };
60
64 template<Policies::HashPolicy Policy>
66 private:
75 template<typename Container>
76 static std::size_t dice_hash_ordered_container(Container const &container) noexcept {
77 typename Policy::HashState hash_state(container.size());
78 std::size_t item_hash;
79 for (const auto &item : container) {
80 item_hash = dice_hash(item);
81 hash_state.add(item_hash);
82 }
83 return hash_state.digest();
84 }
85
95 template<typename Container>
96 static std::size_t dice_hash_unordered_container(Container const &container) noexcept {
97 std::size_t h{};
98 for (auto const &it : container) {
99 h = Policy::hash_invertible_combine({h, dice_hash(it)});
100 }
101 return h;
102 }
103
112 template<typename... TupleArgs, std::size_t... ids>
113 static std::size_t dice_hash_tuple(std::tuple<TupleArgs...> const &tuple, std::index_sequence<ids...> const &) {
114 return Policy::hash_combine({dice_hash(std::get<ids>(tuple))...});
115 }
116
117 template<typename T>
118 static constexpr bool is_fundamental = std::is_fundamental_v<T> || std::is_same_v<std::remove_cv_t<T>, std::byte>;
119
120 public:
128 template<typename T>
129 static std::size_t dice_hash(T const &t) noexcept {
131 }
132
138 template<typename T>
139 requires is_fundamental<std::decay_t<T>> static std::size_t dice_hash(T const &fundamental) noexcept {
140 return Policy::hash_fundamental(fundamental);
141 }
142
148 template<typename CharT>
149 static std::size_t dice_hash(std::basic_string<CharT> const &str) noexcept {
150 return Policy::hash_bytes(str.data(), sizeof(CharT) * str.size());
151 }
152
158 template<typename CharT>
159 static std::size_t dice_hash(std::basic_string_view<CharT> const &sv) noexcept {
160 return Policy::hash_bytes(sv.data(), sizeof(CharT) * sv.size());
161 }
162
169 template<typename T>
170 static std::size_t dice_hash(T *ptr) noexcept {
171 return Policy::hash_fundamental(ptr);
172 }
173
180 template<typename T>
181 static std::size_t dice_hash(std::unique_ptr<T> const &ptr) noexcept {
182 return dice_hash(ptr.get());
183 }
184
191 template<typename T>
192 static std::size_t dice_hash(std::shared_ptr<T> const &ptr) noexcept {
193 return dice_hash(ptr.get());
194 }
195
203 template<typename T, std::size_t N>
204 static std::size_t dice_hash(std::array<T, N> const &arr) noexcept {
205 if constexpr (is_fundamental<T>) {
206 return Policy::hash_bytes(arr.data(), sizeof(T) * N);
207 } else {
208 return dice_hash_ordered_container(arr);
209 }
210 }
211
218 template<typename T>
219 static std::size_t dice_hash(std::vector<T> const &vec) noexcept {
220 if constexpr (is_fundamental<T>) {
221 static_assert(!std::is_same_v<std::decay_t<T>, bool>,
222 "vector of booleans has a special implementation which results in errors!");
223 return Policy::hash_bytes(vec.data(), sizeof(T) * vec.size());
224 } else {
225 return dice_hash_ordered_container(vec);
226 }
227 }
228
233 template<typename T, std::size_t Extent>
234 static std::size_t dice_hash(std::span<T, Extent> const &span) noexcept {
235 if constexpr (is_fundamental<T>) {
236 return Policy::hash_bytes(span.data(), span.size_bytes());
237 } else {
238 return dice_hash_ordered_container(span);
239 }
240 }
241
248 template<typename... TupleArgs>
249 static std::size_t dice_hash(std::tuple<TupleArgs...> const &tpl) noexcept {
250 return dice_hash_tuple(tpl, std::make_index_sequence<sizeof...(TupleArgs)>());
251 }
252
260 template<typename T, typename V>
261 static std::size_t dice_hash(std::pair<T, V> const &p) noexcept {
262 return Policy::hash_combine({dice_hash(p.first), dice_hash(p.second)});
263 }
264
270 static std::size_t dice_hash(std::monostate const &) noexcept {
271 return Policy::ErrorValue;
272 }
273
283 template<typename... VariantArgs>
284 static std::size_t dice_hash(std::variant<VariantArgs...> const &var) noexcept {
285 try {
286 return std::visit([]<typename T>(T &&arg) { return dice_hash(std::forward<T>(arg)); }, var);
287 } catch (std::bad_variant_access const &) {
288 return Policy::ErrorValue;
289 }
290 }
291
299 template<typename T>
300 requires is_ordered_container_v<T> static std::size_t dice_hash(T const &container) noexcept {
301 return dice_hash_ordered_container(container);
302 }
303
311 template<typename T>
312 requires is_unordered_container_v<T> static std::size_t dice_hash(T const &container) noexcept {
313 return dice_hash_unordered_container(container);
314 }
315 };
316
322 template<typename T, Policies::HashPolicy Policy = Policies::Martinus>
323 struct DiceHash : private Policy {
329 using Policy::hash_combine;
330
336 using Policy::hash_invertible_combine;
337
343 std::size_t operator()(T const &t) const noexcept {
345 }
346
352 [[nodiscard]] static constexpr bool is_faulty(std::size_t to_check) noexcept {
353 return to_check == Policy::ErrorValue;
354 }
355 };
356
357 template <typename T>
358 using DiceHashMartinus = DiceHash<T, Policies::Martinus>;
359 template <typename T>
360 using DiceHashxxh3 = DiceHash<T, Policies::xxh3>;
361 template <typename T>
362 using DiceHashwyhash = DiceHash<T, Policies::wyhash>;
363}// namespace dice::hash
364#endif//DICE_HASH_DICEHASH_HPP
Home of custom type traits for the diceHash.
Class which contains all dice_hash functions.
Definition DiceHash.hpp:65
static std::size_t dice_hash(T *ptr) noexcept
Implementation for raw pointers.
Definition DiceHash.hpp:170
static std::size_t dice_hash(std::vector< T > const &vec) noexcept
Implementation for vectors.
Definition DiceHash.hpp:219
static std::size_t dice_hash(std::array< T, N > const &arr) noexcept
Implementation for std arrays.
Definition DiceHash.hpp:204
static std::size_t dice_hash(std::span< T, Extent > const &span) noexcept
Implementation for byte spans.
Definition DiceHash.hpp:234
static std::size_t dice_hash(T const &t) noexcept
Base case for dice_hash.
Definition DiceHash.hpp:129
static std::size_t dice_hash(std::shared_ptr< T > const &ptr) noexcept
implementation for shared pointers.
Definition DiceHash.hpp:192
static std::size_t dice_hash(std::monostate const &) noexcept
Overload for std::monostate.
Definition DiceHash.hpp:270
static std::size_t dice_hash(std::unique_ptr< T > const &ptr) noexcept
Implementation for unique pointers.
Definition DiceHash.hpp:181
static std::size_t dice_hash(std::variant< VariantArgs... > const &var) noexcept
Implementation for variant.
Definition DiceHash.hpp:284
static std::size_t dice_hash(std::pair< T, V > const &p) noexcept
Implementation for pairs.
Definition DiceHash.hpp:261
static std::size_t dice_hash(std::basic_string< CharT > const &str) noexcept
Implementation for string types.
Definition DiceHash.hpp:149
static std::size_t dice_hash(std::tuple< TupleArgs... > const &tpl) noexcept
Implementation for tuples.
Definition DiceHash.hpp:249
static std::size_t dice_hash(T const &container) noexcept
Implementation for ordered container.
Definition DiceHash.hpp:300
static std::size_t dice_hash(T const &container) noexcept
Implementation for unordered container.
Definition DiceHash.hpp:312
static std::size_t dice_hash(std::basic_string_view< CharT > const &sv) noexcept
Implementation for string view.
Definition DiceHash.hpp:159
static std::size_t dice_hash(T const &fundamental) noexcept
Implementation for fundamentals.
Definition DiceHash.hpp:139
Home of the DiceHash.
Definition Blake3.hpp:12
Wrapper class for the dice::hash::dice_hash function.
Definition DiceHash.hpp:323
static constexpr bool is_faulty(std::size_t to_check) noexcept
Function to check if a hash is equal to an error value.
Definition DiceHash.hpp:352
std::size_t operator()(T const &t) const noexcept
Overloaded operator to calculate a hash.
Definition DiceHash.hpp:343
Helper type.
Definition DiceHash.hpp:47
Helper struct for defining the hash for custom structs.
Definition DiceHash.hpp:39
static std::size_t dice_hash(T const &) noexcept
Default implementation of the dice_hash function.
Definition DiceHash.hpp:54