1
2// Copyright 2008-2009 Daniel James.
3// Copyright 2022-2023 Christian Mazakas.
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#include "../helpers/unordered.hpp"
8
9#include "../helpers/test.hpp"
10#include <boost/preprocessor/seq.hpp>
11#include <list>
12
13// TODO: this test needs to be someday cleaned up to not be so heavily
14// macro-generated
15//
16
17namespace equality_tests {
18 struct mod_compare
19 {
20 bool alt_hash_;
21
22 explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
23
24 bool operator()(int x, int y) const { return x % 1000 == y % 1000; }
25
26 std::size_t operator()(int x) const
27 {
28 return alt_hash_ ? static_cast<std::size_t>(x % 250)
29 : static_cast<std::size_t>((x + 5) % 250);
30 }
31 };
32
33#ifdef BOOST_UNORDERED_FOA_TESTS
34 using boost_unordered_set =
35 boost::unordered_flat_set<int, mod_compare, mod_compare>;
36
37 using boost_unordered_map =
38 boost::unordered_flat_map<int, int, mod_compare, mod_compare>;
39
40 using boost_unordered_node_set =
41 boost::unordered_node_set<int, mod_compare, mod_compare>;
42
43 using boost_unordered_node_map =
44 boost::unordered_node_map<int, int, mod_compare, mod_compare>;
45
46#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
47 { \
48 }
49
50#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
51 { \
52 }
53#else
54 typedef boost::unordered_set<int, mod_compare, mod_compare>
55 boost_unordered_set;
56
57 typedef boost::unordered_map<int, int, mod_compare, mod_compare>
58 boost_unordered_map;
59
60#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
61 { \
62 boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
63 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
64 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
65 BOOST_TEST(set1 op set2); \
66 }
67
68#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
69 { \
70 boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
71 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
72 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
73 BOOST_TEST(map1 op map2); \
74 }
75#endif
76
77#ifdef BOOST_UNORDERED_FOA_TESTS
78#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
79 { \
80 boost_unordered_set set1, set2; \
81 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
82 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
83 BOOST_TEST(set1 op set2); \
84 } \
85 { \
86 boost_unordered_node_set set1, set2; \
87 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
88 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
89 BOOST_TEST(set1 op set2); \
90 }
91#else
92#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
93 { \
94 boost_unordered_set set1, set2; \
95 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
96 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
97 BOOST_TEST(set1 op set2); \
98 }
99#endif
100
101#ifdef BOOST_UNORDERED_FOA_TESTS
102#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
103 { \
104 boost_unordered_map map1, map2; \
105 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
106 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
107 BOOST_TEST(map1 op map2); \
108 } \
109 \
110 { \
111 boost_unordered_node_map map1, map2; \
112 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
113 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
114 BOOST_TEST(map1 op map2); \
115 }
116#else
117#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
118 { \
119 boost_unordered_map map1, map2; \
120 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
121 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
122 BOOST_TEST(map1 op map2); \
123 }
124#endif
125
126#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
127#define UNORDERED_MAP_INSERT(r, map, item) \
128 map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
129
130 UNORDERED_AUTO_TEST (equality_size_tests) {
131#ifdef BOOST_UNORDERED_FOA_TESTS
132 {
133 boost::unordered_flat_set<int> x1, x2;
134 BOOST_TEST(x1 == x2);
135 BOOST_TEST(!(x1 != x2));
136
137 x1.insert(1);
138 BOOST_TEST(x1 != x2);
139 BOOST_TEST(!(x1 == x2));
140 BOOST_TEST(x2 != x1);
141 BOOST_TEST(!(x2 == x1));
142
143 x2.insert(1);
144 BOOST_TEST(x1 == x2);
145 BOOST_TEST(!(x1 != x2));
146
147 x2.insert(2);
148 BOOST_TEST(x1 != x2);
149 BOOST_TEST(!(x1 == x2));
150 BOOST_TEST(x2 != x1);
151 BOOST_TEST(!(x2 == x1));
152 }
153
154 {
155 boost::unordered_node_set<int> x1, x2;
156 BOOST_TEST(x1 == x2);
157 BOOST_TEST(!(x1 != x2));
158
159 x1.insert(1);
160 BOOST_TEST(x1 != x2);
161 BOOST_TEST(!(x1 == x2));
162 BOOST_TEST(x2 != x1);
163 BOOST_TEST(!(x2 == x1));
164
165 x2.insert(1);
166 BOOST_TEST(x1 == x2);
167 BOOST_TEST(!(x1 != x2));
168
169 x2.insert(2);
170 BOOST_TEST(x1 != x2);
171 BOOST_TEST(!(x1 == x2));
172 BOOST_TEST(x2 != x1);
173 BOOST_TEST(!(x2 == x1));
174 }
175#else
176 boost::unordered_set<int> x1, x2;
177 BOOST_TEST(x1 == x2);
178 BOOST_TEST(!(x1 != x2));
179
180 x1.insert(x: 1);
181 BOOST_TEST(x1 != x2);
182 BOOST_TEST(!(x1 == x2));
183 BOOST_TEST(x2 != x1);
184 BOOST_TEST(!(x2 == x1));
185
186 x2.insert(x: 1);
187 BOOST_TEST(x1 == x2);
188 BOOST_TEST(!(x1 != x2));
189
190 x2.insert(x: 2);
191 BOOST_TEST(x1 != x2);
192 BOOST_TEST(!(x1 == x2));
193 BOOST_TEST(x2 != x1);
194 BOOST_TEST(!(x2 == x1));
195#endif
196 }
197
198 UNORDERED_AUTO_TEST (equality_key_value_tests) {
199 UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
200 UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
201 UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
202 }
203
204 UNORDERED_AUTO_TEST (equality_collision_test) {
205 UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (501))
206 UNORDERED_EQUALITY_MULTISET_TEST((1)(251), !=, (1)(501))
207 UNORDERED_EQUALITY_MULTIMAP_TEST(((251)(1))((1)(1)), !=, ((501)(1))((1)(1)))
208 UNORDERED_EQUALITY_MULTISET_TEST((1)(501), ==, (1)(501))
209 UNORDERED_EQUALITY_SET_TEST((1)(501), ==, (501)(1))
210 }
211
212 UNORDERED_AUTO_TEST (equality_group_size_test) {
213 UNORDERED_EQUALITY_MULTISET_TEST((10)(20)(20), !=, (10)(10)(20))
214 UNORDERED_EQUALITY_MULTIMAP_TEST(
215 ((10)(1))((20)(1))((20)(1)), !=, ((10)(1))((20)(1))((10)(1)))
216 UNORDERED_EQUALITY_MULTIMAP_TEST(
217 ((20)(1))((10)(1))((10)(1)), ==, ((10)(1))((20)(1))((10)(1)))
218 }
219
220 UNORDERED_AUTO_TEST (equality_map_value_test) {
221 UNORDERED_EQUALITY_MAP_TEST(((1)(1)), !=, ((1)(2)))
222 UNORDERED_EQUALITY_MAP_TEST(((1)(1)), ==, ((1)(1)))
223 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1)), !=, ((1)(2)))
224 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
225 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), ==, ((1)(1))((1)(2)))
226 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), !=, ((1)(1))((1)(3)))
227 }
228
229 UNORDERED_AUTO_TEST (equality_predicate_test) {
230 UNORDERED_EQUALITY_SET_TEST((1), !=, (1001))
231 UNORDERED_EQUALITY_MAP_TEST(((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
232 }
233
234 UNORDERED_AUTO_TEST (equality_multiple_group_test) {
235 UNORDERED_EQUALITY_MULTISET_TEST(
236 (1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==,
237 (3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1))
238 }
239
240 // Test that equality still works when the two containers have
241 // different hash functions but the same equality predicate.
242
243 UNORDERED_AUTO_TEST (equality_different_hash_test) {
244#ifdef BOOST_UNORDERED_FOA_TESTS
245 {
246 typedef boost_unordered_set set;
247 set set1(0, mod_compare(false), mod_compare(false));
248 set set2(0, mod_compare(true), mod_compare(true));
249 BOOST_TEST(set1 == set2);
250 set1.insert(1);
251 set2.insert(2);
252 BOOST_TEST(set1 != set2);
253 set1.insert(2);
254 set2.insert(1);
255 BOOST_TEST(set1 == set2);
256 set1.insert(10);
257 set2.insert(20);
258 BOOST_TEST(set1 != set2);
259 set1.insert(20);
260 set2.insert(10);
261 BOOST_TEST(set1 == set2);
262 }
263
264 {
265 typedef boost_unordered_node_set set;
266 set set1(0, mod_compare(false), mod_compare(false));
267 set set2(0, mod_compare(true), mod_compare(true));
268 BOOST_TEST(set1 == set2);
269 set1.insert(1);
270 set2.insert(2);
271 BOOST_TEST(set1 != set2);
272 set1.insert(2);
273 set2.insert(1);
274 BOOST_TEST(set1 == set2);
275 set1.insert(10);
276 set2.insert(20);
277 BOOST_TEST(set1 != set2);
278 set1.insert(20);
279 set2.insert(10);
280 BOOST_TEST(set1 == set2);
281 }
282#else
283 typedef boost_unordered_set set;
284 set set1(0, mod_compare(false), mod_compare(false));
285 set set2(0, mod_compare(true), mod_compare(true));
286 BOOST_TEST(set1 == set2);
287 set1.insert(x: 1);
288 set2.insert(x: 2);
289 BOOST_TEST(set1 != set2);
290 set1.insert(x: 2);
291 set2.insert(x: 1);
292 BOOST_TEST(set1 == set2);
293 set1.insert(x: 10);
294 set2.insert(x: 20);
295 BOOST_TEST(set1 != set2);
296 set1.insert(x: 20);
297 set2.insert(x: 10);
298 BOOST_TEST(set1 == set2);
299#endif
300 }
301} // namespace equality_tests
302
303RUN_TESTS()
304

source code of boost/libs/unordered/test/unordered/equality_tests.cpp