LeviLamina
Loading...
Searching...
No Matches
HashUtils.h
1#pragma once
2
3#include <compare>
4#include <span>
5#include <string_view>
6#include <type_traits>
7
8#include "ll/api/base/Meta.h"
9#include "ll/api/base/StdInt.h"
10
11namespace ll::inline utils::hash_utils {
12
14protected:
15 [[nodiscard]] constexpr explicit HashedIdBase(size_t hash) noexcept : hash(hash) {}
16
17public:
18 size_t hash;
19
20 [[nodiscard]] constexpr bool operator==(HashedIdBase const& other) const noexcept { return hash == other.hash; }
21
22 [[nodiscard]] constexpr std::strong_ordering operator<=>(HashedIdBase const& other) const noexcept {
23 return hash <=> other.hash;
24 }
25};
26
28 size_t seed;
29
30public:
31 [[nodiscard]] constexpr HashCombiner(size_t seed = 0) : seed(seed) {}
32
33 template <class T>
34 constexpr HashCombiner& add(T const& v) {
35 if constexpr (std::is_integral_v<T>) {
36 seed ^= v + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull);
37 } else {
38 seed ^= std::hash<T>{}(v) + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull);
39 }
40 return *this;
41 }
42
43 template <class T>
44 constexpr HashCombiner& addRange(T&& v) {
45 for (auto const& x : std::forward<T>(v)) {
46 this->add(x);
47 }
48 return *this;
49 }
50
51 [[nodiscard]] constexpr operator size_t() const { return seed; }
52 [[nodiscard]] constexpr size_t hash() const { return seed; }
53};
54
55[[nodiscard]] constexpr uint64 doHash(std::string_view x) {
56 // hash_64_fnv1a
57 uint64 hash = 0xcbf29ce484222325;
58 constexpr uint64 prime = 0x100000001b3;
59 for (char c : x) {
60 hash ^= c;
61 hash *= prime;
62 }
63 return hash;
64}
65
66[[nodiscard]] constexpr uint64 doHash2(std::string_view x) {
67 uint64 rval = 0;
68 for (size_t i = 0; i < x.size(); i++) {
69 rval ^= ((i & 1) == 0) ? (~((rval << 7) ^ x[i] ^ (rval >> 3))) : (~((rval << 11) ^ x[i] ^ (rval >> 5)));
70 }
71 return rval;
72}
73
74[[nodiscard]] constexpr uint64 doHash3(std::string_view x) {
75 uint64 rval = 5381;
76 for (char c : x) {
77 rval = ((rval << 5) + rval) + c;
78 }
79 return rval;
80}
81} // namespace ll::inline utils::hash_utils
82
83namespace ll::inline literals::inline hash_literals {
84[[nodiscard]] consteval uint64 operator""_h(char const* x, size_t len) { return ll::hash_utils::doHash({x, len}); }
85} // namespace ll::inline literals::inline hash_literals
86
87namespace std {
88template <class T>
89 requires(std::is_base_of_v<ll::hash_utils::HashedIdBase, T>)
90struct hash<T> {
91 size_t operator()(T const& id) const noexcept { return id.hash; }
92};
93} // namespace std
Definition HashUtils.h:27
Definition HashUtils.h:13
STL namespace.