2#include "gaia/config/config.h"
11 template <
typename,
typename =
void>
18 constexpr void hash_combine2_out(uint32_t& lhs, uint32_t rhs) {
19 lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
21 constexpr void hash_combine2_out(uint64_t& lhs, uint64_t rhs) {
22 lhs ^= rhs + 0x9e3779B97f4a7c15ULL + (lhs << 6) + (lhs >> 2);
26 GAIA_NODISCARD
constexpr T hash_combine2(T lhs, T rhs) {
27 hash_combine2_out(lhs, rhs);
33 inline constexpr bool is_direct_hash_key_v = detail::is_direct_hash_key<T>::value;
39 static_assert(std::is_integral_v<T>);
40 static constexpr bool IsDirectHashKey =
true;
44 return hash == other.hash;
47 return hash != other.hash;
52 template <
typename... T>
53 constexpr auto combine_or([[maybe_unused]] T... t) {
58 template <
typename T,
typename... Rest>
59 constexpr T hash_combine(T first, T next, Rest... rest) {
60 auto h = detail::hash_combine2(first, next);
61 (detail::hash_combine2_out(h, rest), ...);
65#if GAIA_ECS_HASH == GAIA_ECS_HASH_FNV1A
69 constexpr uint64_t val_64_const = 0xcbf29ce484222325;
70 constexpr uint64_t prime_64_const = 0x100000001b3;
74 constexpr uint64_t calculate_hash64(
const char*
const str)
noexcept {
75 uint64_t hash = detail::fnv1a::val_64_const;
78 while (str[i] !=
'\0') {
79 hash = (hash ^ uint64_t(str[i])) * detail::fnv1a::prime_64_const;
86 constexpr uint64_t calculate_hash64(
const char*
const str,
const uint64_t length)
noexcept {
87 uint64_t hash = detail::fnv1a::val_64_const;
89 for (uint64_t i = 0; i < length; ++i)
90 hash = (hash ^ uint64_t(str[i])) * detail::fnv1a::prime_64_const;
95#elif GAIA_ECS_HASH == GAIA_ECS_HASH_MURMUR2A
99 GAIA_MSVC_WARNING_PUSH()
100 GAIA_MSVC_WARNING_DISABLE(4592)
104 constexpr uint64_t seed_64_const = 0xe17a1465ULL;
105 constexpr uint64_t m = 0xc6a4a7935bd1e995ULL;
106 constexpr uint64_t r = 47;
108 constexpr uint64_t Load8(
const char* data) {
109 return (uint64_t(data[7]) << 56) | (uint64_t(data[6]) << 48) | (uint64_t(data[5]) << 40) |
110 (uint64_t(data[4]) << 32) | (uint64_t(data[3]) << 24) | (uint64_t(data[2]) << 16) |
111 (uint64_t(data[1]) << 8) | (uint64_t(data[0]) << 0);
114 constexpr uint64_t StaticHashValueLast64(uint64_t h) {
115 return (((h * m) ^ ((h * m) >> r)) * m) ^ ((((h * m) ^ ((h * m) >> r)) * m) >> r);
118 constexpr uint64_t StaticHashValueLast64_(uint64_t h) {
119 return (((h) ^ ((h) >> r)) * m) ^ ((((h) ^ ((h) >> r)) * m) >> r);
122 constexpr uint64_t StaticHashValue64Tail1(uint64_t h,
const char* data) {
123 return StaticHashValueLast64((h ^ uint64_t(data[0])));
126 constexpr uint64_t StaticHashValue64Tail2(uint64_t h,
const char* data) {
127 return StaticHashValue64Tail1((h ^ uint64_t(data[1]) << 8), data);
130 constexpr uint64_t StaticHashValue64Tail3(uint64_t h,
const char* data) {
131 return StaticHashValue64Tail2((h ^ uint64_t(data[2]) << 16), data);
134 constexpr uint64_t StaticHashValue64Tail4(uint64_t h,
const char* data) {
135 return StaticHashValue64Tail3((h ^ uint64_t(data[3]) << 24), data);
138 constexpr uint64_t StaticHashValue64Tail5(uint64_t h,
const char* data) {
139 return StaticHashValue64Tail4((h ^ uint64_t(data[4]) << 32), data);
142 constexpr uint64_t StaticHashValue64Tail6(uint64_t h,
const char* data) {
143 return StaticHashValue64Tail5((h ^ uint64_t(data[5]) << 40), data);
146 constexpr uint64_t StaticHashValue64Tail7(uint64_t h,
const char* data) {
147 return StaticHashValue64Tail6((h ^ uint64_t(data[6]) << 48), data);
150 constexpr uint64_t StaticHashValueRest64(uint64_t h, uint64_t len,
const char* data) {
151 return ((len & 7) == 7) ? StaticHashValue64Tail7(h, data)
152 : ((len & 7) == 6) ? StaticHashValue64Tail6(h, data)
153 : ((len & 7) == 5) ? StaticHashValue64Tail5(h, data)
154 : ((len & 7) == 4) ? StaticHashValue64Tail4(h, data)
155 : ((len & 7) == 3) ? StaticHashValue64Tail3(h, data)
156 : ((len & 7) == 2) ? StaticHashValue64Tail2(h, data)
157 : ((len & 7) == 1) ? StaticHashValue64Tail1(h, data)
158 : StaticHashValueLast64_(h);
161 constexpr uint64_t StaticHashValueLoop64(uint64_t i, uint64_t h, uint64_t len,
const char* data) {
163 i == 0 ? StaticHashValueRest64(h, len, data)
164 : StaticHashValueLoop64(
165 i - 1, (h ^ (((Load8(data) * m) ^ ((Load8(data) * m) >> r)) * m)) * m, len, data + 8));
168 constexpr uint64_t hash_murmur2a_64_ct(
const char* key, uint64_t len, uint64_t seed) {
169 return StaticHashValueLoop64(len / 8, seed ^ (len * m), (len), key);
174 constexpr uint64_t calculate_hash64(uint64_t value) {
175 value ^= value >> 33U;
176 value *= 0xff51afd7ed558ccdULL;
177 value ^= value >> 33U;
179 value *= 0xc4ceb9fe1a85ec53ULL;
180 value ^= value >> 33U;
184 constexpr uint64_t calculate_hash64(
const char* str) {
186 while (str[length] !=
'\0')
189 return detail::murmur2a::hash_murmur2a_64_ct(str, length, detail::murmur2a::seed_64_const);
192 constexpr uint64_t calculate_hash64(
const char* str, uint64_t length) {
193 return detail::murmur2a::hash_murmur2a_64_ct(str, length, detail::murmur2a::seed_64_const);
196 GAIA_MSVC_WARNING_POP()
199 #error "Unknown hashing type defined"
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Definition hashing_policy.h:12
Definition hashing_policy.h:36