Zserio C++17 runtime library  0.5.0
Built for Zserio 2.17.0
HashCodeUtil.h
Go to the documentation of this file.
1 #ifndef ZSERIO_HASH_CODE_UTIL_H_INC
2 #define ZSERIO_HASH_CODE_UTIL_H_INC
3 
4 #include <memory>
5 #include <string>
6 #include <string_view>
7 #include <type_traits>
8 #include <variant>
9 #include <vector>
10 
11 #include "zserio/Bytes.h"
12 #include "zserio/FloatUtil.h"
13 #include "zserio/Traits.h"
14 #include "zserio/Types.h"
15 #include "zserio/Vector.h"
16 
17 namespace zserio
18 {
19 
21 static const uint32_t HASH_PRIME_NUMBER = 37;
23 static const uint32_t HASH_SEED = 23;
24 
32 inline uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
33 {
34  return HASH_PRIME_NUMBER * seedValue;
35 }
36 
45 template <typename T>
46 inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) <= 4), uint32_t>::type calcHashCode(
47  uint32_t seedValue, T value)
48 {
49  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(value);
50 }
51 
60 template <typename T>
61 inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) > 4), uint32_t>::type calcHashCode(
62  uint32_t seedValue, T value)
63 {
64  const auto unsignedValue = static_cast<typename std::make_unsigned<T>::type>(value);
65  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(unsignedValue ^ (unsignedValue >> 32U));
66 }
67 
76 inline uint32_t calcHashCode(uint32_t seedValue, float value)
77 {
78  return calcHashCode(seedValue, convertFloatToUInt32(value));
79 }
80 
89 inline uint32_t calcHashCode(uint32_t seedValue, double value)
90 {
91  return calcHashCode(seedValue, convertDoubleToUInt64(value));
92 }
93 
102 inline uint32_t calcHashCode(uint32_t seedValue, Bool value)
103 {
104  return calcHashCode(seedValue, static_cast<Bool::ValueType>(value));
105 }
106 
115 template <BitSize BIT_SIZE, bool IS_SIGNED>
116 inline uint32_t calcHashCode(uint32_t seedValue, detail::FixedIntWrapper<BIT_SIZE, IS_SIGNED> value)
117 {
118  using ValueType = typename detail::FixedIntWrapper<BIT_SIZE, IS_SIGNED>::ValueType;
119  return calcHashCode(seedValue, static_cast<ValueType>(value));
120 }
121 
130 template <typename VALUE_TYPE>
131 inline uint32_t calcHashCode(uint32_t seedValue, detail::DynIntWrapper<VALUE_TYPE> value)
132 {
133  return calcHashCode(seedValue, static_cast<VALUE_TYPE>(value));
134 }
135 
144 template <typename VALUE_TYPE, detail::VarIntType VAR_TYPE>
145 inline uint32_t calcHashCode(uint32_t seedValue, detail::VarIntWrapper<VALUE_TYPE, VAR_TYPE> value)
146 {
147  return calcHashCode(seedValue, static_cast<VALUE_TYPE>(value));
148 }
149 
158 template <typename VALUE_TYPE, detail::FloatType FLOAT_TYPE>
159 inline uint32_t calcHashCode(uint32_t seedValue, detail::FloatWrapper<VALUE_TYPE, FLOAT_TYPE> value)
160 {
161  return calcHashCode(seedValue, static_cast<VALUE_TYPE>(value));
162 }
163 
164 // TODO[Mi-L@]: support all zserio wrappers
165 
174 template <typename ALLOC>
175 inline uint32_t calcHashCode(uint32_t seedValue, const BasicString<ALLOC>& stringValue)
176 {
177  uint32_t result = seedValue;
178  for (auto element : stringValue)
179  {
180  result = calcHashCode(result, element);
181  }
182 
183  return result;
184 }
185 
194 inline uint32_t calcHashCode(uint32_t seedValue, std::string_view stringValue)
195 {
196  uint32_t result = seedValue;
197  for (auto element : stringValue)
198  {
199  result = calcHashCode(result, element);
200  }
201 
202  return result;
203 }
204 
213 template <typename T>
214 inline std::enable_if_t<std::is_enum_v<T> || is_bitmask_v<T>, uint32_t> calcHashCode(
215  uint32_t seedValue, T value)
216 {
217  return calcHashCode(seedValue, std::hash<T>()(value));
218 }
219 
228 template <typename OBJECT>
229 inline std::enable_if_t<!std::is_enum_v<OBJECT> && !is_bitmask_v<OBJECT> && !std::is_integral_v<OBJECT>,
230  uint32_t>
231 calcHashCode(uint32_t seedValue, const OBJECT& object)
232 {
233  return calcHashCode(seedValue, std::hash<OBJECT>()(object));
234 }
235 
236 // TODO[Mi-L@]: implement for a generic span?
245 inline uint32_t calcHashCode(uint32_t seedValue, const BytesView& bytes)
246 {
247  uint32_t result = seedValue;
248  for (auto byte : bytes)
249  {
250  result = calcHashCode(result, byte);
251  }
252 
253  return result;
254 }
255 
264 template <typename ARRAY_ELEMENT, typename ALLOC>
265 inline uint32_t calcHashCode(uint32_t seedValue, const Vector<ARRAY_ELEMENT, ALLOC>& array)
266 {
267  uint32_t result = seedValue;
268  for (const ARRAY_ELEMENT& element : array)
269  {
270  result = calcHashCode(result, element);
271  }
272 
273  return result;
274 }
275 
284 inline uint32_t calcHashCode(uint32_t seedValue, std::monostate)
285 {
286  return calcHashCode(seedValue, 1729);
287 }
288 
289 } // namespace zserio
290 
291 #endif // ZSERIO_HASH_CODE_UTIL_H_INC
uint64_t convertDoubleToUInt64(double float64)
Definition: FloatUtil.cpp:193
detail::BoolWrapper Bool
Definition: Types.h:732
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
Definition: String.h:17
std::vector< T, ALLOC > Vector
Definition: Vector.h:13
uint32_t convertFloatToUInt32(float float32)
Definition: FloatUtil.cpp:177
uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
Definition: HashCodeUtil.h:32
uint32_t calcHashCode(uint32_t seedValue, const ArrayView< T, ARRAY_TRAITS > &array)
Definition: ArrayView.h:860