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 <memory>
19#include <numeric>
20#include <string>
21#include <string_view>
22
26
27namespace sen
28{
29
32
34constexpr u32 hashSeed = 23835769U;
35constexpr u32 propertyHashSeed = 19830715U;
36constexpr u32 methodHashSeed = 93580253U;
37constexpr u32 eventHashSeed = 12125807U;
38
40constexpr u32 nonPresentTypeHash = 18121997U;
41
44template <typename InputIterator>
45[[nodiscard]] u32 crc32(InputIterator first, InputIterator last) noexcept;
46
48[[nodiscard]] inline u32 crc32(std::string_view str) noexcept { return crc32(str.begin(), str.end()); }
49
51template <typename... Types>
52[[nodiscard]] u32 hashCombine(u32 seed, const Types&... args) noexcept;
53
57template <typename... Types>
58[[nodiscard]] uint_fast32_t platformDependentHashCombine(uint_fast32_t seed, const Types&... args) noexcept;
59
61[[nodiscard]] std::unique_ptr<unsigned char[]> decompressSymbol(const void* compressedData);
62
64[[nodiscard]] std::string decompressSymbolToString(const void* compressedData, unsigned int originalSize);
65
67[[nodiscard]] bool fileToCompressedArrayFile(const std::filesystem::path& inputFile,
68 std::string_view symbolName,
69 const std::filesystem::path& outputFile);
70
72
73//----------------------------------------------------------------------------------------------------------------------
74// Inline implementation
75//----------------------------------------------------------------------------------------------------------------------
76
77namespace impl
78{
79
80// FN-1a implementation of the hash
81constexpr u32 fnv1aOffsetBasis = 0x811c9dc5;
82constexpr u32 fnv1aPrime = 0x01000193;
83
85template <typename T>
86inline constexpr std::enable_if_t<std::is_integral_v<T>, u32> hashIntegral(T value) noexcept
87{
88 using UT = std::make_unsigned_t<T>;
89 auto u = static_cast<UT>(value);
90
91 auto hash = fnv1aOffsetBasis;
92
93 // process from most-significant byte to least-significant
94 for (int i = (sizeof(UT) - 1) * 8; i >= 0; i -= 8)
95 {
96 hash ^= static_cast<u8>((u >> i) & 0xFF); // NOLINT
97 hash *= fnv1aPrime;
98 }
99
100 return hash;
101}
102
104template <typename T>
105inline constexpr std::enable_if_t<std::is_floating_point_v<T>, u32> hashFloat(T value) noexcept
106{
107 using IntType = std::conditional_t<sizeof(T) == 4, u32, u64>;
108
109 IntType bits = 0;
110 std::memcpy(&bits, &value, sizeof(T));
111 return hashIntegral(bits);
112}
113
114template <typename T, typename Enable = void>
115struct hash;
116
117template <typename T>
118struct hash<T, typename std::enable_if_t<std::is_integral_v<T>>>
119{
120 inline u32 operator()(T value) const noexcept { return hashIntegral(value); }
121};
122
123template <typename T>
124struct hash<T, typename std::enable_if_t<std::is_floating_point_v<T>>>
125{
126 inline u32 operator()(T value) const noexcept { return hashFloat(value); }
127};
128
129template <>
130struct hash<bool>
131{
132 inline u32 operator()(bool value) const noexcept { return hashIntegral(static_cast<u8>(value)); }
133};
134
135template <>
136struct hash<i8>
137{
138 inline u32 operator()(i8 value) const noexcept { return hashIntegral(static_cast<u8>(value)); }
139};
140
141template <>
142struct hash<std::basic_string_view<char>>
143{
144 inline u32 operator()(const std::basic_string_view<char>& value) const noexcept
145 {
146 auto hash = fnv1aOffsetBasis;
147
148 for (unsigned char c: value)
149 {
150 hash ^= c;
151 hash *= fnv1aPrime;
152 }
153
154 return hash;
155 }
156};
157
158template <>
159struct hash<std::basic_string<char>>
160{
161 inline u32 operator()(const std::basic_string<char>& value) const noexcept
162 {
163 return hash<std::basic_string_view<char>>()(value);
164 }
165};
166
167template <typename T>
168struct hash<T, std::enable_if_t<std::is_enum_v<T>>>
169{
170 inline u32 operator()(T value) const noexcept { return hashIntegral(static_cast<std::underlying_type_t<T>>(value)); }
171};
172
173template <typename T>
174struct hash<T*>
175{
176 u32 operator()(T* value) const noexcept
177 {
178 return hashIntegral(reinterpret_cast<std::uintptr_t>(value)); // NOLINT
179 }
180};
181
182[[nodiscard]] std::array<u32, 256> generateCrc32LookupTable() noexcept; // NOLINT
183
184template <typename T>
185inline void hashCombineImpl(u32& seed, const T& val) noexcept
186{
187 seed ^= hash<T>()(val) + 0x9e3779b9U + (seed << 6) + (seed >> 2); // NOLINT
188}
189
190template <typename T>
191inline void platformDependentHashCombineImpl(std::uint_fast32_t& seed, const T& val) noexcept
192{
193 seed ^= std::hash<T>()(val) + 0x9e3779b9U + (seed << 6) + (seed >> 2); // NOLINT
194}
195
196} // namespace impl
197
198template <typename InputIterator>
199inline u32 crc32(InputIterator first, InputIterator last) noexcept
200{
201 // generate lookup table only on first use then cache it - this is thread-safe.
202 static auto const table = impl::generateCrc32LookupTable();
203
204 // calculate the checksum - make sure to clip to 32 bits, for systems that don't
205 // have a true (fast) 32-bit type.
206 return u32 {0xffffffffUL} & // NOLINT
207 ~std::accumulate(first,
208 last,
209 ~u32 {0} & u32 {0xffffffffUL}, // NOLINT
210 [](u32 checksum, u32 value)
211 { return table[(checksum ^ value) & 0xffU] ^ (checksum >> 8U); }); // NOLINT
212}
213
214template <typename... Types>
215inline u32 hashCombine(u32 seed, const Types&... args) noexcept
216{
217 (impl::hashCombineImpl(seed, args), ...);
218 return seed;
219}
220
221template <typename... Types>
222inline std::uint_fast32_t platformDependentHashCombine(std::uint_fast32_t seed, const Types&... args) noexcept
223{
224 (impl::platformDependentHashCombineImpl(seed, args), ...);
225 return seed;
226}
227
228} // namespace sen
229
230#endif // SEN_CORE_BASE_HASH32_H
constexpr u32 hashSeed
Initial seed for all hashes.
Definition hash32.h:34
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:199
std::string decompressSymbolToString(const void *compressedData, unsigned int originalSize)
Decompresses a blob into a string.
constexpr u32 propertyHashSeed
Definition hash32.h:35
constexpr u32 methodHashSeed
Definition hash32.h:36
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:37
u32 hashCombine(u32 seed, const Types &... args) noexcept
Combines the hash of different values into a single 32-bit hash.
Definition hash32.h:215
std::unique_ptr< 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:40
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.