nfx-hashing 0.1.2
Modern C++20 header-only hashing library with hardware acceleration
Loading...
Searching...
No Matches
Hasher.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 nfx
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
31
32#pragma once
33
34#include <array>
35#include <cstdint>
36#include <optional>
37#include <span>
38#include <string>
39#include <string_view>
40#include <type_traits>
41#include <tuple>
42#include <variant>
43#include <vector>
44
45#include "Concepts.h"
46
47#include "Constants.h"
48
49namespace nfx::hashing
50{
51 //=====================================================================
52 // Type trait helpers for SFINAE
53 //=====================================================================
54
55 template <typename T>
56 struct is_std_pair : std::false_type
57 {
58 };
59
60 template <typename T1, typename T2>
61 struct is_std_pair<std::pair<T1, T2>> : std::true_type
62 {
63 };
64
65 template <typename T>
66 struct is_std_tuple : std::false_type
67 {
68 };
69
70 template <typename... Ts>
71 struct is_std_tuple<std::tuple<Ts...>> : std::true_type
72 {
73 };
74
75 template <typename T>
76 struct is_std_array : std::false_type
77 {
78 };
79
80 template <typename T, std::size_t N>
81 struct is_std_array<std::array<T, N>> : std::true_type
82 {
83 };
84
85 template <typename T>
86 struct is_std_vector : std::false_type
87 {
88 };
89
90 template <typename T>
91 struct is_std_vector<std::vector<T>> : std::true_type
92 {
93 };
94
95 template <typename T>
96 struct is_std_span : std::false_type
97 {
98 };
99
100 template <typename T, std::size_t Extent>
101 struct is_std_span<std::span<T, Extent>> : std::true_type
102 {
103 };
104
105 template <typename T>
106 struct is_std_optional : std::false_type
107 {
108 };
109
110 template <typename T>
111 struct is_std_optional<std::optional<T>> : std::true_type
112 {
113 };
114
115 template <typename T>
116 struct is_std_variant : std::false_type
117 {
118 };
119
120 template <typename... Ts>
121 struct is_std_variant<std::variant<Ts...>> : std::true_type
122 {
123 };
124
125 //=====================================================================
126 // General-purpose STL-compatible hash functor
127 //=====================================================================
128
167 template <Hash32or64 HashType = uint32_t, HashType Seed = ( sizeof( HashType ) == 4 ? constants::FNV_OFFSET_BASIS_32 : constants::FNV_OFFSET_BASIS_64 )>
168 struct Hasher final
169 {
170 //----------------------------------------------
171 // Transparent lookup support
172 //----------------------------------------------
173
178 using is_transparent = void;
179
180 //----------------------------------------------
181 // String type overloads
182 //----------------------------------------------
183
190 [[nodiscard]] inline HashType operator()( std::string_view key ) const noexcept;
191
198 [[nodiscard]] inline HashType operator()( const std::string& key ) const noexcept;
199
206 [[nodiscard]] inline HashType operator()( const char* key ) const noexcept;
207
208 //----------------------------------------------
209 // Integer type overloads
210 //----------------------------------------------
211
219 template <typename TKey>
220 [[nodiscard]] inline std::enable_if_t<std::is_integral_v<TKey>, HashType> operator()( const TKey& key ) const noexcept;
221
222 //----------------------------------------------
223 // Floating-point type overloads
224 //----------------------------------------------
225
233 template <typename T>
234 [[nodiscard]] inline std::enable_if_t<std::is_floating_point_v<T>, HashType> operator()( T value ) const noexcept;
235
236 //----------------------------------------------
237 // Pointer type overloads
238 //----------------------------------------------
239
247 template <typename T>
248 [[nodiscard]] inline std::enable_if_t<std::is_pointer_v<T> && !std::is_same_v<T, const char*> && !std::is_same_v<T, char*>, HashType> operator()( T ptr ) const noexcept;
249
250 //----------------------------------------------
251 // Enum type overloads
252 //----------------------------------------------
253
261 template <typename TKey>
262 [[nodiscard]] inline std::enable_if_t<std::is_enum_v<TKey>, HashType> operator()( const TKey& key ) const noexcept;
263
264 //----------------------------------------------
265 // std::array type overloads
266 //----------------------------------------------
267
276 template <typename T, size_t N>
277 [[nodiscard]] inline HashType operator()( const std::array<T, N>& arr ) const noexcept;
278
279 //----------------------------------------------
280 // std::optional type overloads
281 //----------------------------------------------
282
290 template <typename T>
291 [[nodiscard]] inline HashType operator()( const std::optional<T>& opt ) const noexcept;
292
293 //----------------------------------------------
294 // std::pair type overloads
295 //----------------------------------------------
296
305 template <typename T1, typename T2>
306 [[nodiscard]] inline HashType operator()( const std::pair<T1, T2>& p ) const noexcept;
307
308 //----------------------------------------------
309 // std::span type overloads
310 //----------------------------------------------
311
320 template <typename T, std::size_t Extent = std::dynamic_extent>
321 [[nodiscard]] inline HashType operator()( std::span<T, Extent> sp ) const noexcept;
322
323 //----------------------------------------------
324 // std::tuple type overloads
325 //----------------------------------------------
326
334 template <typename... Ts>
335 [[nodiscard]] inline HashType operator()( const std::tuple<Ts...>& t ) const noexcept;
336
337 //----------------------------------------------
338 // std::variant type overloads
339 //----------------------------------------------
340
348 template <typename... Ts>
349 [[nodiscard]] inline HashType operator()( const std::variant<Ts...>& var ) const noexcept;
350
351 //----------------------------------------------
352 // std::vector type overloads
353 //----------------------------------------------
354
362 template <typename T>
363 [[nodiscard]] inline HashType operator()( const std::vector<T>& vec ) const noexcept;
364
365 //----------------------------------------------
366 // Custom type fallback
367 //----------------------------------------------
368
379 template <typename TKey>
380 [[nodiscard]] inline std::enable_if_t<!std::is_same_v<std::decay_t<TKey>, std::string_view> &&
381 !std::is_same_v<std::decay_t<TKey>, std::string> &&
382 !std::is_same_v<std::decay_t<TKey>, const char*> &&
383 !std::is_integral_v<TKey> &&
384 !std::is_floating_point_v<TKey> &&
385 !std::is_pointer_v<TKey> &&
386 !std::is_enum_v<TKey> &&
394 HashType>
395 operator()( const TKey& key ) const noexcept;
396 };
397} // namespace nfx::hashing
398
399#include "nfx/detail/hashing/Hasher.inl"
Mathematical constants for hash algorithms.
C++20 concepts and type traits for nfx-hashing library.
General-purpose STL-compatible hash functor supporting multiple types.
Definition Hasher.h:169
HashType operator()(const std::variant< Ts... > &var) const noexcept
Hashes a std::variant by combining index and active alternative's hash.
std::enable_if_t< std::is_enum_v< TKey >, HashType > operator()(const TKey &key) const noexcept
Hashes an enum by its underlying integral value.
std::enable_if_t< std::is_integral_v< TKey >, HashType > operator()(const TKey &key) const noexcept
Hashes an integral type using multiplicative hashing.
std::enable_if_t<!std::is_same_v< std::decay_t< TKey >, std::string_view > &&!std::is_same_v< std::decay_t< TKey >, std::string > &&!std::is_same_v< std::decay_t< TKey >, const char * > &&!std::is_integral_v< TKey > &&!std::is_floating_point_v< TKey > &&!std::is_pointer_v< TKey > &&!std::is_enum_v< TKey > &&!is_std_array< TKey >::value &&!is_std_optional< TKey >::value &&!is_std_pair< TKey >::value &&!is_std_span< TKey >::value &&!is_std_tuple< TKey >::value &&!is_std_variant< TKey >::value &&!is_std_vector< TKey >::value, HashType > operator()(const TKey &key) const noexcept
Hashes custom types using std::hash fallback.
HashType operator()(const std::tuple< Ts... > &t) const noexcept
Hashes a std::tuple by combining hashes of all elements.
HashType operator()(const char *key) const noexcept
Hashes a C-style string using CRC32-C algorithm.
HashType operator()(const std::optional< T > &opt) const noexcept
Hashes a std::optional - nullopt has distinct hash from any value.
void is_transparent
Enables transparent lookup in STL containers.
Definition Hasher.h:178
std::enable_if_t< std::is_floating_point_v< T >, HashType > operator()(T value) const noexcept
Hashes a floating-point value with normalization.
HashType operator()(const std::string &key) const noexcept
Hashes a std::string using CRC32-C algorithm.
HashType operator()(const std::array< T, N > &arr) const noexcept
Hashes a std::array by combining hashes of all elements.
HashType operator()(std::string_view key) const noexcept
Hashes a std::string_view using CRC32-C algorithm.
HashType operator()(std::span< T, Extent > sp) const noexcept
Hashes a std::span by combining hashes of all elements in the view.
HashType operator()(const std::pair< T1, T2 > &p) const noexcept
Hashes a std::pair by combining hashes of both elements.
std::enable_if_t< std::is_pointer_v< T > &&!std::is_same_v< T, const char * > &&!std::is_same_v< T, char * >, HashType > operator()(T ptr) const noexcept
Hashes a pointer by its address.
HashType operator()(const std::vector< T > &vec) const noexcept
Hashes a std::vector by combining size and hashes of all elements.