GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef ZSERIO_HASH_CODE_UTIL_H_INC |
||
2 |
#define ZSERIO_HASH_CODE_UTIL_H_INC |
||
3 |
|||
4 |
#include <type_traits> |
||
5 |
#include <string> |
||
6 |
#include <vector> |
||
7 |
#include <memory> |
||
8 |
|||
9 |
#include "zserio/Types.h" |
||
10 |
#include "zserio/FloatUtil.h" |
||
11 |
#include "zserio/Enums.h" |
||
12 |
#include "zserio/OptionalHolder.h" |
||
13 |
|||
14 |
namespace zserio |
||
15 |
{ |
||
16 |
/** Prime number for hash calculation. */ |
||
17 |
static const uint32_t HASH_PRIME_NUMBER = 37; |
||
18 |
/** Initial seed for hash calculation. */ |
||
19 |
static const uint32_t HASH_SEED = 23; |
||
20 |
|||
21 |
/** |
||
22 |
* Gets initial hash code calculated from the given seed value. |
||
23 |
* |
||
24 |
* \param seedValue Seed value (current hash code). |
||
25 |
* |
||
26 |
* \return Hash code. |
||
27 |
*/ |
||
28 |
74 |
inline uint32_t calcHashCodeFirstTerm(uint32_t seedValue) |
|
29 |
{ |
||
30 |
74 |
return HASH_PRIME_NUMBER * seedValue; |
|
31 |
} |
||
32 |
|||
33 |
/** |
||
34 |
* Calculates hash code of the given integral value using the given seed value. |
||
35 |
* |
||
36 |
* \param seedValue Seed value (current hash code). |
||
37 |
* \param value Value for which to calculate the hash code. |
||
38 |
* |
||
39 |
* \return Calculated hash code. |
||
40 |
*/ |
||
41 |
template<typename T> |
||
42 |
inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) <= 4), uint32_t>::type |
||
43 |
71 |
calcHashCode(uint32_t seedValue, T value) |
|
44 |
{ |
||
45 |
71 |
return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(value); |
|
46 |
} |
||
47 |
|||
48 |
/** |
||
49 |
* Calculates hash code of the given integral value using the given seed value. |
||
50 |
* |
||
51 |
* \param seedValue Seed value (current hash code). |
||
52 |
* \param value Value for which to calculate the hash code. |
||
53 |
* |
||
54 |
* \return Calculated hash code. |
||
55 |
*/ |
||
56 |
template<typename T> |
||
57 |
inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) > 4), uint32_t>::type |
||
58 |
3 |
calcHashCode(uint32_t seedValue, T value) |
|
59 |
{ |
||
60 |
3 |
const auto unsignedValue = static_cast<typename std::make_unsigned<T>::type>(value); |
|
61 |
3 |
return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(unsignedValue ^ (unsignedValue >> 32U)); |
|
62 |
} |
||
63 |
|||
64 |
/** |
||
65 |
* Calculates hash code of the given float value using the given seed value. |
||
66 |
* |
||
67 |
* \param seedValue Seed value (current hash code). |
||
68 |
* \param value Value for which to calculate the hash code. |
||
69 |
* |
||
70 |
* \return Calculated hash code. |
||
71 |
*/ |
||
72 |
1 |
inline uint32_t calcHashCode(uint32_t seedValue, float value) |
|
73 |
{ |
||
74 |
1 |
return calcHashCode(seedValue, convertFloatToUInt32(value)); |
|
75 |
} |
||
76 |
|||
77 |
/** |
||
78 |
* Calculates hash code of the given double value using the given seed value. |
||
79 |
* |
||
80 |
* \param seedValue Seed value (current hash code). |
||
81 |
* \param value Value for which to calculate the hash code. |
||
82 |
* |
||
83 |
* \return Calculated hash code. |
||
84 |
*/ |
||
85 |
1 |
inline uint32_t calcHashCode(uint32_t seedValue, double value) |
|
86 |
{ |
||
87 |
1 |
return calcHashCode(seedValue, convertDoubleToUInt64(value)); |
|
88 |
} |
||
89 |
|||
90 |
/** |
||
91 |
* Calculates hash code of the given string value using the given seed value. |
||
92 |
* |
||
93 |
* \param seedValue Seed value (current hash code). |
||
94 |
* \param stringValue Value for which to calculate the hash code. |
||
95 |
* |
||
96 |
* \return Calculated hash code. |
||
97 |
*/ |
||
98 |
template <typename ALLOC> |
||
99 |
2 |
inline uint32_t calcHashCode(uint32_t seedValue, |
|
100 |
const std::basic_string<char, std::char_traits<char>, ALLOC>& stringValue) |
||
101 |
{ |
||
102 |
2 |
uint32_t result = seedValue; |
|
103 |
✓✓ | 4 |
for (auto element : stringValue) |
104 |
2 |
result = calcHashCode(result, element); |
|
105 |
|||
106 |
2 |
return result; |
|
107 |
} |
||
108 |
|||
109 |
/** |
||
110 |
* Calculates hash code of the given enum item using the given seed value. |
||
111 |
* |
||
112 |
* \param seedValue Seed value (current hash code). |
||
113 |
* \param enumValue Enum item for which to calculate the hash code. |
||
114 |
* |
||
115 |
* \return Calculated hash code. |
||
116 |
*/ |
||
117 |
template <typename ENUM_TYPE> |
||
118 |
5 |
inline typename std::enable_if<std::is_enum<ENUM_TYPE>::value, uint32_t>::type calcHashCode( |
|
119 |
uint32_t seedValue, ENUM_TYPE enumValue) |
||
120 |
{ |
||
121 |
5 |
return calcHashCode(seedValue, enumHashCode(enumValue)); |
|
122 |
} |
||
123 |
|||
124 |
/** |
||
125 |
* Calculates hash code of the given Zserio object (structure, choice, ...) using the given seed value. |
||
126 |
* |
||
127 |
* \param seedValue Seed value (current hash code). |
||
128 |
* \param object Object for which to calculate the hash code. |
||
129 |
* |
||
130 |
* \return Calculated hash code. |
||
131 |
*/ |
||
132 |
template <typename OBJECT> |
||
133 |
inline |
||
134 |
typename std::enable_if<!std::is_enum<OBJECT>::value && !std::is_integral<OBJECT>::value, uint32_t>::type |
||
135 |
14 |
calcHashCode(uint32_t seedValue, const OBJECT& object) |
|
136 |
{ |
||
137 |
14 |
return calcHashCode(seedValue, object.hashCode()); |
|
138 |
} |
||
139 |
|||
140 |
/** |
||
141 |
* Calculates hash code of the given Zserio array using the given seed value. |
||
142 |
* |
||
143 |
* \param seedValue Seed value (current hash code). |
||
144 |
* \param array Array for which to calculate the hash code. |
||
145 |
* |
||
146 |
* \return Calculated hash code. |
||
147 |
*/ |
||
148 |
template <typename ARRAY_ELEMENT, typename ALLOC> |
||
149 |
11 |
inline uint32_t calcHashCode(uint32_t seedValue, const std::vector<ARRAY_ELEMENT, ALLOC>& array) |
|
150 |
{ |
||
151 |
11 |
uint32_t result = seedValue; |
|
152 |
✓✓✓✓ ✓✓✓✓ ✓✓✗✗ ✗✗✗✗ ✗✗ |
27 |
for (const ARRAY_ELEMENT& element : array) |
153 |
✗✓✗✓ ✓✗✓✓ ✗✗✗✗ ✗ |
16 |
result = calcHashCode(result, element); |
154 |
|||
155 |
11 |
return result; |
|
156 |
} |
||
157 |
|||
158 |
// must be last because of the two-phase lookup |
||
159 |
// - we can have optional array (OptionalHolder<std::vector<T>>), but we cannot have array of optionals |
||
160 |
/** |
||
161 |
* Calculates hash code of the given Zserio optional field using the given seed value. |
||
162 |
* |
||
163 |
* \param seedValue Seed value (current hash code). |
||
164 |
* \param optionalHolder Optional field for which to calculate the hash code. |
||
165 |
* |
||
166 |
* \return Calculated hash code. |
||
167 |
*/ |
||
168 |
template <typename FIELD> |
||
169 |
5 |
inline uint32_t calcHashCode(uint32_t seedValue, const InplaceOptionalHolder<FIELD>& optionalHolder) |
|
170 |
{ |
||
171 |
✗✓✗✓ ✗✓✓✓ |
5 |
if (!optionalHolder) |
172 |
1 |
return calcHashCode(seedValue, 0); |
|
173 |
|||
174 |
4 |
return calcHashCode(seedValue, *optionalHolder); |
|
175 |
} |
||
176 |
|||
177 |
/** |
||
178 |
* Calculates hash code of the given Zserio optional field using the given seed value. |
||
179 |
* |
||
180 |
* \param seedValue Seed value (current hash code). |
||
181 |
* \param optionalHolder Optional field for which to calculate the hash code. |
||
182 |
* |
||
183 |
* \return Calculated hash code. |
||
184 |
*/ |
||
185 |
template <typename FIELD, typename ALLOC> |
||
186 |
2 |
inline uint32_t calcHashCode(uint32_t seedValue, const HeapOptionalHolder<FIELD, ALLOC>& optionalHolder) |
|
187 |
{ |
||
188 |
✓✓ | 2 |
if (!optionalHolder) |
189 |
1 |
return calcHashCode(seedValue, 0); |
|
190 |
|||
191 |
1 |
return calcHashCode(seedValue, *optionalHolder); |
|
192 |
} |
||
193 |
|||
194 |
} // namespace zserio |
||
195 |
|||
196 |
#endif // ZSERIO_HASH_CODE_UTIL_H_INC |
Generated by: GCOVR (Version 4.2) |