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 <iostream>
41#include <concepts>
42#include <cinttypes>
43
44namespace sbx::utility {
45
49template<typename Type>
50concept hashable = requires(const Type& instance) {
51 { std::hash<Type>{}(instance) } -> std::same_as<std::size_t>;
52}; // concept hashable
53
57inline constexpr auto hash_combine([[maybe_unused]] std::size_t& seed) -> void { }
58
69template<hashable Type, hashable... Rest>
70inline constexpr auto hash_combine(std::size_t& seed, const Type& value, Rest... rest) -> void {
71 auto hasher = std::hash<Type>{};
72 seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
73 (hash_combine(seed, rest), ...);
74}
75
81template<typename Type>
82concept 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>;
83
89template<std::unsigned_integral Type>
91
97template<>
98struct fnv1a_traits<std::uint32_t> {
100 inline static constexpr auto basis = std::uint32_t{0x811c9dc5};
102 inline static constexpr auto prime = std::uint32_t{0x01000193};
103}; // struct fnv1a_traits
104
110template<>
111struct fnv1a_traits<std::uint64_t> {
113 inline static constexpr auto basis = std::uint64_t{0xcbf29ce484222325};
115 inline static constexpr auto prime = std::uint64_t{0x00000100000001B3};
116}; // struct fnv1a_traits
117
125template<character Char, std::unsigned_integral Hash = std::uint64_t, typename HashTraits = fnv1a_traits<Hash>>
127 using char_type = Char;
128 using size_type = std::size_t;
129 using hash_type = Hash;
130 using hash_traits = HashTraits;
131
140 inline constexpr auto operator()(std::basic_string_view<Char> string) const noexcept -> hash_type {
141 auto hash = hash_traits::basis;
142
143 for (const auto& character : string) {
144 hash ^= static_cast<hash_type>(character);
145 hash *= hash_traits::prime;
146 }
147
148 return hash;
149 }
150}; // struct fnv1a_hash
151
152} // namespace sbx::utility
153
154#endif // LIBSBX_UTILITY_HASH_HPP_
A concept that represents a character type.
Definition: hash.hpp:82
A concept that represents a type that can be hashed.
Definition: hash.hpp:50
constexpr auto hash_combine(std::size_t &seed) -> void
Combines multiple hashes into a single hash.
Definition: hash.hpp:57
Functor that implements the fnv1a hash algorithm.
Definition: hash.hpp:126
constexpr auto operator()(std::basic_string_view< Char > string) const noexcept -> hash_type
Hashes the given string.
Definition: hash.hpp:140
Traits for the fnv1a hash function.
Definition: hash.hpp:90