Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
HashCombine.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
15inline uint64 HashBytes(const void *inData, uint inSize, uint64 inSeed = 0xcbf29ce484222325UL)
16{
17 uint64 hash = inSeed;
18 for (const uint8 *data = reinterpret_cast<const uint8 *>(inData); data < reinterpret_cast<const uint8 *>(inData) + inSize; ++data)
19 {
20 hash ^= uint64(*data);
21 hash *= 0x100000001b3UL;
22 }
23 return hash;
24}
25
28constexpr uint64 HashString(const char *inString, uint64 inSeed = 0xcbf29ce484222325UL)
29{
30 uint64 hash = inSeed;
31 for (const char *c = inString; *c != 0; ++c)
32 {
33 hash ^= uint64(*c);
34 hash *= 0x100000001b3UL;
35 }
36 return hash;
37}
38
43inline uint64 Hash64(uint64 inValue)
44{
45 uint64 hash = inValue;
46 hash = (~hash) + (hash << 21); // hash = (hash << 21) - hash - 1;
47 hash = hash ^ (hash >> 24);
48 hash = (hash + (hash << 3)) + (hash << 8); // hash * 265
49 hash = hash ^ (hash >> 14);
50 hash = (hash + (hash << 2)) + (hash << 4); // hash * 21
51 hash = hash ^ (hash >> 28);
52 hash = hash + (hash << 31);
53 return hash;
54}
55
57template <class T>
58struct Hash
59{
60 uint64 operator () (const T &inValue) const
61 {
62 return inValue.GetHash();
63 }
64};
65
67template <>
68struct Hash<float>
69{
70 uint64 operator () (float inValue) const
71 {
72 float value = inValue == 0.0f? 0.0f : inValue; // Convert -0.0f to 0.0f
73 return HashBytes(&value, sizeof(value));
74 }
75};
76
78template <>
79struct Hash<double>
80{
81 uint64 operator () (double inValue) const
82 {
83 double value = inValue == 0.0? 0.0 : inValue; // Convert -0.0 to 0.0
84 return HashBytes(&value, sizeof(value));
85 }
86};
87
89template <>
90struct Hash<const char *>
91{
92 uint64 operator () (const char *inValue) const
93 {
94 return HashString(inValue);
95 }
96};
97
99template <>
100struct Hash<std::string_view>
101{
102 uint64 operator () (const std::string_view &inValue) const
103 {
104 return HashBytes(inValue.data(), uint(inValue.size()));
105 }
106};
107
109template <>
111{
112 uint64 operator () (const String &inValue) const
113 {
114 return HashBytes(inValue.data(), uint(inValue.size()));
115 }
116};
117
119template <class T>
120struct Hash<T *>
121{
122 uint64 operator () (T *inValue) const
123 {
124 return HashBytes(&inValue, sizeof(inValue));
125 }
126};
127
129#define JPH_DEFINE_TRIVIAL_HASH(type) \
130template <> \
131struct Hash<type> \
132{ \
133 uint64 operator () (const type &inValue) const \
134 { \
135 return HashBytes(&inValue, sizeof(inValue)); \
136 } \
137};
138
144
145
147template <typename T>
148inline void HashCombine(uint64 &ioSeed, const T &inValue)
149{
150 constexpr uint64 c = 0xbea225f9eb34556dUL;
151
152 uint64 h = ioSeed;
153 uint64 x = Hash<T> { } (inValue);
154
155 // See: https://github.com/jonmaiga/mx3/blob/master/mx3.h
156 // mix_stream(h, x)
157 x *= c;
158 x ^= x >> 39;
159 h += x * c;
160 h *= c;
161
162 // mix(h)
163 h ^= h >> 32;
164 h *= c;
165 h ^= h >> 29;
166 h *= c;
167 h ^= h >> 32;
168 h *= c;
169 h ^= h >> 29;
170
171 ioSeed = h;
172}
173
186template <typename FirstValue, typename... Values>
187inline uint64 HashCombineArgs(const FirstValue &inFirstValue, Values... inValues)
188{
189 // Prime the seed by hashing the first value
190 uint64 seed = Hash<FirstValue> { } (inFirstValue);
191
192 // Hash all remaining values together using a fold expression
193 (HashCombine(seed, inValues), ...);
194
195 return seed;
196}
197
198#define JPH_MAKE_HASH_STRUCT(type, name, ...) \
199 struct [[nodiscard]] name \
200 { \
201 ::JPH::uint64 operator()(const type &t) const \
202 { \
203 return ::JPH::HashCombineArgs(__VA_ARGS__); \
204 } \
205 };
206
207#define JPH_MAKE_STD_HASH(type) \
208 JPH_SUPPRESS_WARNING_PUSH \
209 JPH_SUPPRESS_WARNINGS \
210 namespace std \
211 { \
212 template<> \
213 struct [[nodiscard]] hash<type> \
214 { \
215 size_t operator()(const type &t) const \
216 { \
217 return size_t(::JPH::Hash<type>{ }(t)); \
218 } \
219 }; \
220 } \
221 JPH_SUPPRESS_WARNING_POP
222
223#define JPH_MAKE_HASHABLE(type, ...) \
224 JPH_SUPPRESS_WARNING_PUSH \
225 JPH_SUPPRESS_WARNINGS \
226 namespace JPH \
227 { \
228 template<> \
229 JPH_MAKE_HASH_STRUCT(type, Hash<type>, __VA_ARGS__) \
230 } \
231 JPH_SUPPRESS_WARNING_POP \
232 JPH_MAKE_STD_HASH(type)
233
std::uint8_t uint8
Definition Core.h:482
std::uint64_t uint64
Definition Core.h:485
unsigned int uint
Definition Core.h:481
#define JPH_NAMESPACE_END
Definition Core.h:414
std::uint32_t uint32
Definition Core.h:484
#define JPH_NAMESPACE_BEGIN
Definition Core.h:408
constexpr uint64 HashString(const char *inString, uint64 inSeed=0xcbf29ce484222325UL)
Definition HashCombine.h:28
JPH_NAMESPACE_BEGIN uint64 HashBytes(const void *inData, uint inSize, uint64 inSeed=0xcbf29ce484222325UL)
Definition HashCombine.h:15
uint64 HashCombineArgs(const FirstValue &inFirstValue, Values... inValues)
Definition HashCombine.h:187
uint64 Hash64(uint64 inValue)
Definition HashCombine.h:43
void HashCombine(uint64 &ioSeed, const T &inValue)
Commonly used types.
Definition HashCombine.h:148
#define JPH_DEFINE_TRIVIAL_HASH(type)
Helper macro to define a hash function for trivial types.
Definition HashCombine.h:129
std::basic_string< char, std::char_traits< char >, STLAllocator< char > > String
Definition STLAllocator.h:107
Definition Array.h:590
Fallback hash function that calls T::GetHash()
Definition HashCombine.h:59
uint64 operator()(const T &inValue) const
Definition HashCombine.h:60