Zserio C++ runtime library  1.1.0
Built for Zserio 2.15.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 <type_traits>
7 #include <vector>
8 
9 #include "zserio/Enums.h"
10 #include "zserio/FloatUtil.h"
11 #include "zserio/OptionalHolder.h"
12 #include "zserio/Types.h"
13 
14 namespace zserio
15 {
16 
18 static const uint32_t HASH_PRIME_NUMBER = 37;
20 static const uint32_t HASH_SEED = 23;
21 
29 inline uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
30 {
31  return HASH_PRIME_NUMBER * seedValue;
32 }
33 
42 template <typename T>
43 inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) <= 4), uint32_t>::type calcHashCode(
44  uint32_t seedValue, T value)
45 {
46  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(value);
47 }
48 
57 template <typename T>
58 inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) > 4), uint32_t>::type calcHashCode(
59  uint32_t seedValue, T value)
60 {
61  const auto unsignedValue = static_cast<typename std::make_unsigned<T>::type>(value);
62  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(unsignedValue ^ (unsignedValue >> 32U));
63 }
64 
73 inline uint32_t calcHashCode(uint32_t seedValue, float value)
74 {
75  return calcHashCode(seedValue, convertFloatToUInt32(value));
76 }
77 
86 inline uint32_t calcHashCode(uint32_t seedValue, double value)
87 {
88  return calcHashCode(seedValue, convertDoubleToUInt64(value));
89 }
90 
99 template <typename ALLOC>
100 inline uint32_t calcHashCode(
101  uint32_t seedValue, const std::basic_string<char, std::char_traits<char>, ALLOC>& stringValue)
102 {
103  uint32_t result = seedValue;
104  for (auto element : stringValue)
105  {
106  result = calcHashCode(result, element);
107  }
108 
109  return result;
110 }
111 
120 template <typename ENUM_TYPE>
121 inline typename std::enable_if<std::is_enum<ENUM_TYPE>::value, uint32_t>::type calcHashCode(
122  uint32_t seedValue, ENUM_TYPE enumValue)
123 {
124  return calcHashCode(seedValue, enumHashCode(enumValue));
125 }
126 
135 template <typename OBJECT>
136 inline typename std::enable_if<!std::is_enum<OBJECT>::value && !std::is_integral<OBJECT>::value, uint32_t>::type
137 calcHashCode(uint32_t seedValue, const OBJECT& object)
138 {
139  return calcHashCode(seedValue, object.hashCode());
140 }
141 
150 template <typename ARRAY_ELEMENT, typename ALLOC>
151 inline uint32_t calcHashCode(uint32_t seedValue, const std::vector<ARRAY_ELEMENT, ALLOC>& array)
152 {
153  uint32_t result = seedValue;
154  for (const ARRAY_ELEMENT& element : array)
155  {
156  result = calcHashCode(result, element);
157  }
158 
159  return result;
160 }
161 
162 // must be last because of the two-phase lookup
163 // - we can have optional array (OptionalHolder<std::vector<T>>), but we cannot have array of optionals
172 template <typename FIELD>
173 inline uint32_t calcHashCode(uint32_t seedValue, const InplaceOptionalHolder<FIELD>& optionalHolder)
174 {
175  if (!optionalHolder)
176  {
177  return calcHashCode(seedValue, 0);
178  }
179 
180  return calcHashCode(seedValue, *optionalHolder);
181 }
182 
191 template <typename FIELD, typename ALLOC>
192 inline uint32_t calcHashCode(uint32_t seedValue, const HeapOptionalHolder<FIELD, ALLOC>& optionalHolder)
193 {
194  if (!optionalHolder)
195  {
196  return calcHashCode(seedValue, 0);
197  }
198 
199  return calcHashCode(seedValue, *optionalHolder);
200 }
201 
202 } // namespace zserio
203 
204 #endif // ZSERIO_HASH_CODE_UTIL_H_INC
uint64_t convertDoubleToUInt64(double float64)
Definition: FloatUtil.cpp:193
uint32_t convertFloatToUInt32(float float32)
Definition: FloatUtil.cpp:177
uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
Definition: HashCodeUtil.h:29
std::enable_if< std::is_integral< T >::value &&(sizeof(T)<=4), uint32_t >::type calcHashCode(uint32_t seedValue, T value)
Definition: HashCodeUtil.h:43
detail::heap_optional_holder< T, ALLOC > HeapOptionalHolder
uint32_t enumHashCode(T value)
detail::inplace_optional_holder< T > InplaceOptionalHolder