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 = hash ^ uint64(*data);
21 hash = 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 = 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 ioSeed ^= Hash<T> { } (inValue) + 0x9e3779b9 + (ioSeed << 6) + (ioSeed >> 2);
151}
152
165template <typename FirstValue, typename... Values>
166inline uint64 HashCombineArgs(const FirstValue &inFirstValue, Values... inValues)
167{
168 // Prime the seed by hashing the first value
169 uint64 seed = Hash<FirstValue> { } (inFirstValue);
170
171 // Hash all remaining values together using a fold expression
172 (HashCombine(seed, inValues), ...);
173
174 return seed;
175}
176
178
179JPH_SUPPRESS_WARNING_PUSH
180JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
181
182#define JPH_MAKE_HASH_STRUCT(type, name, ...) \
183 struct [[nodiscard]] name \
184 { \
185 ::JPH::uint64 operator()(const type &t) const \
186 { \
187 return ::JPH::HashCombineArgs(__VA_ARGS__); \
188 } \
189 };
190
191#define JPH_MAKE_HASHABLE(type, ...) \
192 JPH_SUPPRESS_WARNING_PUSH \
193 JPH_SUPPRESS_WARNINGS \
194 namespace JPH \
195 { \
196 template<> \
197 JPH_MAKE_HASH_STRUCT(type, Hash<type>, __VA_ARGS__) \
198 } \
199 namespace std \
200 { \
201 template<> \
202 struct [[nodiscard]] hash<type> \
203 { \
204 std::size_t operator()(const type &t) const \
205 { \
206 return std::size_t(::JPH::Hash<type>{ }(t));\
207 } \
208 }; \
209 } \
210 JPH_SUPPRESS_WARNING_POP
211
212JPH_SUPPRESS_WARNING_POP
std::uint8_t uint8
Definition Core.h:454
std::uint64_t uint64
Definition Core.h:457
unsigned int uint
Definition Core.h:453
#define JPH_NAMESPACE_END
Definition Core.h:379
#define JPH_CLANG_SUPPRESS_WARNING(w)
Definition Core.h:263
std::uint32_t uint32
Definition Core.h:456
#define JPH_NAMESPACE_BEGIN
Definition Core.h:373
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:166
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