1// Copyright 2021-2023 Christian Mazakas.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
5#include "../helpers/unordered.hpp"
6
7#include "../helpers/test.hpp"
8
9struct key
10{
11 int x_;
12 static int count_;
13
14 key(int x) : x_(x) { ++count_; }
15 key(key const& k) : x_(k.x_) { ++count_; }
16};
17
18int key::count_;
19
20std::ostream& operator<<(std::ostream& os, key const& k)
21{
22 os << "key { x_: " << k.x_ << " }";
23 return os;
24}
25
26bool operator==(key const& k, int const x) { return k.x_ == x; }
27bool operator==(int const x, key const& k) { return k.x_ == x; }
28
29struct transparent_hasher
30{
31 typedef void is_transparent;
32
33 std::size_t operator()(key const& k) const
34 {
35 return boost::hash<int>()(k.x_);
36 }
37
38 std::size_t operator()(int const k) const { return boost::hash<int>()(k); }
39};
40
41struct transparent_key_equal
42{
43 typedef void is_transparent;
44
45 bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; }
46 bool operator()(int const x, key const& k1) const { return k1 == x; }
47 bool operator()(key const& k1, int const x) const { return k1 == x; }
48};
49
50struct hasher
51{
52 std::size_t operator()(key const& k) const
53 {
54 return boost::hash<int>()(k.x_);
55 }
56};
57
58struct key_equal
59{
60 bool operator()(key const& k1, key const& k2) const { return k1.x_ == k2.x_; }
61};
62
63void count_reset() { key::count_ = 0; }
64
65template <class UnorderedMap> void test_map_transparent_contains()
66{
67 count_reset();
68
69 UnorderedMap map;
70 bool contains = map.contains(0);
71 BOOST_TEST(!contains);
72
73 BOOST_TEST_EQ(key::count_, 0);
74
75 map.insert(std::make_pair(x: 0, y: 1337));
76 map.insert(std::make_pair(x: 0, y: 1338));
77 map.insert(std::make_pair(x: 0, y: 1339));
78 map.insert(std::make_pair(x: 1, y: 1340));
79
80 int const expected_key_count = key::count_;
81
82 contains = map.contains(0);
83 BOOST_TEST(contains);
84
85 contains = map.contains(1);
86 BOOST_TEST(contains);
87
88 contains = map.contains(2);
89 BOOST_TEST(!contains);
90
91 BOOST_TEST_EQ(key::count_, expected_key_count);
92}
93
94template <class UnorderedMap> void test_map_non_transparent_contains()
95{
96 count_reset();
97
98 UnorderedMap map;
99 bool contains = map.contains(0);
100 BOOST_TEST(!contains);
101 BOOST_TEST_EQ(key::count_, 1);
102
103 map.insert(std::make_pair(x: 0, y: 1337));
104 map.insert(std::make_pair(x: 0, y: 1338));
105 map.insert(std::make_pair(x: 0, y: 1339));
106 map.insert(std::make_pair(x: 1, y: 1340));
107
108 int key_count = key::count_;
109
110 contains = map.contains(0);
111 ++key_count;
112 BOOST_TEST(contains);
113
114 contains = map.contains(1);
115 ++key_count;
116 BOOST_TEST(contains);
117
118 contains = map.contains(2);
119 ++key_count;
120 BOOST_TEST(!contains);
121
122 BOOST_TEST_EQ(key::count_, key_count);
123}
124
125void test_map()
126{
127#ifdef BOOST_UNORDERED_FOA_TESTS
128 typedef boost::unordered_flat_map<key, int, transparent_hasher,
129 transparent_key_equal>
130 transparent_map;
131
132 typedef boost::unordered_flat_map<key, int, transparent_hasher, key_equal>
133 non_transparent_map1;
134
135 typedef boost::unordered_flat_map<key, int, hasher, transparent_key_equal>
136 non_transparent_map2;
137
138 typedef boost::unordered_flat_map<key, int, hasher, key_equal>
139 non_transparent_map3;
140
141 typedef boost::unordered_node_map<key, int, transparent_hasher,
142 transparent_key_equal>
143 transparent_node_map;
144
145 typedef boost::unordered_node_map<key, int, transparent_hasher, key_equal>
146 non_transparent_node_map1;
147
148 typedef boost::unordered_node_map<key, int, hasher, transparent_key_equal>
149 non_transparent_node_map2;
150
151 typedef boost::unordered_node_map<key, int, hasher, key_equal>
152 non_transparent_node_map3;
153
154 test_map_transparent_contains<transparent_node_map>();
155 test_map_non_transparent_contains<non_transparent_node_map1>();
156 test_map_non_transparent_contains<non_transparent_node_map2>();
157 test_map_non_transparent_contains<non_transparent_node_map3>();
158#else
159 typedef boost::unordered_map<key, int, transparent_hasher,
160 transparent_key_equal>
161 transparent_map;
162
163 typedef boost::unordered_map<key, int, transparent_hasher, key_equal>
164 non_transparent_map1;
165
166 typedef boost::unordered_map<key, int, hasher, transparent_key_equal>
167 non_transparent_map2;
168
169 typedef boost::unordered_map<key, int, hasher, key_equal>
170 non_transparent_map3;
171#endif
172
173 test_map_transparent_contains<transparent_map>();
174 test_map_non_transparent_contains<non_transparent_map1>();
175 test_map_non_transparent_contains<non_transparent_map2>();
176 test_map_non_transparent_contains<non_transparent_map3>();
177}
178
179#ifndef BOOST_UNORDERED_FOA_TESTS
180void test_multimap()
181{
182 typedef boost::unordered_multimap<key, int, transparent_hasher,
183 transparent_key_equal>
184 transparent_multimap;
185
186 typedef boost::unordered_multimap<key, int, transparent_hasher, key_equal>
187 non_transparent_multimap1;
188
189 typedef boost::unordered_multimap<key, int, hasher, transparent_key_equal>
190 non_transparent_multimap2;
191
192 typedef boost::unordered_multimap<key, int, hasher, key_equal>
193 non_transparent_multimap3;
194
195 test_map_transparent_contains<transparent_multimap>();
196 test_map_non_transparent_contains<non_transparent_multimap1>();
197 test_map_non_transparent_contains<non_transparent_multimap2>();
198 test_map_non_transparent_contains<non_transparent_multimap3>();
199}
200#endif
201
202template <class UnorderedSet> void test_set_transparent_contains()
203{
204 count_reset();
205
206 UnorderedSet set;
207 bool contains = set.contains(0);
208 BOOST_TEST(!contains);
209
210 BOOST_TEST_EQ(key::count_, 0);
211
212 set.insert(0);
213 set.insert(0);
214 set.insert(0);
215 set.insert(1);
216
217 int const expected_key_count = key::count_;
218
219 contains = set.contains(0);
220 BOOST_TEST(contains);
221
222 contains = set.contains(1);
223 BOOST_TEST(contains);
224
225 contains = set.contains(2);
226 BOOST_TEST(!contains);
227
228 BOOST_TEST_EQ(key::count_, expected_key_count);
229}
230
231template <class UnorderedSet> void test_set_non_transparent_contains()
232{
233 count_reset();
234
235 UnorderedSet set;
236 bool contains = set.contains(0);
237 BOOST_TEST(!contains);
238 BOOST_TEST_EQ(key::count_, 1);
239
240 set.insert(0);
241 set.insert(0);
242 set.insert(0);
243 set.insert(1);
244
245 int key_count = key::count_;
246
247 contains = set.contains(0);
248 ++key_count;
249 BOOST_TEST(contains);
250
251 contains = set.contains(1);
252 ++key_count;
253 BOOST_TEST(contains);
254
255 contains = set.contains(2);
256 ++key_count;
257 BOOST_TEST(!contains);
258
259 BOOST_TEST_EQ(key::count_, key_count);
260}
261
262void test_set()
263{
264#ifdef BOOST_UNORDERED_FOA_TESTS
265 typedef boost::unordered_flat_set<key, transparent_hasher,
266 transparent_key_equal>
267 transparent_set;
268
269 typedef boost::unordered_flat_set<key, transparent_hasher, key_equal>
270 non_transparent_set1;
271 typedef boost::unordered_flat_set<key, hasher, transparent_key_equal>
272 non_transparent_set2;
273 typedef boost::unordered_flat_set<key, hasher, key_equal>
274 non_transparent_set3;
275
276 typedef boost::unordered_node_set<key, transparent_hasher,
277 transparent_key_equal>
278 transparent_node_set;
279
280 typedef boost::unordered_node_set<key, transparent_hasher, key_equal>
281 non_transparent_node_set1;
282 typedef boost::unordered_node_set<key, hasher, transparent_key_equal>
283 non_transparent_node_set2;
284 typedef boost::unordered_node_set<key, hasher, key_equal>
285 non_transparent_node_set3;
286
287 test_set_transparent_contains<transparent_node_set>();
288 test_set_non_transparent_contains<non_transparent_node_set1>();
289 test_set_non_transparent_contains<non_transparent_node_set2>();
290 test_set_non_transparent_contains<non_transparent_node_set3>();
291#else
292 typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
293 transparent_set;
294
295 typedef boost::unordered_set<key, transparent_hasher, key_equal>
296 non_transparent_set1;
297 typedef boost::unordered_set<key, hasher, transparent_key_equal>
298 non_transparent_set2;
299 typedef boost::unordered_set<key, hasher, key_equal> non_transparent_set3;
300#endif
301
302 test_set_transparent_contains<transparent_set>();
303 test_set_non_transparent_contains<non_transparent_set1>();
304 test_set_non_transparent_contains<non_transparent_set2>();
305 test_set_non_transparent_contains<non_transparent_set3>();
306}
307
308#ifndef BOOST_UNORDERED_FOA_TESTS
309void test_multiset()
310{
311 typedef boost::unordered_multiset<key, transparent_hasher,
312 transparent_key_equal>
313 transparent_multiset;
314
315 typedef boost::unordered_multiset<key, transparent_hasher, key_equal>
316 non_transparent_multiset1;
317 typedef boost::unordered_multiset<key, hasher, transparent_key_equal>
318 non_transparent_multiset2;
319 typedef boost::unordered_multiset<key, hasher, key_equal>
320 non_transparent_multiset3;
321
322 test_set_transparent_contains<transparent_multiset>();
323 test_set_non_transparent_contains<non_transparent_multiset1>();
324 test_set_non_transparent_contains<non_transparent_multiset2>();
325 test_set_non_transparent_contains<non_transparent_multiset3>();
326}
327#endif
328
329UNORDERED_AUTO_TEST (contains_) { // avoid -Wshadow warning with `bool contains`
330 test_map();
331 test_set();
332#ifndef BOOST_UNORDERED_FOA_TESTS
333 test_multimap();
334 test_multiset();
335#endif
336}
337
338RUN_TESTS()
339

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