FE
0.13.1
Header-only C++ frontend library
Toggle main menu visibility
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <concepts>
4
#include <cstddef>
5
#include <cstdint>
6
7
namespace
fe
{
8
9
static_assert
(
sizeof
(size_t) == 4 ||
sizeof
(size_t) == 8,
"unsupported sizeof(size_t)"
);
10
11
/// @name Bit Mixers
12
/// These finalizers scramble a single word.
13
/// They are bijective, i.e., they don't introduce any collisions on their own - they merely spread the input bits.
14
///@{
15
16
/// [MurmurHash3](https://en.wikipedia.org/wiki/MurmurHash)'s 32-bit finalizer `fmix32`.
17
constexpr
uint32_t
murmur3
(uint32_t h)
noexcept
{
18
h ^= h >> 16;
19
h *= UINT32_C(0x85ebca6b);
20
h ^= h >> 13;
21
h *= UINT32_C(0xc2b2ae35);
22
h ^= h >> 16;
23
return
h;
24
}
25
26
/// [SplitMix64](https://prng.di.unimi.it/splitmix64.c)'s 64-bit finalizer.
27
constexpr
uint64_t
splitmix64
(uint64_t h)
noexcept
{
28
h ^= h >> 30;
29
h *= UINT64_C(0xbf58476d1ce4e5b9);
30
h ^= h >> 27;
31
h *= UINT64_C(0x94d049bb133111eb);
32
h ^= h >> 31;
33
return
h;
34
}
35
36
/// Mixes @p h with murmur3 or splitmix64 - whichever matches `sizeof(size_t)`.
37
constexpr
size_t
hash
(
size_t
h)
noexcept
{
38
if
constexpr
(
sizeof
(size_t) == 4)
39
return
size_t
(
murmur3
(uint32_t(h)));
40
else
41
return
size_t(
splitmix64
(uint64_t(h)));
42
}
43
///@}
44
45
/// @name FNV-1 Hash
46
/// See [Wikipedia](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1_hash).
47
/// Use hash_begin to seed a hash chain and hash_combine to fold in one value after another:
48
/// ```
49
/// auto h = fe::hash_begin(x);
50
/// for (auto elem : elems) h = fe::hash_combine(h, elem);
51
/// ```
52
/// @note These hashes are *not* stable:
53
/// they differ between 32- and 64-bit builds and may change between fe releases.
54
/// Never serialize them and never rely on the iteration order they induce.
55
///@{
56
57
// clang-format off
58
/// FNV-1 [magic numbers](http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-var) for `sizeof(size_t)`.
59
inline
constexpr
size_t
fnv1_offset
=
sizeof
(size_t) == 4 ?
size_t
(UINT32_C(2166136261)) : size_t(UINT64_C(14695981039346656037));
60
inline
constexpr
size_t
fnv1_prime
=
sizeof
(size_t) == 4 ?
size_t
(UINT32_C( 16777619)) : size_t(UINT64_C( 1099511628211));
61
// clang-format on
62
63
/// Seeds a hash chain with the FNV-1 offset basis.
64
constexpr
size_t
hash_begin
() noexcept {
return
fnv1_offset
; }
65
66
/// Mixes @p v into @p seed word-wise, reusing the FNV-1 prime as multiplier.
67
template
<std::
int
egral T>
68
constexpr
size_t
hash_combine
(
size_t
seed, T v)
noexcept
{
69
return
hash
(seed ^ (
size_t
(v) *
fnv1_prime
));
70
}
71
72
/// Shorthand for `hash_combine(hash_begin(), v)`.
73
template
<std::
int
egral T>
74
constexpr
size_t
hash_begin
(T v)
noexcept
{
75
return
hash_combine
(
hash_begin
(), v);
76
}
77
///@}
78
79
}
// namespace fe
fe
Definition
algo.h:17
fe::hash
constexpr size_t hash(size_t h) noexcept
Mixes h with murmur3 or splitmix64 - whichever matches sizeof(size_t).
Definition
hash.h:37
fe::fnv1_offset
constexpr size_t fnv1_offset
FNV-1 magic numbers for sizeof(size_t).
Definition
hash.h:59
fe::hash_begin
constexpr size_t hash_begin() noexcept
Seeds a hash chain with the FNV-1 offset basis.
Definition
hash.h:64
fe::fnv1_prime
constexpr size_t fnv1_prime
Definition
hash.h:60
fe::murmur3
constexpr uint32_t murmur3(uint32_t h) noexcept
MurmurHash3's 32-bit finalizer fmix32.
Definition
hash.h:17
fe::hash_combine
constexpr size_t hash_combine(size_t seed, T v) noexcept
Mixes v into seed word-wise, reusing the FNV-1 prime as multiplier.
Definition
hash.h:68
fe::splitmix64
constexpr uint64_t splitmix64(uint64_t h) noexcept
SplitMix64's 64-bit finalizer.
Definition
hash.h:27
fe
hash.h
Generated by
1.18.0