Plasma Engine  2.0
Loading...
Searching...
No Matches
HashingUtils_inl.h
1#include <Foundation/Strings/Implementation/StringBase.h>
2
3namespace plInternal
4{
5 template <typename T, bool isString>
6 struct HashHelperImpl
7 {
8 static plUInt32 Hash(const T& value);
9 };
10
11 template <typename T>
12 struct HashHelperImpl<T, true>
13 {
14 PL_ALWAYS_INLINE static plUInt32 Hash(plStringView sString)
15 {
17 }
18 };
19
20 template <typename T, bool isString>
21 PL_ALWAYS_INLINE plUInt32 HashHelperImpl<T, isString>::Hash(const T& value)
22 {
23 static_assert(isString, "plHashHelper is not implemented for the given type.");
24 return 0;
25 }
26} // namespace plInternal
27
28template <typename T>
29template <typename U>
30PL_ALWAYS_INLINE plUInt32 plHashHelper<T>::Hash(const U& value)
31{
32 return plInternal::HashHelperImpl<T, PL_IS_DERIVED_FROM_STATIC(plThisIsAString, T)>::Hash(value);
33}
34
35template <typename T>
36template <typename U>
37PL_ALWAYS_INLINE bool plHashHelper<T>::Equal(const T& a, const U& b)
38{
39 return a == b;
40}
41
42
43
44template <>
45struct plHashHelper<plUInt32>
46{
47 PL_ALWAYS_INLINE static plUInt32 Hash(plUInt32 value)
48 {
49 // Knuth: multiplication by the golden ratio will minimize gaps in the hash space.
50 // 2654435761U: prime close to 2^32/phi with phi = golden ratio (sqrt(5) - 1) / 2
51 return value * 2654435761U;
52 }
53
54 PL_ALWAYS_INLINE static bool Equal(plUInt32 a, plUInt32 b) { return a == b; }
55};
56
57template <>
58struct plHashHelper<plInt32>
59{
60 PL_ALWAYS_INLINE static plUInt32 Hash(plInt32 value) { return plHashHelper<plUInt32>::Hash(plUInt32(value)); }
61
62 PL_ALWAYS_INLINE static bool Equal(plInt32 a, plInt32 b) { return a == b; }
63};
64
65template <>
66struct plHashHelper<plUInt64>
67{
68 PL_ALWAYS_INLINE static plUInt32 Hash(plUInt64 value)
69 {
70 // boost::hash_combine.
71 plUInt32 a = plUInt32(value >> 32);
72 plUInt32 b = plUInt32(value);
73 return a ^ (b + 0x9e3779b9 + (a << 6) + (b >> 2));
74 }
75
76 PL_ALWAYS_INLINE static bool Equal(plUInt64 a, plUInt64 b) { return a == b; }
77};
78
79template <>
80struct plHashHelper<plInt64>
81{
82 PL_ALWAYS_INLINE static plUInt32 Hash(plInt64 value) { return plHashHelper<plUInt64>::Hash(plUInt64(value)); }
83
84 PL_ALWAYS_INLINE static bool Equal(plInt64 a, plInt64 b) { return a == b; }
85};
86
87template <>
88struct plHashHelper<const char*>
89{
90 PL_ALWAYS_INLINE static plUInt32 Hash(const char* szValue)
91 {
93 }
94
95 PL_ALWAYS_INLINE static bool Equal(const char* a, const char* b) { return plStringUtils::IsEqual(a, b); }
96};
97
98template <>
100{
101 PL_ALWAYS_INLINE static plUInt32 Hash(plStringView sValue)
102 {
104 }
105
106 PL_ALWAYS_INLINE static bool Equal(plStringView a, plStringView b) { return a == b; }
107};
108
109template <typename T>
110struct plHashHelper<T*>
111{
112 PL_ALWAYS_INLINE static plUInt32 Hash(T* value)
113 {
114#if PL_ENABLED(PL_PLATFORM_64BIT)
115 return plHashHelper<plUInt64>::Hash(reinterpret_cast<plUInt64>(value) >> 4);
116#else
117 return plHashHelper<plUInt32>::Hash(reinterpret_cast<plUInt32>(value) >> 4);
118#endif
119 }
120
121 PL_ALWAYS_INLINE static bool Equal(T* a, T* b)
122 {
123 return a == b;
124 }
125};
126
127template <size_t N>
128constexpr PL_ALWAYS_INLINE plUInt64 plHashingUtils::StringHash(const char (&str)[N], plUInt64 uiSeed)
129{
130 return xxHash64String(str, uiSeed);
131}
132
133PL_ALWAYS_INLINE plUInt64 plHashingUtils::StringHash(plStringView sStr, plUInt64 uiSeed)
134{
135 return xxHash64String(sStr, uiSeed);
136}
137
138constexpr PL_ALWAYS_INLINE plUInt32 plHashingUtils::StringHashTo32(plUInt64 uiHash)
139{
140 // just throw away the upper bits
141 return static_cast<plUInt32>(uiHash);
142}
143
144constexpr PL_ALWAYS_INLINE plUInt32 plHashingUtils::CombineHashValues32(plUInt32 ui0, plUInt32 ui1)
145{
146 // See boost::hash_combine
147 return ui0 ^ (ui1 + 0x9e3779b9 + (ui0 << 6) + (ui1 >> 2));
148}
static constexpr plUInt32 CombineHashValues32(plUInt32 ui0, plUInt32 ui1)
Combines two 32 bit hash values into one.
Definition HashingUtils_inl.h:144
static constexpr plUInt64 xxHash64String(const char(&str)[N], plUInt64 uiSeed=0)
Calculates the 64bit xxHash of the given string literal at compile time.
static constexpr plUInt32 StringHashTo32(plUInt64 uiHash)
Truncates a 64 bit string hash to 32 bit.
Definition HashingUtils_inl.h:138
static constexpr plUInt64 StringHash(const char(&str)[N], plUInt64 uiSeed=0)
Calculates the hash of the given string literal at compile time.
static bool IsEqual(const char *pString1, const char *pString2, const char *pString1End=plUnicodeUtils::GetMaxStringEnd< char >(), const char *pString2End=plUnicodeUtils::GetMaxStringEnd< char >())
Returns true, if the two given strings are identical (bitwise).
Definition StringUtils_inl.h:125
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
Helper struct to calculate the Hash of different types.
Definition HashingUtils.h:75
Definition StringBase.h:8
Base class which marks a class as containing string data.
Definition StringView.h:19