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
29namespace original {
30
35 template <typename TYPE>
36 class hash;
37
42 template <typename DERIVED>
43 class hashable;
44
61 template <typename DERIVED>
62 concept isHashable =
63 requires(const DERIVED& t, const DERIVED& other) {
64 { t.toHash() } -> std::same_as<u_integer>;
65 { t.equals(other) } -> std::same_as<bool>;
66 };
67
91 template <typename TYPE>
92 class hash {
99 template <typename T>
100 static inline void hashCombine(u_integer& seed, const T& value) noexcept;
101
113 template <typename T>
114 static u_integer hashFuncImpl(const T& t) noexcept;
115
116 public:
117 template <typename>
118 friend class hashable;
119
121 static constexpr u_integer FNV_OFFSET_BASIS = 0x811C9DC5;
122
124 static constexpr u_integer FNV_32_PRIME = 0x01000193;
125
133 static u_integer fnv1a(const byte* data, u_integer size) noexcept;
134
143 template <typename T, typename... Rest>
144 static void hashCombine(u_integer& seed, const T& value, const Rest&... rest) noexcept;
145
154 template <typename T>
155 static u_integer hashFunc(const T& t) noexcept;
156
163 template <isHashable T>
164 static u_integer hashFunc(const T& t) noexcept;
165
172 template<std::integral T>
173 static u_integer hashFunc(const T& t) noexcept;
174
181 template <typename T>
182 static u_integer hashFunc(T* const& t) noexcept;
183
189 static u_integer hashFunc(const std::nullptr_t& null) noexcept;
190
196 static u_integer hashFunc(const char& t) noexcept;
197
204 static u_integer hashFunc(const char* str) noexcept;
205
211 static u_integer hashFunc(const std::string& str) noexcept;
212
219 u_integer operator()(const TYPE& t) const noexcept;
220 };
221
239 template <typename DERIVED>
240 class hashable {
241 public:
247 [[nodiscard]] virtual u_integer toHash() const noexcept;
248
255 virtual bool equals(const DERIVED& other) const noexcept;
256
261 virtual ~hashable() = 0;
262 };
263}
264
265
270template <typename T>
271requires original::isHashable<T>
272struct std::hash<T> { // NOLINT
278 std::size_t operator()(const T& t) const noexcept;
279};
280
281template<typename TYPE>
282template<typename T>
283void original::hash<TYPE>::hashCombine(u_integer &seed, const T& value) noexcept {
284 seed ^= hash<T>::hashFunc(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
285}
286
287template<typename TYPE>
288template<typename T>
290 if constexpr (std::is_trivially_copyable_v<T>) {
291 byte buffer[sizeof(T)];
292 std::memcpy(buffer, &t, sizeof(T));
293 return fnv1a(buffer, sizeof(T));
294 } else {
295 return static_cast<u_integer>(reinterpret_cast<uintptr_t>(&t));
296 }
297}
298
299template<typename TYPE>
300original::u_integer original::hash<TYPE>::fnv1a(const byte* data, const u_integer size) noexcept {
301 u_integer hash = FNV_OFFSET_BASIS;
302 for (u_integer i = 0; i < size; ++i) {
303 hash ^= data[i];
304 hash *= FNV_32_PRIME;
305 }
306 return hash;
307}
308
309template<typename TYPE>
310template<typename T, typename... Rest>
311void original::hash<TYPE>::hashCombine(u_integer &seed, const T& value, const Rest&... rest) noexcept {
312 hashCombine(seed, value);
313 (hashCombine(seed, rest), ...);
314}
315
316template<typename TYPE>
317template<typename T>
319 return hashFuncImpl(t);
320}
321
322template<typename TYPE>
323template<original::isHashable T>
325 return t.toHash();
326}
327
328template<typename TYPE>
330 return 0;
331}
332
333template<typename TYPE>
334template<std::integral T>
336 return static_cast<u_integer>(t);
337}
338
339template<typename TYPE>
340template<typename T>
342 return static_cast<u_integer>(reinterpret_cast<uintptr_t>(t));
343}
344
345template<typename TYPE>
347 return static_cast<u_integer>(t);
348}
349
350template<typename TYPE>
352 if (str == nullptr) return 0;
353 return fnv1a(reinterpret_cast<const byte*>(str), std::strlen(str));
354}
355
356template<typename TYPE>
357original::u_integer original::hash<TYPE>::hashFunc(const std::string& str) noexcept {
358 return fnv1a(reinterpret_cast<const byte*>(str.data()), str.size());
359}
360
361template<typename TYPE>
363 return hashFunc(t);
364}
365
366template <typename DERIVED>
368 return hash<DERIVED>::hashFuncImpl(static_cast<const DERIVED&>(*this));
369}
370
371template<typename DERIVED>
372bool original::hashable<DERIVED>::equals(const DERIVED &other) const noexcept {
373 return static_cast<const DERIVED&>(*this) == other;
374}
375
376template <typename DERIVED>
378
379template <typename T>
381std::size_t std::hash<T>::operator()(const T &t) const noexcept {
382 return static_cast<std::size_t>(t.toHash());
383}
384
385#endif //HASH_H
Forward declaration of hash class template.
Definition hash.h:92
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:311
static u_integer hashFunc(const std::nullptr_t &null) noexcept
Hash function for nullptr.
Definition hash.h:329
static u_integer hashFunc(T *const &t) noexcept
Hash function for pointers.
u_integer operator()(const TYPE &t) const noexcept
Hash function object call operator.
Definition hash.h:362
static u_integer hashFunc(const char &t) noexcept
Hash function for single character.
Definition hash.h:346
static u_integer hashFunc(const char *str) noexcept
Hash function for C-style strings.
Definition hash.h:351
static u_integer hashFunc(const std::string &str) noexcept
Hash function for std::string.
Definition hash.h:357
static constexpr u_integer FNV_OFFSET_BASIS
FNV-1a initial offset value (0x811C9DC5)
Definition hash.h:121
static constexpr u_integer FNV_32_PRIME
FNV-1a prime multiplier (0x01000193)
Definition hash.h:124
static u_integer fnv1a(const byte *data, u_integer size) noexcept
FNV-1a hash implementation for raw byte data.
Definition hash.h:300
Forward declaration of hashable interface template.
Definition hash.h:240
virtual bool equals(const DERIVED &other) const noexcept
Compares two objects for equality.
Definition hash.h:372
virtual ~hashable()=0
Virtual destructor.
virtual u_integer toHash() const noexcept
Computes the hash of the object.
Definition hash.h:367
Concept checking for types that can be hashed.
Definition hash.h:62
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