ORIGINAL
Loading...
Searching...
No Matches
hash.h
Go to the documentation of this file.
1#ifndef HASH_H
2#define HASH_H
3
4#include "config.h"
5#include <cstring>
6#include <string>
7#include "types.h"
8
29namespace original {
30
35 template <typename DERIVED>
36 class hashable;
37
61 template <typename TYPE>
62 class hash {
63
75 template <typename T>
76 static u_integer hashFuncImpl(const T& t) noexcept;
77
78 public:
79 template <typename>
80 friend class hashable;
81
83 static constexpr u_integer FNV_OFFSET_BASIS = 0x811C9DC5;
84
86 static constexpr u_integer FNV_32_PRIME = 0x01000193;
87
94 template <typename T>
95 static void hashCombine(u_integer& seed, const T& value) noexcept;
96
104 static u_integer fnv1a(const byte* data, u_integer size) noexcept;
105
114 template <typename T, typename... Rest>
115 static void hashCombine(u_integer& seed, const T& value, const Rest&... rest) noexcept;
116
125 template <typename T>
126 static u_integer hashFunc(const T& t) noexcept;
127
128 template <typename T>
129 requires ExtendsOf<hashable<T>, T>
130 static u_integer hashFunc(const T& t) noexcept;
131
138 template<std::integral T>
139 static u_integer hashFunc(const T& t) noexcept;
140
147 template <typename T>
148 static u_integer hashFunc(T* const& t) noexcept;
149
155 static u_integer hashFunc(const std::nullptr_t& null) noexcept;
156
162 static u_integer hashFunc(const char& t) noexcept;
163
170 static u_integer hashFunc(const char* str) noexcept;
171
177 static u_integer hashFunc(const std::string& str) noexcept;
178
185 u_integer operator()(const TYPE& t) const noexcept;
186 };
187
205 template <typename DERIVED>
206 class hashable {
207 public:
213 [[nodiscard]] virtual u_integer toHash() const noexcept;
214
221 virtual bool equals(const DERIVED& other) const noexcept;
222
227 virtual ~hashable() = 0;
228 };
229}
230
231
236template <typename T>
237requires original::ExtendsOf<original::hashable<T>, T>
238struct std::hash<T> { // NOLINT
244 std::size_t operator()(const T& t) const noexcept;
245};
246
247template<typename TYPE>
248template<typename T>
249void original::hash<TYPE>::hashCombine(u_integer &seed, const T& value) noexcept {
250 seed ^= hash<T>::hashFunc(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
251}
252
253template<typename TYPE>
254template<typename T>
256 if constexpr (std::is_trivially_copyable_v<T>) {
257 byte buffer[sizeof(T)];
258 std::memcpy(buffer, &t, sizeof(T));
259 return fnv1a(buffer, sizeof(T));
260 } else {
261 return static_cast<u_integer>(reinterpret_cast<uintptr_t>(&t));
262 }
263}
264
265template<typename TYPE>
266original::u_integer original::hash<TYPE>::fnv1a(const byte* data, const u_integer size) noexcept {
267 u_integer hash = FNV_OFFSET_BASIS;
268 for (u_integer i = 0; i < size; ++i) {
269 hash ^= data[i];
270 hash *= FNV_32_PRIME;
271 }
272 return hash;
273}
274
275template<typename TYPE>
276template<typename T, typename... Rest>
277void original::hash<TYPE>::hashCombine(u_integer &seed, const T& value, const Rest&... rest) noexcept {
278 hashCombine(seed, value);
279 (hashCombine(seed, rest), ...);
280}
281
282template<typename TYPE>
283template<typename T>
285 return hashFuncImpl(t);
286}
287
288template <typename TYPE>
289template <typename T> requires original::ExtendsOf<original::hashable<T>, T>
291 return t.toHash();
292}
293
294template<typename TYPE>
296 return 0;
297}
298
299template<typename TYPE>
300template<std::integral T>
302 return static_cast<u_integer>(t);
303}
304
305template<typename TYPE>
306template<typename T>
308 return static_cast<u_integer>(reinterpret_cast<uintptr_t>(t));
309}
310
311template<typename TYPE>
313 return static_cast<u_integer>(t);
314}
315
316template<typename TYPE>
318 if (str == nullptr) return 0;
319 return fnv1a(reinterpret_cast<const byte*>(str), std::strlen(str));
320}
321
322template<typename TYPE>
323original::u_integer original::hash<TYPE>::hashFunc(const std::string& str) noexcept {
324 return fnv1a(reinterpret_cast<const byte*>(str.data()), str.size());
325}
326
327template<typename TYPE>
329 return hashFunc(t);
330}
331
332template <typename DERIVED>
334 return hash<DERIVED>::hashFuncImpl(static_cast<const DERIVED&>(*this));
335}
336
337template<typename DERIVED>
338bool original::hashable<DERIVED>::equals(const DERIVED &other) const noexcept {
339 return static_cast<const DERIVED&>(*this) == other;
340}
341
342template <typename DERIVED>
344
345template <typename T>
347std::size_t std::hash<T>::operator()(const T &t) const noexcept {
348 return static_cast<std::size_t>(t.toHash());
349}
350
351#endif //HASH_H
Generic hash function object supporting multiple types.
Definition hash.h:62
static u_integer hashFunc(const T &t) noexcept
Default hash function fallback.
static void hashCombine(u_integer &seed, const T &value, const Rest &... rest) noexcept
Combines multiple hash values into one.
Definition hash.h:277
static u_integer hashFunc(const std::nullptr_t &null) noexcept
Hash function for nullptr.
Definition hash.h:295
static u_integer hashFunc(T *const &t) noexcept
Hash function for pointers.
static void hashCombine(u_integer &seed, const T &value) noexcept
Combines a hash value with another value's hash.
Definition hash.h:249
u_integer operator()(const TYPE &t) const noexcept
Hash function object call operator.
Definition hash.h:328
static u_integer hashFunc(const char &t) noexcept
Hash function for single character.
Definition hash.h:312
static u_integer hashFunc(const char *str) noexcept
Hash function for C-style strings.
Definition hash.h:317
static u_integer hashFunc(const std::string &str) noexcept
Hash function for std::string.
Definition hash.h:323
static constexpr u_integer FNV_OFFSET_BASIS
FNV-1a initial offset value (0x811C9DC5)
Definition hash.h:83
static constexpr u_integer FNV_32_PRIME
FNV-1a prime multiplier (0x01000193)
Definition hash.h:86
static u_integer fnv1a(const byte *data, u_integer size) noexcept
FNV-1a hash implementation for raw byte data.
Definition hash.h:266
Forward declaration of hashable interface template.
Definition hash.h:206
virtual bool equals(const DERIVED &other) const noexcept
Compares two objects for equality.
Definition hash.h:338
virtual ~hashable()=0
Virtual destructor.
virtual u_integer toHash() const noexcept
Computes the hash of the object.
Definition hash.h:333
Checks derivation or type identity using std::derived_from.
Definition types.h:393
Platform-independent type definitions and compiler/platform detection.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:263
Main namespace for the project Original.
Definition algorithms.h:21
Core type system foundations and concept definitions.