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 uint32_t murmur3(uint32_t h) {
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 uint64_t splitmix64(uint64_t h) {
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 size_t hash(size_t h) {
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> struct FNV1 {};
47
48template<> struct FNV1<4> {
49 static const uint32_t offset = UINT32_C(2166136261);
50 static const uint32_t prime = UINT32_C(16777619);
51};
52
53template<> struct FNV1<8> {
54 static const uint64_t offset = UINT64_C(14695981039346656037);
55 static const uint64_t prime = UINT64_C(1099511628211);
56};
57
58template<class T> size_t hash_combine(size_t seed, T v) {
59 static_assert(std::is_signed<T>::value || std::is_unsigned<T>::value, "please provide your own hash function");
60
61 size_t val = v;
62 for (size_t i = 0; i < sizeof(T); ++i) {
63 size_t octet = val & size_t(0xff); // extract lower 8 bits
64 seed ^= octet;
65 seed *= FNV1<sizeof(size_t)>::prime;
66 val >>= size_t(8);
67 }
68 return seed;
69}
70
71inline size_t hash_begin() { return FNV1<sizeof(size_t)>::offset; }
72
73template<class T> size_t hash_begin(T val) { return hash_combine(hash_begin(), val); }
74///@}
75
76} // namespace mim
Definition cfg.h:11
uint64_t splitmix64(uint64_t h)
Definition hash.h:23
uint32_t murmur3(uint32_t h)
Definition hash.h:14
size_t hash_combine(size_t seed, T v)
Definition hash.h:58
size_t hash(size_t h)
Definition hash.h:32
size_t hash_begin()
Definition hash.h:71