MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5
6#include <type_traits>
7
8namespace mim {
9
10/// @name Simple Hash
11/// See [Wikipedia](https://en.wikipedia.org/wiki/MurmurHash).
12///@{
13/// Use for a single value to hash.
14inline constexpr uint32_t murmur3(uint32_t h) noexcept {
15 h ^= h >> UINT32_C(16);
16 h *= UINT32_C(0x85ebca6b);
17 h ^= h >> UINT32_C(13);
18 h *= UINT32_C(0xc2b2ae35);
19 h ^= h >> UINT32_C(16);
20 return h;
21}
22
23inline constexpr uint64_t splitmix64(uint64_t h) noexcept {
24 h ^= h >> UINT64_C(30);
25 h *= UINT64_C(0xbf58476d1ce4e5b9);
26 h ^= h >> UINT64_C(27);
27 h *= UINT64_C(0x94d049bb133111eb);
28 h ^= h >> UINT64_C(31);
29 return h;
30}
31
32inline constexpr size_t hash(size_t h) noexcept {
33 if constexpr (sizeof(size_t) == 4)
34 return murmur3(h);
35 else if constexpr (sizeof(size_t) == 8)
36 return splitmix64(h);
37 else
38 static_assert("unsupported size of size_t");
39}
40///@}
41
42/// @name FNV-1 Hash
43/// See [Wikipedia](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1_hash).
44///@{
45/// [Magic numbers](http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-var) for FNV-1 hash.
46template<size_t>
47struct FNV1 {};
48
49template<>
50struct FNV1<4> {
51 static const uint32_t offset = UINT32_C(2166136261);
52 static const uint32_t prime = UINT32_C(16777619);
53};
54
55template<>
56struct FNV1<8> {
57 static const uint64_t offset = UINT64_C(14695981039346656037);
58 static const uint64_t prime = UINT64_C(1099511628211);
59};
60
61template<class T>
62constexpr size_t hash_combine(size_t seed, T v) noexcept {
63 static_assert(std::is_signed<T>::value || std::is_unsigned<T>::value, "please provide your own hash function");
64
65 size_t val = v;
66 for (size_t i = 0; i < sizeof(T); ++i) {
67 size_t octet = val & size_t(0xff); // extract lower 8 bits
68 seed ^= octet;
69 seed *= FNV1<sizeof(size_t)>::prime;
70 val >>= size_t(8);
71 }
72 return seed;
73}
74
75inline consteval size_t hash_begin() noexcept { return FNV1<sizeof(size_t)>::offset; }
76
77template<class T>
78constexpr size_t hash_begin(T val) noexcept {
79 return hash_combine(hash_begin(), val);
80}
81///@}
82
83} // namespace mim
Definition ast.h:14
constexpr size_t hash_combine(size_t seed, T v) noexcept
Definition hash.h:62
constexpr uint64_t splitmix64(uint64_t h) noexcept
Definition hash.h:23
consteval size_t hash_begin() noexcept
Definition hash.h:75
constexpr size_t hash(size_t h) noexcept
Definition hash.h:32
constexpr uint32_t murmur3(uint32_t h) noexcept
Definition hash.h:14
static const uint32_t offset
Definition hash.h:51
static const uint32_t prime
Definition hash.h:52
static const uint64_t offset
Definition hash.h:57
static const uint64_t prime
Definition hash.h:58