LeviLamina
Loading...
Searching...
No Matches
HashUtils.h
1#pragma once
2
3#include <compare>
4#include <string_view>
5#include <type_traits>
6#include <vector>
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
27template <class T>
28constexpr void hashCombine(T const& v, size_t& seed) {
29 seed ^= v + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull);
30}
31
32template <class T>
33constexpr size_t hashCombineTo(T const& v, size_t seed) {
34 seed ^= v + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull);
35 return seed;
36}
37
38[[nodiscard]] constexpr uint64 doHash(std::string_view x) {
39 // hash_64_fnv1a
40 uint64 hash = 0xcbf29ce484222325;
41 constexpr uint64 prime = 0x100000001b3;
42 for (char c : x) {
43 hash ^= c;
44 hash *= prime;
45 }
46 return hash;
47}
48
49[[nodiscard]] constexpr uint64 doHash2(std::string_view x) {
50 uint64 rval = 0;
51 for (size_t i = 0; i < x.size(); i++) {
52 rval ^= ((i & 1) == 0) ? (~((rval << 7) ^ x[i] ^ (rval >> 3))) : (~((rval << 11) ^ x[i] ^ (rval >> 5)));
53 }
54 return rval;
55}
56
57[[nodiscard]] constexpr uint64 doHash3(std::string_view x) {
58 uint64 rval = 5381;
59 for (char c : x) {
60 rval = ((rval << 5) + rval) + c;
61 }
62 return rval;
63}
64
65template <class T>
66[[nodiscard]] constexpr uint64 hashType(std::vector<T> const& v) {
67 size_t seed = v.size();
68 for (auto const& x : v) {
69 hashCombine(std::hash<T>{}(x), seed);
70 }
71 return seed;
72}
73} // namespace ll::inline utils::hash_utils
74
75namespace ll::inline literals::inline hash_literals {
76[[nodiscard]] consteval uint64 operator""_h(char const* x, size_t len) { return ll::hash_utils::doHash({x, len}); }
77} // namespace ll::inline literals::inline hash_literals
78
79namespace std {
80template <class T>
81 requires(std::is_base_of_v<ll::hash_utils::HashedIdBase, T>)
82struct hash<T> {
83 size_t operator()(T const& id) const noexcept { return id.hash; }
84};
85} // namespace std
Definition HashUtils.h:13
STL namespace.