ipaddress 1.1.0
Loading...
Searching...
No Matches
hash.hpp
Go to the documentation of this file.
1/**
2 * @file hash.hpp
3 * @brief Algorithms for calculating hash sums
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * The `hash.hpp` file contains hash templates and functions that can be used to
8 * hash IP addresses or other numeric data.
9 *
10 * This code uses patterns and specializations to optimize the hashing process
11 * for different sizes of data. Magic numbers and bitwise operations in hash_combine
12 * functions help distribute hash values evenly, which is important for avoiding
13 * collisions in hash tables. The hash_sum and calc_hash functions provide a convenient
14 * interface for calculating hash sums and computing the hash sum of multiple values.
15 */
16
17#ifndef IPADDRESS_HASH_HPP
18#define IPADDRESS_HASH_HPP
19
20#include "config.hpp"
21
22namespace IPADDRESS_NAMESPACE {
23
24namespace internal {
25
26template <size_t Size>
27struct hash_combine;
28
29template <>
30struct hash_combine<4> {
31 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t operator()(uint32_t value) const IPADDRESS_NOEXCEPT {
32 value ^= value >> 16;
33 value *= 0x21f0aaad;
34 value ^= value >> 15;
35 value *= 0x735a2d97;
36 value ^= value >> 15;
37 return size_t(value);
38 }
39};
40
41template <>
42struct hash_combine<8> {
43 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t operator()(uint64_t value) const IPADDRESS_NOEXCEPT {
44 value ^= value >> 32;
45 value *= 0xe9846af9b1a615d;
46 value ^= value >> 32;
47 value *= 0xe9846af9b1a615d;
48 value ^= value >> 28;
49 return size_t(value);
50 }
51};
52
53IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t hash_sum(size_t seed, size_t value) IPADDRESS_NOEXCEPT {
54 const hash_combine<sizeof(size_t)> hash{};
55 return hash(seed + 0x9e3779b9 + value);
56}
57
58template <typename Arg>
59IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t calc_hash(size_t seed, Arg arg) IPADDRESS_NOEXCEPT {
60 return hash_sum(seed, arg);
61}
62
63template <typename Arg, typename... Args>
64IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t calc_hash(size_t seed, Arg arg, Args... args) IPADDRESS_NOEXCEPT {
65 seed = hash_sum(seed, size_t(arg));
66 return calc_hash(seed, args...);
67}
68
69} // namespace IPADDRESS_NAMESPACE::internal
70
71} // namespace IPADDRESS_NAMESPACE
72
73#endif // IPADDRESS_HASH_HPP
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89