Sen API
Sen Libraries
Loading...
Searching...
No Matches
hash32.h
Go to the documentation of this file.
1// === hash32.h ========================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_CORE_BASE_HASH32_H
9#define SEN_CORE_BASE_HASH32_H
10
12
13// std
14#include <array>
15#include <cstdint>
16#include <cstring>
17#include <filesystem>
18#include <numeric>
19#include <string>
20#include <string_view>
21
25
26namespace sen
27{
28
31
33constexpr u32 hashSeed = 23835769U;
34constexpr u32 propertyHashSeed = 19830715U;
35constexpr u32 methodHashSeed = 93580253U;
36constexpr u32 eventHashSeed = 12125807U;
37
39constexpr u32 nonPresentTypeHash = 18121997U;
40
43template <typename InputIterator>
44[[nodiscard]] u32 crc32(InputIterator first, InputIterator last) noexcept;
45
47[[nodiscard]] inline u32 crc32(std::string_view str) noexcept { return crc32(str.begin(), str.end()); }
48
50template <typename... Types>
51[[nodiscard]] u32 hashCombine(u32 seed, const Types&... args) noexcept;
52
56template <typename... Types>
57[[nodiscard]] uint_fast32_t platformDependentHashCombine(uint_fast32_t seed, const Types&... args) noexcept;
58
60unsigned char* decompressSymbol(const void* compressedData);
61
63[[nodiscard]] std::string decompressSymbolToString(const void* compressedData, unsigned int originalSize);
64
66[[nodiscard]] bool fileToCompressedArrayFile(const std::filesystem::path& inputFile,
67 std::string_view symbolName,
68 const std::filesystem::path& outputFile);
69
71
72//----------------------------------------------------------------------------------------------------------------------
73// Inline implementation
74//----------------------------------------------------------------------------------------------------------------------
75
76namespace impl
77{
78
79// FN-1a implementation of the hash
80constexpr u32 fnv1aOffsetBasis = 0x811c9dc5;
81constexpr u32 fnv1aPrime = 0x01000193;
82
84template <typename T>
85inline constexpr std::enable_if_t<std::is_integral_v<T>, u32> hashIntegral(T value) noexcept
86{
87 using UT = std::make_unsigned_t<T>;
88 auto u = static_cast<UT>(value);
89
90 auto hash = fnv1aOffsetBasis;
91
92 // process from most-significant byte to least-significant
93 for (int i = (sizeof(UT) - 1) * 8; i >= 0; i -= 8)
94 {
95 hash ^= static_cast<u8>((u >> i) & 0xFF); // NOLINT
96 hash *= fnv1aPrime;
97 }
98
99 return hash;
100}
101
103template <typename T>
104inline constexpr std::enable_if_t<std::is_floating_point_v<T>, u32> hashFloat(T value) noexcept
105{
106 using IntType = std::conditional_t<sizeof(T) == 4, u32, u64>;
107
108 IntType bits = 0;
109 std::memcpy(&bits, &value, sizeof(T));
110 return hashIntegral(bits);
111}
112
113template <typename T, typename Enable = void>
114struct hash;
115
116template <typename T>
117struct hash<T, typename std::enable_if_t<std::is_integral_v<T>>>
118{
119 inline u32 operator()(T value) const noexcept { return hashIntegral(value); }
120};
121
122template <typename T>
123struct hash<T, typename std::enable_if_t<std::is_floating_point_v<T>>>
124{
125 inline u32 operator()(T value) const noexcept { return hashFloat(value); }
126};
127
128template <>
129struct hash<bool>
130{
131 inline u32 operator()(bool value) const noexcept { return hashIntegral(static_cast<u8>(value)); }
132};
133
134template <>
135struct hash<i8>
136{
137 inline u32 operator()(i8 value) const noexcept { return hashIntegral(static_cast<u8>(value)); }
138};
139
140template <>
141struct hash<std::basic_string_view<char>>
142{
143 inline u32 operator()(const std::basic_string_view<char>& value) const noexcept
144 {
145 auto hash = fnv1aOffsetBasis;
146
147 for (unsigned char c: value)
148 {
149 hash ^= c;
150 hash *= fnv1aPrime;
151 }
152
153 return hash;
154 }
155};
156
157template <>
158struct hash<std::basic_string<char>>
159{
160 inline u32 operator()(const std::basic_string<char>& value) const noexcept
161 {
162 return hash<std::basic_string_view<char>>()(value);
163 }
164};
165
166template <typename T>
167struct hash<T, std::enable_if_t<std::is_enum_v<T>>>
168{
169 inline u32 operator()(T value) const noexcept { return hashIntegral(static_cast<std::underlying_type_t<T>>(value)); }
170};
171
172template <typename T>
173struct hash<T*>
174{
175 u32 operator()(T* value) const noexcept
176 {
177 return hashIntegral(reinterpret_cast<std::uintptr_t>(value)); // NOLINT
178 }
179};
180
181[[nodiscard]] std::array<u32, 256> generateCrc32LookupTable() noexcept; // NOLINT
182
183template <typename T>
184inline void hashCombineImpl(u32& seed, const T& val) noexcept
185{
186 seed ^= hash<T>()(val) + 0x9e3779b9U + (seed << 6) + (seed >> 2); // NOLINT
187}
188
189template <typename T>
190inline void platformDependentHashCombineImpl(std::uint_fast32_t& seed, const T& val) noexcept
191{
192 seed ^= std::hash<T>()(val) + 0x9e3779b9U + (seed << 6) + (seed >> 2); // NOLINT
193}
194
195} // namespace impl
196
197template <typename InputIterator>
198inline u32 crc32(InputIterator first, InputIterator last) noexcept
199{
200 // generate lookup table only on first use then cache it - this is thread-safe.
201 static auto const table = impl::generateCrc32LookupTable();
202
203 // calculate the checksum - make sure to clip to 32 bits, for systems that don't
204 // have a true (fast) 32-bit type.
205 return u32 {0xffffffffUL} & // NOLINT
206 ~std::accumulate(first,
207 last,
208 ~u32 {0} & u32 {0xffffffffUL}, // NOLINT
209 [](u32 checksum, u32 value)
210 { return table[(checksum ^ value) & 0xffU] ^ (checksum >> 8U); }); // NOLINT
211}
212
213template <typename... Types>
214inline u32 hashCombine(u32 seed, const Types&... args) noexcept
215{
216 (impl::hashCombineImpl(seed, args), ...);
217 return seed;
218}
219
220template <typename... Types>
221inline std::uint_fast32_t platformDependentHashCombine(std::uint_fast32_t seed, const Types&... args) noexcept
222{
223 (impl::platformDependentHashCombineImpl(seed, args), ...);
224 return seed;
225}
226
227} // namespace sen
228
229#endif // SEN_CORE_BASE_HASH32_H
constexpr u32 hashSeed
Initial seed for all hashes.
Definition hash32.h:33
u32 crc32(InputIterator first, InputIterator last) noexcept
Calculates the CRC32 for any sequence of values. (You could use type traits and a static assert to en...
Definition hash32.h:198
std::string decompressSymbolToString(const void *compressedData, unsigned int originalSize)
Decompresses a blob into a string.
constexpr u32 propertyHashSeed
Definition hash32.h:34
constexpr u32 methodHashSeed
Definition hash32.h:35
uint_fast32_t platformDependentHashCombine(uint_fast32_t seed, const Types &... args) noexcept
Old version of the hashCombine method. The current one replaced this implementation to allow sen proc...
constexpr u32 eventHashSeed
Definition hash32.h:36
u32 hashCombine(u32 seed, const Types &... args) noexcept
Combines the hash of different values into a single 32-bit hash.
Definition hash32.h:214
unsigned char * decompressSymbol(const void *compressedData)
Decompresses a blob into its original shape.
constexpr u32 nonPresentTypeHash
This hash is combined when no Type is found in a certain spec.
Definition hash32.h:39
bool fileToCompressedArrayFile(const std::filesystem::path &inputFile, std::string_view symbolName, const std::filesystem::path &outputFile)
Creates a C++ source file that contains an array representing the contents of another file.
int8_t i8
Definition numbers.h:20
uint64_t u64
Definition numbers.h:27
uint32_t u32
Definition numbers.h:25
uint8_t u8
Definition numbers.h:21
Definition assert.h:17
STL namespace.