Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
hash.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_HASH_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_HASH_HPP_
7
8// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
9#include "arene/base/constraints.hpp"
10#include "arene/base/span.hpp"
11#include "arene/base/utility.hpp"
12#include "stdlib/include/stdlib_detail/conditional.hpp"
13#include "stdlib/include/stdlib_detail/cstddef.hpp"
14#include "stdlib/include/stdlib_detail/cstdint.hpp"
15#include "stdlib/include/stdlib_detail/enable_if.hpp"
16#include "stdlib/include/stdlib_detail/integral_constant.hpp"
17#include "stdlib/include/stdlib_detail/is_enum.hpp"
18#include "stdlib/include/stdlib_detail/is_fundamental.hpp"
19#include "stdlib/include/stdlib_detail/is_pointer.hpp"
20// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
21
22// The iwyu-private pragma below will direct users to include '<functional>' for use
23// of 'std::hash'
24//
25// Components that provide a specializtion of 'std::hash', should also provide
26// an iwyu-export pragma so that an include of <functional> is not needlessly
27// recommended.
28
29// IWYU pragma: private, include <functional>
30// IWYU pragma: friend "stdlib_detail/.*"
31
32// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
33// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
34
35namespace std {
36
37namespace hash_detail {
38
39/// @brief The FNV prime to use depending on bit variant.
40/// @tparam Scalar the scalar type
41/// @tparam Dummy a dummy type to allow partial specialization of variable template
42///
43/// The value of this constant depends on the bit length of the hash being used, determined by the type of @c Scalar.
44/// The value of this constant for common bit-lengths is provided by the paper "The FNV Non-Cryptographic Hash
45/// Algorithm".
46template <class Scalar, class Dummy = nullptr_t>
47extern constexpr Scalar fnv_prime_v{0};
48
49/// @brief The FNV 64-bit prime
50/// @tparam Dummy a dummy type to allow partial specialization of variable template
51template <class Dummy>
52extern constexpr uint64_t fnv_prime_v<uint64_t, Dummy>{1099511628211ULL};
53
54/// @brief The FNV 32-bit prime
55/// @tparam Dummy a dummy type to allow partial specialization of variable template
56template <class Dummy>
57extern constexpr uint32_t fnv_prime_v<uint32_t, Dummy>{16777619UL};
58
59/// @brief The FNV offset basis to use depending on bit variant.
60/// @tparam Scalar the scalar type
61/// @tparam Dummy a dummy type to allow partial specialization of variable template
62///
63/// The value of this constant depends on the bit length of the hash being used, determined by the type of @c Scalar.
64/// The value of this constant for common bit-lengths is provided by the paper "The FNV Non-Cryptographic Hash
65/// Algorithm".
66template <class Scalar, class Dummy = nullptr_t>
67extern constexpr Scalar fnv_offset_basis_v{0};
68
69/// @brief The FNV 64-bit offset basis
70/// @tparam Dummy a dummy type to allow partial specialization of variable template
71template <class Dummy>
72constexpr uint64_t fnv_offset_basis_v<uint64_t, Dummy>{14695981039346656037ULL};
73
74/// @brief The FNV 32-bit offset basis
75/// @tparam Dummy a dummy type to allow partial specialization of variable template
76template <class Dummy>
77constexpr uint32_t fnv_offset_basis_v<uint32_t, Dummy>{2166136261UL};
78
79/// @brief FNV-1a hash algorithm
80/// @tparam T the type to hash
81///
82/// Implement the Fowler-Noll-Vo hashing algorithm with the 1a variant. This hashing algorithm uses two constants that
83/// depend on the bit-length of @c std::size_t for the current platform.
84///
85/// The algorithm starts with an initial hash value of FNV offset basis. For each byte in the input, XOR the hash with
86/// the byte from the input, then multiply it by the FNV prime:
87/// @code
88/// hash := FNV_offset_basis
89/// for each byte_of_data to be hashed do
90/// hash := hash XOR byte_of_data
91/// hash := hash * FNV_prime
92/// return hash
93/// @endcode
94template <typename T>
96 public:
97 /// @brief The type of the result of the function call operator
99 /// @brief The type of the argument of the function call operator
100 using argument_type = T;
101
102 /// @brief Calculate the hash of a value
103 /// @param value The value to hash
104 /// @return The hash of the value
105 auto operator()(T const& value) const noexcept -> size_t {
106 using scalar_type = conditional_t<sizeof(size_t) == sizeof(uint32_t), uint32_t, uint64_t>;
107
108 scalar_type hash{fnv_offset_basis_v<scalar_type>};
109
110 for (auto const elem : arene::base::as_bytes(arene::base::span<T const, 1U>(&value, 1U))) {
111 hash ^= static_cast<scalar_type>(arene::base::to_underlying(elem));
112 hash *= fnv_prime_v<scalar_type>;
113 }
114 return hash;
115 }
116};
117
118/// @brief Default implementation of @c std::hash implemented only for fundamental types, enumerations and pointers
119/// @tparam T type to hash
120template <class T, typename = arene::base::constraints<>>
121class default_hash;
122
123/// @brief Default implementation of @c std::hash
124///
125/// Specialization for fundamental types, enumerations and pointers
126/// @tparam T type to hash
127template <class T>
130
131} // namespace hash_detail
132
133// parasoft-begin-suppress AUTOSAR-A11_0_2-a "Specified as struct in C++ Standard"
134/// @brief hash function primary template
135/// @tparam T type to hash
136///
137template <class T>
139// parasoft-end-suppress AUTOSAR-A11_0_2-a
140
141} // namespace std
142
143#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_HASH_HPP_
FNV-1a hash algorithm.
Definition hash.hpp:95
auto operator()(T const &value) const noexcept -> size_t
Calculate the hash of a value.
Definition hash.hpp:105
Definition hash.hpp:37
constexpr Scalar fnv_prime_v
The FNV prime to use depending on bit variant.
constexpr Scalar fnv_offset_basis_v
The FNV offset basis to use depending on bit variant.
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827
hash function primary template
Definition hash.hpp:138