kblib 0.2.3
General utilities library for modern C++
hash.cpp
Go to the documentation of this file.
1#include "kblib/hash.h"
2
3#include "catch.hpp"
4
5#include <deque>
6#include <map>
7#include <set>
8#include <unordered_map>
9
11 char c;
12 int i;
13};
14
15struct no_padding {
16 int i, j;
17};
18
19struct empty_t {};
20
21static_assert(
22 kblib::is_linear_container_v<
23 std::
24 string> and kblib::is_contiguous_v<std::string> and kblib::is_trivially_hashable_v<std::string::value_type> and kblib::is_trivially_hashable_v<int*>,
25 "");
26static_assert(kblib::asserts::is_trivial_container<std::vector<char>>, "");
27
28#if KBLIB_USE_CXX17
29static_assert(kblib::is_trivially_hashable_v<no_padding>);
30static_assert(std::is_same_v<decltype(kblib::FNV_hash<no_padding>{}(
31 std::declval<no_padding&>())),
32 std::size_t>);
33static_assert(
34 std::is_default_constructible_v<kblib::FNV_hash<
35 no_padding>> and std::is_invocable_r_v<std::size_t, kblib::FNV_hash<no_padding>, const no_padding&>);
36#endif
37
38template <typename T>
39static constexpr bool is_disabled_hash
40 = not (std::is_nothrow_default_constructible_v<kblib::FNV_hash<
41 T>> and std::is_invocable_v<kblib::FNV_hash<T>, const T&>);
42template <typename T>
43static constexpr bool is_enabled_hash
44 = std::is_nothrow_default_constructible_v<kblib::FNV_hash<T>>and
45 std::is_invocable_r_v<std::size_t, kblib::FNV_hash<T>, const T&>;
46
47TEST_CASE("FNV_hash") {
48 (void)kblib::FNV_hash<int*>{}({});
50 (void)kblib::FNV_hash<std::vector<char>>{}({});
51 (void)kblib::FNV_hash<std::vector<int>>{}({});
52 (void)kblib::FNV_hash<std::deque<char>>{}({});
53 (void)kblib::FNV_hash<std::tuple<>>{}({});
54 (void)kblib::FNV_hash<std::tuple<int*>>{}({});
55 (void)kblib::FNV_hash<std::tuple<std::wstring, int*>>{}({});
57 (void)kblib::FNV_hash<std::vector<int>::iterator>{}({});
58 (void)kblib::FNV_hash<std::deque<char>::iterator>{}({});
59 (void)kblib::FNV_hash<std::set<int>::iterator>{}({});
60
61 std::unordered_map<std::tuple<std::wstring, int*>,
62 std::vector<std::basic_string<bool>>, kblib::FNV_hash<>,
63 std::equal_to<>>
64 test_map;
66 std::vector<std::basic_string<bool>>>;
67 static_assert(std::is_same<decltype(test_map), map_t>::value, "");
72 test_hash1c;
74 std::vector<std::basic_string<bool>>>>
75 test_hash2;
77 test_hash3;
78 KBLIB_UNUSED auto call = &decltype(test_hash1)::operator();
79 // std::hash<
80 // std::unordered_map<std::wstring, std::vector<std::basic_string<bool>>,
81 // std::hash<std::wstring>>>
82 // std_hash;
83 using namespace kblib::literals;
85 static_assert(3452452_fnv64 == h_i(3452452ull),
86 "hash literal and FNH_hash don't agree");
87
88 CHECK(kblib::FNV_hash<int>{}(1000) == 0x2fa9eaf82259d71cu);
89 (void)kblib::FNV_hash<std::vector<int>>{}({});
90 (void)kblib::FNV_hash<std::vector<empty_t>>{}({});
91 // fails because of padding:
92 static_assert(is_disabled_hash<std::vector<has_padding>>);
93 // fails because of unorderedness:
94 static_assert(is_disabled_hash<std::unordered_map<int, int>>);
95
97 CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i));
98#if KBLIB_USE_CXX17
100 (void)test_opt_hash(std::nullopt);
101 (void)test_opt_hash(42);
102 CHECK(test_opt_hash(42) == kblib::FNV_hash<int>{}(42));
103
104 std::variant<int, int, std::string> var(std::in_place_index<1>, 42);
105 kblib::FNV_hash<decltype(var)> test_var_hash;
106 CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash<int>{}(42));
107 CHECK_FALSE(test_var_hash(var)
108 == test_var_hash(decltype(var){std::in_place_index<0>, 42}));
109#endif
110}
111TEST_CASE("FNV_hash (32 bit)") {
114 (void)kblib::FNV_hash<std::vector<char>, std::uint32_t>{}({});
115 (void)kblib::FNV_hash<std::vector<int>, std::uint32_t>{}({});
116 (void)kblib::FNV_hash<std::deque<char>, std::uint32_t>{}({});
117 (void)kblib::FNV_hash<std::tuple<>, std::uint32_t>{}({});
118 (void)kblib::FNV_hash<std::tuple<int*>, std::uint32_t>{}({});
119 (void)kblib::FNV_hash<std::tuple<std::wstring, int*>, std::uint32_t>{}({});
121 (void)kblib::FNV_hash<std::vector<int>::iterator, std::uint32_t>{}({});
122 (void)kblib::FNV_hash<std::deque<char>::iterator, std::uint32_t>{}({});
123 (void)kblib::FNV_hash<std::set<int>::iterator, std::uint32_t>{}({});
124
125 KBLIB_UNUSED kblib::FNV_hash<std::map<int, int>, std::uint32_t> test_hash1;
127 test_hash1a;
129 test_hash1b;
131 std::uint32_t>
132 test_hash1c;
134 std::vector<std::basic_string<bool>>>,
135 std::uint32_t>
136 test_hash2;
139 test_hash3;
140 KBLIB_UNUSED auto call = &decltype(test_hash1)::operator();
141 // std::hash<
142 // std::unordered_map<std::wstring, std::vector<std::basic_string<bool>>,
143 // std::hash<std::wstring>>>
144 // std_hash;
145 using namespace kblib::literals;
147 static_assert(3452452_fnv32 == h_i(3452452u),
148 "hash literal and FNH_hash don't agree");
149
150 CHECK(kblib::FNV_hash<int, std::uint32_t>{}(1000) == 0xf49c691cu);
151 (void)kblib::FNV_hash<std::vector<int>, std::uint32_t>{}({});
152 (void)kblib::FNV_hash<std::vector<empty_t>, std::uint32_t>{}({});
153 // fails because of padding:
154 // kblib::FNV_hash<std::vector<has_padding>>{}({});
155 // fails because of unorderedness:
156 // kblib::FNV_hash<std::unordered_map<int, int>>{}({});
157
159 CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i));
160#if KBLIB_USE_CXX17
161 kblib::FNV_hash<std::optional<int>, std::uint32_t> test_opt_hash;
162 (void)test_opt_hash(std::nullopt);
163 (void)test_opt_hash(42);
164 CHECK(test_opt_hash(42) == kblib::FNV_hash<int, std::uint32_t>{}(42));
165
166 std::variant<int, int, std::string> var(std::in_place_index<1>, 42);
167 kblib::FNV_hash<decltype(var)> test_var_hash;
168 CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash<int, std::uint32_t>{}(42));
169 CHECK_FALSE(test_var_hash(var)
170 == test_var_hash(decltype(var){std::in_place_index<0>, 42}));
171#endif
172}
TEST_CASE("FNV_hash")
Definition: hash.cpp:47
Provides generic facilities for hashing data, and aliases for standard unordered containers using the...
constexpr bool is_invocable_v
Definition: fakestd.h:453
std::unordered_map< Key, Value, FNV_hash<>, std::equal_to<> > hash_map
Definition: hash.h:764
Definition: hash.cpp:19
char c
Definition: hash.cpp:11
int i
Definition: hash.cpp:12
The primary template has to exist, but not be constructible, in order to be compatible with std::hash...
Definition: hash.h:334
int i
Definition: hash.cpp:16
int j
Definition: hash.cpp:16
#define KBLIB_UNUSED
This internal macro is used to provide a fallback for [[maybe_unused]] in C++14.
Definition: tdecl.h:130