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/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(kblib::is_linear_container_v<std::string>
22 and kblib::is_contiguous_v<std::string>
23 and kblib::is_trivially_hashable_v<std::string::value_type>
24 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(std::is_default_constructible_v<kblib::FNV_hash<no_padding>>
35 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<T>>
42template <typename T>
43static constexpr bool is_enabled_hash
44 = std::is_nothrow_default_constructible_v<kblib::FNV_hash<T>>
45 and 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::array<bool, 16>>, kblib::FNV_hash<>,
63 std::equal_to<>>
64 test_map;
66 std::vector<std::array<bool, 16>>>;
67 static_assert(std::is_same<decltype(test_map), map_t>::value, "");
72 test_hash1c;
74 std::vector<std::array<bool, 16>>>>
75 test_hash2;
77 KBLIB_UNUSED auto call = &decltype(test_hash1)::operator();
78 // std::hash<
79 // std::unordered_map<std::wstring,
80 // std::vector<std::array<bool, 16>>, std::hash<std::wstring>>> std_hash;
81 using namespace kblib::literals;
83 static_assert(3452452_fnv64 == h_i(3452452ull),
84 "hash literal and FNH_hash don't agree");
85
86 CHECK(kblib::FNV_hash<int>{}(1000) == 0x2fa9eaf82259d71cu);
87 (void)kblib::FNV_hash<std::vector<int>>{}({});
88 (void)kblib::FNV_hash<std::vector<empty_t>>{}({});
89 // fails because of padding:
90 static_assert(is_disabled_hash<std::vector<has_padding>>);
91 // fails because of unorderedness:
92 static_assert(is_disabled_hash<std::unordered_map<int, int>>);
93
95 CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i));
96#if KBLIB_USE_CXX17
98 (void)test_opt_hash(std::nullopt);
99 (void)test_opt_hash(42);
100 CHECK(test_opt_hash(42) == kblib::FNV_hash<int>{}(42));
101
102 std::variant<int, int, std::string> var(std::in_place_index<1>, 42);
103 kblib::FNV_hash<decltype(var)> test_var_hash;
104 CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash<int>{}(42));
105 CHECK_FALSE(test_var_hash(var)
106 == test_var_hash(decltype(var){std::in_place_index<0>, 42}));
107#endif
108}
109TEST_CASE("FNV_hash (32 bit)") {
112 (void)kblib::FNV_hash<std::vector<char>, std::uint32_t>{}({});
113 (void)kblib::FNV_hash<std::vector<int>, std::uint32_t>{}({});
114 (void)kblib::FNV_hash<std::deque<char>, std::uint32_t>{}({});
115 (void)kblib::FNV_hash<std::tuple<>, std::uint32_t>{}({});
116 (void)kblib::FNV_hash<std::tuple<int*>, std::uint32_t>{}({});
117 (void)kblib::FNV_hash<std::tuple<std::wstring, int*>, std::uint32_t>{}({});
119 (void)kblib::FNV_hash<std::vector<int>::iterator, std::uint32_t>{}({});
120 (void)kblib::FNV_hash<std::deque<char>::iterator, std::uint32_t>{}({});
121 (void)kblib::FNV_hash<std::set<int>::iterator, std::uint32_t>{}({});
122
123 KBLIB_UNUSED kblib::FNV_hash<std::map<int, int>, std::uint32_t> test_hash1;
125 test_hash1a;
127 test_hash1b;
129 std::uint32_t>
130 test_hash1c;
133 std::vector<std::array<bool, 16>>>,
134 std::uint32_t>
135 test_hash2;
138 test_hash3;
139 KBLIB_UNUSED auto call = &decltype(test_hash1)::operator();
140 // std::hash<
141 // std::unordered_map<std::wstring,
142 // std::vector<std::array<bool, 16>>, std::hash<std::wstring>>> std_hash;
143 using namespace kblib::literals;
145 static_assert(3452452_fnv32 == h_i(3452452u),
146 "hash literal and FNH_hash don't agree");
147
148 CHECK(kblib::FNV_hash<int, std::uint32_t>{}(1000) == 0xf49c691cu);
149 (void)kblib::FNV_hash<std::vector<int>, std::uint32_t>{}({});
150 (void)kblib::FNV_hash<std::vector<empty_t>, std::uint32_t>{}({});
151 // fails because of padding:
152 // kblib::FNV_hash<std::vector<has_padding>>{}({});
153 // fails because of unorderedness:
154 // kblib::FNV_hash<std::unordered_map<int, int>>{}({});
155
157 CHECK(test_hash4(nullptr) != test_hash4(&has_padding::i));
158#if KBLIB_USE_CXX17
159 kblib::FNV_hash<std::optional<int>, std::uint32_t> test_opt_hash;
160 (void)test_opt_hash(std::nullopt);
161 (void)test_opt_hash(42);
162 CHECK(test_opt_hash(42) == kblib::FNV_hash<int, std::uint32_t>{}(42));
163
164 std::variant<int, int, std::string> var(std::in_place_index<1>, 42);
165 kblib::FNV_hash<decltype(var)> test_var_hash;
166 CHECK_FALSE(test_var_hash(var) == kblib::FNV_hash<int, std::uint32_t>{}(42));
167 CHECK_FALSE(test_var_hash(var)
168 == test_var_hash(decltype(var){std::in_place_index<0>, 42}));
169#endif
170}
#define CHECK_FALSE(...)
Definition: catch.hpp:17688
#define CHECK(...)
Definition: catch.hpp:17687
TEST_CASE("FNV_hash")
Definition: hash.cpp:47
Provides generic facilities for hashing data, and aliases for standard unordered containers using the...
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:4001
constexpr bool is_invocable_v
Definition: fakestd.h:470
constexpr bool is_invocable_r_v
Definition: fakestd.h:473
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:147