67#include "smats/util/concepts.h"
78template <InvocableHashAlgorithm HashAlgorithm, Hashable<HashAlgorithm> T>
79void hash_append(HashAlgorithm& hasher,
const T& hashable)
noexcept {
80 hashable.
hash(hasher);
91 hasher(std::addressof(item),
sizeof(item));
104 hash_append(hasher,
reinterpret_cast<std::uintptr_t
>(item));
116 hasher(std::addressof(item),
sizeof(item));
126template <std::
floating_po
int T>
130 if (std::isnan(item)) {
131 std::cerr <<
"Hashing a NaN makes no sense, since they cannot compare as equal." << std::endl;
138 hasher(std::addressof(zero),
sizeof(zero));
140 hasher(std::addressof(item),
sizeof(item));
152template <
class Traits,
class Allocator>
154 hasher(item.data(), item.size());
174template <
class T1,
class T2>
175void hash_append(InvocableHashAlgorithm
auto& hasher,
const std::pair<T1, T2>& item)
noexcept;
188void hash_append(InvocableHashAlgorithm
auto& hasher,
const std::optional<T>& item)
noexcept;
202template <
class T1,
class T2,
class Compare,
class Allocator>
203void hash_append(InvocableHashAlgorithm
auto& hasher,
const std::map<T1, T2, Compare, Allocator>& item)
noexcept;
216template <
class Key,
class Compare,
class Allocator>
217void hash_append(InvocableHashAlgorithm
auto& hasher,
const std::set<Key, Compare, Allocator>& item)
noexcept;
221template <
class T1,
class T2>
238void hash_append_range(InvocableHashAlgorithm
auto& hasher, Iter begin, Iter end)
noexcept {
241 for (Iter iter = begin; iter != end; ++iter, ++count) {
248template <
class T1,
class T2,
class Compare,
class Allocator>
250 return hash_append_range(hasher, item.begin(), item.end());
252template <
class Key,
class Compare,
class Allocator>
254 return hash_append_range(hasher, item.begin(), item.end());
264template <
class HashAlgorithm>
266 using result_type =
typename HashAlgorithm::result_type;
269 result_type operator()(
const T& item)
const noexcept {
270 HashAlgorithm hasher;
273 return static_cast<result_type
>(hasher);
286 using result_type = size_t;
293 void operator()(
const void* data,
const size_t length)
noexcept {
294 const auto*
const begin =
static_cast<const uint8_t*
>(data);
295 const uint8_t*
const end = begin + length;
296 for (
const uint8_t* iter = begin; iter < end; ++iter) {
308 explicit constexpr operator size_t() const noexcept {
return hash_; }
311 static_assert(
sizeof(result_type) == (64 / 8),
"We require a 64-bit size_t");
312 result_type
hash_{0xcbf29ce484222325u};
326 using Func = std::function<void(
const void*,
size_t)>;
335 if (!
static_cast<bool>(
func_))
throw std::runtime_error(
"The function must be non-empty");
static constexpr size_t k_fnv_prime
FNV-1a prime.
Definition hash.hpp:313
constexpr void add_byte(const uint8_t byte) noexcept
Definition hash.hpp:305
result_type hash_
FNV-1a offset basis.
Definition hash.hpp:312
void operator()(const void *data, const size_t length) noexcept
Definition hash.hpp:293
void hash_append(HashAlgorithm &hasher, const T &hashable) noexcept
Definition hash.hpp:79
typename DefaultHashAlgorithm::result_type result_type
Necessary to be accepted by hash_append.
Definition hash.hpp:327
const Func func_
Concrete hash algorithm implementation.
Definition hash.hpp:352
DelegatingHasher(Func func)
Definition hash.hpp:334
void operator()(const void *data, size_t length) noexcept
Definition hash.hpp:342