FE
0.16.1
Fast, Effecient FrontEnds
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
#include <functional>
8
#include <string>
9
#include <string_view>
10
11
#include <ankerl/unordered_dense.h>
12
13
namespace
fe
{
14
15
/// Folds @p v into @p seed like `ankerl::unordered_dense` hashes a tuple: one 128-bit multiply, halves xored.
16
/// Each step avalanches, so a chain needs no finalizer and suits a hasher that declares `is_avalanching`.
17
/// Seed a chain with `0`:
18
/// ```
19
/// size_t h = 0;
20
/// for (auto elem : elems) h = fe::hash_combine(h, elem);
21
/// ```
22
/// @note These hashes are *not* stable:
23
/// they differ between 32- and 64-bit builds and may change between fe releases.
24
/// Never serialize them and never rely on the iteration order they induce.
25
template
<std::
int
egral T>
26
constexpr
size_t
hash_combine
(
size_t
seed, T v)
noexcept
{
27
constexpr
auto
Secret = UINT64_C(0x9ddfea08eb382d69);
28
auto
a = uint64_t(seed) + uint64_t(v);
29
30
if
!
consteval
{
31
return
size_t(ankerl::unordered_dense::detail::hash_impl::mix(a, Secret));
32
}
else
{
33
uint64_t ha = a >> 32, la = uint32_t(a);
34
uint64_t hb = Secret >> 32, lb = uint32_t(Secret);
35
uint64_t rh = ha * hb, rm0 = ha * lb, rm1 = hb * la, rl = la * lb;
36
uint64_t t = rl + (rm0 << 32);
37
uint64_t c = t < rl;
38
uint64_t lo = t + (rm1 << 32);
39
c += lo < t;
40
uint64_t hi = rh + (rm0 >> 32) + (rm1 >> 32) + c;
41
return
size_t(lo ^ hi);
42
}
43
}
44
45
/// Hashes the characters of a string; transparent, so `std::string` keys may be looked up by `std::string_view`.
46
struct
StrHash
{
47
using
is_transparent
= void;
48
using
is_avalanching
= void;
49
50
size_t
operator()
(std::string_view sv)
const
noexcept
{
51
return
ankerl::unordered_dense::hash<std::string_view>()(sv);
52
}
53
};
54
55
/// @name StrMap/StrSet
56
/// Keyed by `std::string` but also looked up by `std::string_view` or `const char*` without building a `std::string`.
57
///@{
58
template
<
class
V>
59
using
StrMap
= ankerl::unordered_dense::map<std::string, V, StrHash, std::equal_to<>>;
60
using
StrSet
= ankerl::unordered_dense::set<std::string, StrHash, std::equal_to<>>;
61
///@}
62
63
}
// namespace fe
fe
Definition
algo.h:17
fe::StrMap
ankerl::unordered_dense::map< std::string, V, StrHash, std::equal_to<> > StrMap
Definition
hash.h:59
fe::StrSet
ankerl::unordered_dense::set< std::string, StrHash, std::equal_to<> > StrSet
Definition
hash.h:60
fe::hash_combine
constexpr size_t hash_combine(size_t seed, T v) noexcept
Folds v into seed like ankerl::unordered_dense hashes a tuple: one 128-bit multiply,...
Definition
hash.h:26
fe::StrHash
Hashes the characters of a string; transparent, so std::string keys may be looked up by std::string_v...
Definition
hash.h:46
fe::StrHash::operator()
size_t operator()(std::string_view sv) const noexcept
Definition
hash.h:50
fe::StrHash::is_transparent
void is_transparent
Definition
hash.h:47
fe::StrHash::is_avalanching
void is_avalanching
Definition
hash.h:48
fe
hash.h
Generated by
1.18.0