1
2// Copyright 2006-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// This test creates the containers with members that meet their minimum
8// requirements. Makes sure everything compiles and is defined correctly.
9
10#include "../helpers/unordered.hpp"
11
12#include "../helpers/test.hpp"
13#include "../objects/minimal.hpp"
14#include "./compile_tests.hpp"
15
16// Explicit instantiation to catch compile-time errors
17
18#ifdef BOOST_UNORDERED_FOA_TESTS
19
20// emulates what was already done for previous tests but without leaking to
21// the detail namespace
22//
23template <typename T, typename H, typename P, typename A>
24class instantiate_flat_set
25{
26 typedef boost::unordered_flat_set<T, H, P, A> container;
27 container x;
28};
29
30template class instantiate_flat_set<int, boost::hash<int>, std::equal_to<int>,
31 test::minimal::allocator<int> >;
32
33template class instantiate_flat_set<test::minimal::assignable const,
34 test::minimal::hash<test::minimal::assignable>,
35 test::minimal::equal_to<test::minimal::assignable>,
36 test::minimal::allocator<int> >;
37
38template <typename T, typename H, typename P, typename A>
39class instantiate_node_set
40{
41 typedef boost::unordered_node_set<T, H, P, A> container;
42 container x;
43};
44
45template class instantiate_node_set<int, boost::hash<int>, std::equal_to<int>,
46 test::minimal::allocator<int> >;
47
48template class instantiate_node_set<test::minimal::assignable const,
49 test::minimal::hash<test::minimal::assignable>,
50 test::minimal::equal_to<test::minimal::assignable>,
51 test::minimal::allocator<int> >;
52
53#else
54
55#define INSTANTIATE(type) \
56 template class boost::unordered::detail::instantiate_##type
57
58INSTANTIATE(set)<int, boost::hash<int>, std::equal_to<int>,
59 test::minimal::allocator<int> >;
60INSTANTIATE(multiset)<int const, boost::hash<int>, std::equal_to<int>,
61 test::minimal::allocator<int> >;
62
63INSTANTIATE(set)<test::minimal::assignable const,
64 test::minimal::hash<test::minimal::assignable>,
65 test::minimal::equal_to<test::minimal::assignable>,
66 test::minimal::allocator<int> >;
67INSTANTIATE(multiset)<test::minimal::assignable,
68 test::minimal::hash<test::minimal::assignable>,
69 test::minimal::equal_to<test::minimal::assignable>,
70 test::minimal::allocator<int> >;
71
72#endif
73
74template <class X> static void type_traits_impl()
75{
76 BOOST_STATIC_ASSERT(boost::is_same<int const&,
77 typename std::iterator_traits<typename X::iterator>::reference>::value);
78}
79
80UNORDERED_AUTO_TEST (type_traits) {
81#ifdef BOOST_UNORDERED_FOA_TESTS
82 type_traits_impl<boost::unordered_flat_set<int> >();
83 type_traits_impl<boost::unordered_node_set<int> >();
84#else
85 type_traits_impl<boost::unordered_set<int> >();
86 type_traits_impl<boost::unordered_multiset<int> >();
87#endif
88}
89
90template <template <class T, class H = boost::hash<T>,
91 class P = std::equal_to<T>, class A = std::allocator<T> >
92 class Set>
93static void test0_impl()
94{
95 test::minimal::constructor_param x;
96
97 test::minimal::assignable assignable(x);
98
99 Set<int> int_set;
100
101 Set<int, boost::hash<int>, std::equal_to<int>,
102 test::minimal::cxx11_allocator<int> >
103 int_set2;
104
105 Set<test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
106 test::minimal::equal_to<test::minimal::assignable>,
107 test::minimal::allocator<test::minimal::assignable> >
108 set;
109
110 container_test(int_set, 0);
111 container_test(int_set2, 0);
112 container_test(set, assignable);
113}
114
115UNORDERED_AUTO_TEST (test0) {
116#ifdef BOOST_UNORDERED_FOA_TESTS
117 test0_impl<boost::unordered_flat_set>();
118 test0_impl<boost::unordered_node_set>();
119#else
120 test0_impl<boost::unordered_set>();
121 test0_impl<boost::unordered_multiset>();
122#endif
123}
124
125template <template <class T, class H = boost::hash<T>,
126 class P = std::equal_to<T>, class A = std::allocator<T> >
127 class Set>
128static void equality_tests_impl()
129{
130 typedef test::minimal::copy_constructible_equality_comparable value_type;
131
132 Set<int> int_set;
133
134 Set<int, boost::hash<int>, std::equal_to<int>,
135 test::minimal::cxx11_allocator<int> >
136 int_set2;
137
138 Set<test::minimal::copy_constructible_equality_comparable,
139 test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
140 test::minimal::equal_to<
141 test::minimal::copy_constructible_equality_comparable>,
142 test::minimal::allocator<value_type> >
143 set;
144
145 equality_test(int_set);
146 equality_test(int_set2);
147 equality_test(set);
148}
149
150UNORDERED_AUTO_TEST (equality_tests) {
151#ifdef BOOST_UNORDERED_FOA_TESTS
152 equality_tests_impl<boost::unordered_flat_set>();
153 equality_tests_impl<boost::unordered_node_set>();
154#else
155 equality_tests_impl<boost::unordered_set>();
156 equality_tests_impl<boost::unordered_multiset>();
157#endif
158}
159
160template <template <class T, class H = boost::hash<T>,
161 class P = std::equal_to<T>, class A = std::allocator<T> >
162 class Set>
163static void test1_unique_impl()
164{
165
166 boost::hash<int> hash;
167 std::equal_to<int> equal_to;
168 int value = 0;
169 Set<int> set;
170
171 Set<int, boost::hash<int>, std::equal_to<int>,
172 test::minimal::cxx11_allocator<int> >
173 set2;
174
175 unordered_unique_test(set, value);
176 unordered_set_test(set, value);
177 unordered_copyable_test(set, value, value, hash, equal_to);
178
179 unordered_unique_test(set2, value);
180 unordered_set_test(set2, value);
181 unordered_copyable_test(set2, value, value, hash, equal_to);
182}
183
184#ifndef BOOST_UNORDERED_FOA_TESTS
185template <template <class T, class H = boost::hash<T>,
186 class P = std::equal_to<T>, class A = std::allocator<T> >
187 class Set>
188static void test1_equivalent_impl()
189{
190
191 boost::hash<int> hash;
192 std::equal_to<int> equal_to;
193 int value = 0;
194 Set<int> set;
195
196 Set<int, boost::hash<int>, std::equal_to<int>,
197 test::minimal::cxx11_allocator<int> >
198 set2;
199
200 unordered_equivalent_test(set, value);
201 unordered_set_test(set, value);
202 unordered_copyable_test(set, value, value, hash, equal_to);
203
204 unordered_equivalent_test(set2, value);
205 unordered_set_test(set2, value);
206 unordered_copyable_test(set2, value, value, hash, equal_to);
207}
208#endif
209
210UNORDERED_AUTO_TEST (test1) {
211#ifdef BOOST_UNORDERED_FOA_TESTS
212 test1_unique_impl<boost::unordered_flat_set>();
213 test1_unique_impl<boost::unordered_node_set>();
214#else
215 test1_unique_impl<boost::unordered_set>();
216 test1_equivalent_impl<boost::unordered_multiset>();
217#endif
218}
219
220template <template <class T, class H = boost::hash<T>,
221 class P = std::equal_to<T>, class A = std::allocator<T> >
222 class Set>
223static void test2_unique_impl()
224{
225 test::minimal::constructor_param x;
226
227 test::minimal::assignable assignable(x);
228 test::minimal::copy_constructible copy_constructible(x);
229 test::minimal::hash<test::minimal::assignable> hash(x);
230 test::minimal::equal_to<test::minimal::assignable> equal_to(x);
231
232 Set<test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
233 test::minimal::equal_to<test::minimal::assignable>,
234 test::minimal::allocator<test::minimal::assignable> >
235 set;
236
237 unordered_unique_test(set, assignable);
238 unordered_set_test(set, assignable);
239 unordered_copyable_test(set, assignable, assignable, hash, equal_to);
240 unordered_set_member_test(set, assignable);
241}
242
243#ifndef BOOST_UNORDERED_FOA_TESTS
244template <template <class T, class H = boost::hash<T>,
245 class P = std::equal_to<T>, class A = std::allocator<T> >
246 class Set>
247static void test2_equivalent_impl()
248{
249 test::minimal::constructor_param x;
250
251 test::minimal::assignable assignable(x);
252 test::minimal::copy_constructible copy_constructible(x);
253 test::minimal::hash<test::minimal::assignable> hash(x);
254 test::minimal::equal_to<test::minimal::assignable> equal_to(x);
255
256 Set<test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
257 test::minimal::equal_to<test::minimal::assignable>,
258 test::minimal::allocator<test::minimal::assignable> >
259 set;
260
261 unordered_equivalent_test(set, assignable);
262 unordered_set_test(set, assignable);
263 unordered_copyable_test(set, assignable, assignable, hash, equal_to);
264 unordered_set_member_test(set, assignable);
265}
266#endif
267
268UNORDERED_AUTO_TEST (test2) {
269#ifdef BOOST_UNORDERED_FOA_TESTS
270 test2_unique_impl<boost::unordered_flat_set>();
271 test2_unique_impl<boost::unordered_node_set>();
272#else
273 test2_unique_impl<boost::unordered_set>();
274 test2_equivalent_impl<boost::unordered_multiset>();
275#endif
276}
277
278template <template <class T, class H = boost::hash<T>,
279 class P = std::equal_to<T>, class A = std::allocator<T> >
280 class Set>
281static void movable1_tests_impl()
282{
283 test::minimal::constructor_param x;
284
285 test::minimal::movable1 movable1(x);
286 test::minimal::hash<test::minimal::movable1> hash(x);
287 test::minimal::equal_to<test::minimal::movable1> equal_to(x);
288
289 Set<test::minimal::movable1, test::minimal::hash<test::minimal::movable1>,
290 test::minimal::equal_to<test::minimal::movable1>,
291 test::minimal::allocator<test::minimal::movable1> >
292 set;
293
294 // TODO: find out why Daniel had this commented out and if we need it and the
295 // corresponding equivalent impl
296 //
297 // unordered_unique_test(set, movable1);
298 unordered_set_test(set, movable1);
299 unordered_movable_test(set, movable1, movable1, hash, equal_to);
300}
301
302UNORDERED_AUTO_TEST (movable1_tests) {
303#ifdef BOOST_UNORDERED_FOA_TESTS
304 movable1_tests_impl<boost::unordered_flat_set>();
305 movable1_tests_impl<boost::unordered_node_set>();
306#else
307 movable1_tests_impl<boost::unordered_set>();
308 movable1_tests_impl<boost::unordered_multiset>();
309#endif
310}
311
312template <template <class T, class H = boost::hash<T>,
313 class P = std::equal_to<T>, class A = std::allocator<T> >
314 class Set>
315static void movable2_tests_impl()
316{
317 test::minimal::constructor_param x;
318
319 test::minimal::movable2 movable2(x);
320 test::minimal::hash<test::minimal::movable2> hash(x);
321 test::minimal::equal_to<test::minimal::movable2> equal_to(x);
322
323 Set<test::minimal::movable2, test::minimal::hash<test::minimal::movable2>,
324 test::minimal::equal_to<test::minimal::movable2>,
325 test::minimal::allocator<test::minimal::movable2> >
326 set;
327
328 // unordered_unique_test(set, movable2);
329 unordered_set_test(set, movable2);
330 unordered_movable_test(set, movable2, movable2, hash, equal_to);
331}
332
333UNORDERED_AUTO_TEST (movable2_tests) {
334
335#ifdef BOOST_UNORDERED_FOA_TESTS
336 movable2_tests_impl<boost::unordered_flat_set>();
337 movable2_tests_impl<boost::unordered_node_set>();
338#else
339 movable2_tests_impl<boost::unordered_set>();
340 movable2_tests_impl<boost::unordered_multiset>();
341#endif
342}
343
344template <template <class T, class H = boost::hash<T>,
345 class P = std::equal_to<T>, class A = std::allocator<T> >
346 class Set>
347static void destructible_tests_impl()
348{
349 test::minimal::constructor_param x;
350
351 test::minimal::destructible destructible(x);
352 test::minimal::hash<test::minimal::destructible> hash(x);
353 test::minimal::equal_to<test::minimal::destructible> equal_to(x);
354
355 Set<test::minimal::destructible,
356 test::minimal::hash<test::minimal::destructible>,
357 test::minimal::equal_to<test::minimal::destructible> >
358 set;
359
360 unordered_destructible_test(set);
361}
362
363UNORDERED_AUTO_TEST (destructible_tests) {
364#ifdef BOOST_UNORDERED_FOA_TESTS
365 destructible_tests_impl<boost::unordered_flat_set>();
366 destructible_tests_impl<boost::unordered_node_set>();
367#else
368 destructible_tests_impl<boost::unordered_set>();
369 destructible_tests_impl<boost::unordered_multiset>();
370#endif
371}
372
373// Test for ambiguity when using key convertible from iterator
374// See LWG2059
375
376struct lwg2059_key
377{
378 int value;
379
380 template <typename T> lwg2059_key(T v) : value(v) {}
381};
382
383std::size_t hash_value(lwg2059_key x)
384{
385 return static_cast<std::size_t>(x.value);
386}
387
388bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
389
390UNORDERED_AUTO_TEST (lwg2059) {
391#ifdef BOOST_UNORDERED_FOA_TESTS
392 {
393 boost::unordered_flat_set<lwg2059_key> x;
394 x.emplace(lwg2059_key(10));
395 x.erase(x.begin());
396 }
397
398 {
399 boost::unordered_node_set<lwg2059_key> x;
400 x.emplace(lwg2059_key(10));
401 x.erase(x.begin());
402 }
403#else
404 {
405 boost::unordered_set<lwg2059_key> x;
406 x.emplace(args: lwg2059_key(10));
407 x.erase(position: x.begin());
408 }
409
410 {
411 boost::unordered_multiset<lwg2059_key> x;
412 x.emplace(args: lwg2059_key(10));
413 x.erase(position: x.begin());
414 }
415#endif
416}
417
418RUN_TESTS()
419

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