GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 3, 0 excluded
0.0%
Functions:
0 of 1, 0 excluded
0.0%
Branches:
0 of 0, 0 excluded
-%

libs/core/src/eu/core/hash.h
Line Branch Exec Source
1 #pragma once
2
3 namespace eu::core
4 {
5
6 /** \addtogroup hash Hash-util
7 * \brief Helper macros for specializing the std::hash.
8 * This group provides a util \ref HashCombiner to simplify the creation of hash functions
9 * for user-defined types (using std::hash) and macros for specialization of std::hash for custom types.
10 *
11 * Example usage:
12 * ```
13 * HASH_DEF_BEGIN(MyType)
14 * HASH_DEF(member1)
15 * HASH_DEF(member2)
16 * HASH_DEF_END()
17 * ```
18 * @{
19 */
20
21
22 /// A utility for combining hash values of multiple objects into a single hash value.
23 /// \note
24 /// Do not use when hashing is critical.
25 struct HashCombiner
26 {
27 std::size_t result = 17;
28
29 /// Combines the hash of the given object with the current result.
30 ///
31 /// src: https://stackoverflow.com/a/17017281/180307
32 /// numbers from: https://stackoverflow.com/a/1646913/180307
33 /// \note
34 /// A word of warning, this is (a variation of) the Berstein hash, and because nobody
35 /// knows why it does well in tests it is not advisable when hashing is critical.
36 /// See https://github.com/mignon-p/jsw-libs/blob/master/Tutorials/jsw_tut_hashing.md
37 template<typename T>
38 HashCombiner& combine(const T& t)
39 {
40 result = result * 31 + std::hash<T>{}(t);
41 return *this;
42 }
43 };
44
45
46 /** Begins the definition of a specialization of std::hash for the given TYPE.
47 * Should be closed by the \ref HASH_DEF_END macro
48 * @param TYPE The user-defined type for which the hash specialization is being created.
49 * \hideinlinesource
50 */
51 #define HASH_DEF_BEGIN(TYPE) \
52 template<> \
53 struct std::hash<TYPE> \
54 { \
55 std::size_t operator()(const TYPE& x) const \
56 { \
57 return eu::core::HashCombiner \
58 { \
59 }
60
61 /** Adds the hash of a member variable to the hash combination.
62 * \hideinlinesource
63 *
64 * This macro should be used within a \ref HASH_DEF_BEGIN and \ref HASH_DEF_END block to combine
65 * the hash of a specific member variable of the type.
66 *
67 *
68 * @param NAME The name of the member variable to include in the hash.
69 */
70 #define HASH_DEF(NAME) .combine(x.NAME)
71
72 /** Ends the definition of the std::hash specialization.
73 *
74 * This macro should be used to close the hash function definition started with
75 * \ref HASH_DEF_BEGIN. It returns the final combined hash value.
76 *
77 * \hideinlinesource
78 */
79 #define HASH_DEF_END() \
80 .result; \
81 } \
82 } \
83 ;
84
85 /**
86 * @}
87 */
88
89 } // namespace klotter
90
91