Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.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 <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 {
17  static const uint32_t HASH_PRIME_NUMBER = 37;
19  static const uint32_t HASH_SEED = 23;
20 
28  inline uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
29  {
30  return HASH_PRIME_NUMBER * seedValue;
31  }
32 
41  template<typename T>
42  inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) <= 4), uint32_t>::type
43  calcHashCode(uint32_t seedValue, T value)
44  {
45  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(value);
46  }
47 
56  template<typename T>
57  inline typename std::enable_if<std::is_integral<T>::value && (sizeof(T) > 4), uint32_t>::type
58  calcHashCode(uint32_t seedValue, T value)
59  {
60  const auto unsignedValue = static_cast<typename std::make_unsigned<T>::type>(value);
61  return calcHashCodeFirstTerm(seedValue) + static_cast<uint32_t>(unsignedValue ^ (unsignedValue >> 32U));
62  }
63 
72  inline uint32_t calcHashCode(uint32_t seedValue, float value)
73  {
74  return calcHashCode(seedValue, convertFloatToUInt32(value));
75  }
76 
85  inline uint32_t calcHashCode(uint32_t seedValue, double value)
86  {
87  return calcHashCode(seedValue, convertDoubleToUInt64(value));
88  }
89 
98  template <typename ALLOC>
99  inline uint32_t calcHashCode(uint32_t seedValue,
100  const std::basic_string<char, std::char_traits<char>, ALLOC>& stringValue)
101  {
102  uint32_t result = seedValue;
103  for (auto element : stringValue)
104  result = calcHashCode(result, element);
105 
106  return result;
107  }
108 
117  template <typename ENUM_TYPE>
118  inline typename std::enable_if<std::is_enum<ENUM_TYPE>::value, uint32_t>::type calcHashCode(
119  uint32_t seedValue, ENUM_TYPE enumValue)
120  {
121  return calcHashCode(seedValue, enumHashCode(enumValue));
122  }
123 
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  calcHashCode(uint32_t seedValue, const OBJECT& object)
136  {
137  return calcHashCode(seedValue, object.hashCode());
138  }
139 
148  template <typename ARRAY_ELEMENT, typename ALLOC>
149  inline uint32_t calcHashCode(uint32_t seedValue, const std::vector<ARRAY_ELEMENT, ALLOC>& array)
150  {
151  uint32_t result = seedValue;
152  for (const ARRAY_ELEMENT& element : array)
153  result = calcHashCode(result, element);
154 
155  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
168  template <typename FIELD>
169  inline uint32_t calcHashCode(uint32_t seedValue, const InplaceOptionalHolder<FIELD>& optionalHolder)
170  {
171  if (!optionalHolder)
172  return calcHashCode(seedValue, 0);
173 
174  return calcHashCode(seedValue, *optionalHolder);
175  }
176 
185  template <typename FIELD, typename ALLOC>
186  inline uint32_t calcHashCode(uint32_t seedValue, const HeapOptionalHolder<FIELD, ALLOC>& optionalHolder)
187  {
188  if (!optionalHolder)
189  return calcHashCode(seedValue, 0);
190 
191  return calcHashCode(seedValue, *optionalHolder);
192  }
193 
194 } // namespace zserio
195 
196 #endif // ZSERIO_HASH_CODE_UTIL_H_INC
detail::heap_optional_holder< T, ALLOC > HeapOptionalHolder
detail::inplace_optional_holder< T > InplaceOptionalHolder
uint32_t convertFloatToUInt32(float float32)
Definition: FloatUtil.cpp:169
uint32_t enumHashCode(T value)
uint32_t calcHashCodeFirstTerm(uint32_t seedValue)
Definition: HashCodeUtil.h:28
std::enable_if< std::is_integral< T >::value &&(sizeof(T)<=4), uint32_t >::type calcHashCode(uint32_t seedValue, T value)
Definition: HashCodeUtil.h:43
uint64_t convertDoubleToUInt64(double float64)
Definition: FloatUtil.cpp:183