sandbox
Loading...
Searching...
No Matches
hash.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Jonas Kabelitz
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * You should have received a copy of the MIT License along with this program.
23 * If not, see <https://opensource.org/licenses/MIT/>.
24 */
25
30#ifndef LIBSBX_UTILITY_HASH_HPP_
31#define LIBSBX_UTILITY_HASH_HPP_
32
37#include <utility>
38#include <string>
39#include <string_view>
40#include <span>
41#include <iostream>
42#include <concepts>
43#include <cinttypes>
44
45namespace sbx::utility {
46
50template<typename Type>
51concept hashable = requires(const Type& instance) {
52 { std::hash<Type>{}(instance) } -> std::same_as<std::size_t>;
53}; // concept hashable
54
58inline constexpr auto hash_combine([[maybe_unused]] std::size_t& seed) -> void { }
59
70template<hashable Type, hashable... Rest>
71inline constexpr auto hash_combine(std::size_t& seed, const Type& value, Rest... rest) -> void {
72 auto hasher = std::hash<Type>{};
73 seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
74 (hash_combine(seed, rest), ...);
75}
76
82template<typename Type>
83concept character = std::same_as<Type, char> || std::same_as<Type, wchar_t> || std::same_as<Type, char8_t> || std::same_as<Type, char16_t> || std::same_as<Type, char32_t>;
84
90template<std::unsigned_integral Type>
92
98template<>
99struct fnv1a_traits<std::uint32_t> {
101 inline static constexpr auto basis = std::uint32_t{0x811c9dc5};
103 inline static constexpr auto prime = std::uint32_t{0x01000193};
104}; // struct fnv1a_traits
105
111template<>
112struct fnv1a_traits<std::uint64_t> {
114 inline static constexpr auto basis = std::uint64_t{0xcbf29ce484222325};
116 inline static constexpr auto prime = std::uint64_t{0x00000100000001B3};
117}; // struct fnv1a_traits
118
126template<character Char, std::unsigned_integral Hash = std::uint64_t, typename HashTraits = fnv1a_traits<Hash>>
128 using char_type = Char;
129 using size_type = std::size_t;
130 using hash_type = Hash;
131 using hash_traits = HashTraits;
132
141 inline constexpr auto operator()(std::basic_string_view<Char> string) const noexcept -> hash_type {
142 auto hash = hash_traits::basis;
143
144 for (const auto& character : string) {
145 hash ^= static_cast<hash_type>(character);
146 hash *= hash_traits::prime;
147 }
148
149 return hash;
150 }
151}; // struct fnv1a_hash
152
153template<std::unsigned_integral Hash = std::uint64_t>
154struct djb2_hash {
155
156 using hash_type = Hash;
157
158 inline constexpr auto operator()(std::span<const std::uint8_t> buffer) const noexcept -> hash_type {
159 // Implementation from https://theartincode.stanis.me/008-djb2/
160 auto hash = hash_type{5381};
161
162 for (auto byte : buffer) {
163 hash = ((hash << 5) + hash) + static_cast<std::int32_t>(byte);
164 }
165
166 return hash;
167 }
168
169 template<typename Type>
170 requires (std::is_trivially_copyable_v<Type>)
171 inline constexpr auto operator()(const Type& value) const noexcept -> hash_type {
172 return operator()({reinterpret_cast<std::uint8_t*>(std::addressof(value)), sizeof(Type)});
173 }
174
175}; // struct djb2_hash
176
177} // namespace sbx::utility
178
179#endif // LIBSBX_UTILITY_HASH_HPP_
A concept that represents a character type.
Definition: hash.hpp:83
A concept that represents a type that can be hashed.
Definition: hash.hpp:51
constexpr auto hash_combine(std::size_t &seed) -> void
Combines multiple hashes into a single hash.
Definition: hash.hpp:58
Definition: hash.hpp:154
Functor that implements the fnv1a hash algorithm.
Definition: hash.hpp:127
constexpr auto operator()(std::basic_string_view< Char > string) const noexcept -> hash_type
Hashes the given string.
Definition: hash.hpp:141
Traits for the fnv1a hash function.
Definition: hash.hpp:91