Skip to content

Commit b8e3c5f

Browse files
author
Julian LALU
committed
Improve hashers
1 parent 95e3ebd commit b8e3c5f

File tree

3 files changed

+61
-23
lines changed

3 files changed

+61
-23
lines changed

interface/core/hash.h

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,29 +93,13 @@ namespace hud
9393
}
9494

9595
/** Retrieves the 32 bits hash of a wchar null-terminated string. */
96-
[[nodiscard]] static constexpr u32 hash_32(const wchar *value, usize length) noexcept
96+
[[nodiscard]] static inline u32 hash_32(const wchar *value, usize length) noexcept
9797
{
98-
struct A
99-
{
100-
union
101-
{
102-
const ansichar *a_;
103-
const wchar *w_;
104-
};
105-
106-
constexpr A(const wchar *w)
107-
: w_(w)
108-
{
109-
}
110-
};
111-
112-
A a(value);
113-
a.w_;
114-
return hud::hash_algorithm::city_hash::hash_32(a.a_, length * sizeof(wchar));
98+
return hud::hash_algorithm::city_hash::hash_32(reinterpret_cast<const ansichar *>(value), length * sizeof(wchar));
11599
}
116100

117101
/** Retrieves the 32 bits hash of a ansichar null-terminated string. */
118-
[[nodiscard]] static constexpr u32 hash_32(const wchar *const value) noexcept
102+
[[nodiscard]] static inline u32 hash_32(const wchar *const value) noexcept
119103
{
120104
return hash_32(value, hud::cstring::length(value));
121105
}
@@ -218,7 +202,7 @@ namespace hud
218202
}
219203

220204
/** Retrieves the 32 bits hash of a ansichar null-terminated string. */
221-
[[nodiscard]] static constexpr u32 hash_64(const ansichar *const value) noexcept
205+
[[nodiscard]] static constexpr u64 hash_64(const ansichar *const value) noexcept
222206
{
223207
return hash_64(value, hud::cstring::length(value));
224208
}
@@ -263,27 +247,73 @@ namespace hud
263247
return hud::hash_algorithm::city_hash::combine_64(a, b);
264248
}
265249

266-
struct hasher_32
250+
/**
251+
* A 32 bit hasher class used for hashing an arbitrary stream of bytes
252+
* Instances of `hasher_32` usually represent state that is changed while hashing data.
253+
* `hasher_32` provides a fairly basic interface for retrieving the generated hash.
254+
* `hasher_32` used all functions in `hud` namespace like `hud::hash_32(const u32 value)`, `hud::hash_32(const ansichar *const value)` or `hud::combine_32(u64 a, u64 b)`.
255+
* If you want to hash a user defined type, add your `hud::hash_my_type(my_type& t)` function and just call `hasher_32::operator()`
256+
*/
257+
class hasher_32
267258
{
259+
public:
260+
/** Hash the value and combine the value with the current hasher value. */
268261
template<typename... type_t>
269-
[[nodiscard]] constexpr u32 operator()(type_t &&...values) noexcept
262+
[[nodiscard]] constexpr hasher_32 &operator()(type_t &&...values) noexcept
270263
{
271264
state_ = hud::combine_32(state_, hud::hash_32(hud::forward<type_t>(values)...));
265+
return *this;
266+
}
267+
268+
/** Retrieves the value of the `hasher_32`. */
269+
[[nodiscard]] operator u32() const noexcept
270+
{
272271
return state_;
273272
}
274273

274+
/** Hash the value and combine the value with the current hasher value. */
275+
template<typename... type_t>
276+
[[nodiscard]] constexpr hasher_32 &hash(type_t &&...values) noexcept
277+
{
278+
return (*this)(hud::forward<type_t>(values)...);
279+
}
280+
281+
private:
275282
u32 state_ {0}; // Default is 0, but can be a seed
276283
};
277284

285+
/**
286+
* A 64 bit hasher class used for hashing an arbitrary stream of bytes
287+
* Instances of `hasher_64` usually represent state that is changed while hashing data.
288+
* `hasher_64` provides a fairly basic interface for retrieving the generated hash.
289+
* `hasher_64` used all functions in `hud` namespace like `hud::hash_64(const u32 value)`, `hud::hash_64(const ansichar *const value)` or `hud::combine_64(u64 a, u64 b)`.
290+
* If you want to hash a user defined type, add your `hud::hash_my_type(my_type& t)` function and just call `hasher_64::operator()`
291+
*/
278292
struct hasher_64
279293
{
294+
public:
295+
/** Hash the value and combine the value with the current hasher value. */
280296
template<typename... type_t>
281-
[[nodiscard]] constexpr u64 operator()(type_t &&...values) noexcept
297+
[[nodiscard]] constexpr hasher_64 &operator()(type_t &&...values) noexcept
282298
{
283299
state_ = hud::combine_64(state_, hud::hash_64(hud::forward<type_t>(values)...));
300+
return *this;
301+
}
302+
303+
/** Retrieves the value of the `hasher_64`. */
304+
[[nodiscard]] operator u64() const noexcept
305+
{
284306
return state_;
285307
}
286308

309+
/** Hash the value and combine the value with the current hasher value. */
310+
template<typename... type_t>
311+
[[nodiscard]] constexpr hasher_64 &hash(type_t &&...values) noexcept
312+
{
313+
return (*this)(hud::forward<type_t>(values)...);
314+
}
315+
316+
private:
287317
u64 state_ {0}; // Default is 0, but can be a seed
288318
};
289319

test/hash/hash_32.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,8 @@ GTEST_TEST(hash_32, hasher32)
137137
hud::hasher_32 hasher;
138138
hud_assert_eq(hasher("key", len), 0x105695BEu);
139139
hud_assert_eq(hasher((const ansichar *)&len, sizeof(len)), 0xE638A9DBu);
140+
141+
// Test that hasher can be called redundancy
142+
u32 value = hud::hasher_32 {}("key").hash((const ansichar *)&len, sizeof(len));
143+
hud_assert_eq(value, 0xE638A9DBu);
140144
}

test/hash/hash_64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,8 @@ GTEST_TEST(hash_64, hasher64)
161161
hud::hasher_64 hasher;
162162
hud_assert_eq(hasher("key", len), 0xCEAAB8E77B74C2E7u);
163163
hud_assert_eq(hasher((const ansichar *)&len, sizeof(len)), 0x746D68F6EB969EB7u);
164+
165+
// Test that hasher can be called redundancy
166+
u64 value = hud::hasher_64 {}("key").hash((const ansichar *)&len, sizeof(len));
167+
hud_assert_eq(value, 0x746D68F6EB969EB7u);
164168
}

0 commit comments

Comments
 (0)