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#include "../helpers/unordered.hpp"
8
9#include "../helpers/metafunctions.hpp"
10#include "../helpers/random_values.hpp"
11#include "../helpers/test.hpp"
12#include "../helpers/tracker.hpp"
13#include "../objects/test.hpp"
14
15namespace rehash_tests {
16
17 test::seed_t initialize_seed(2974);
18
19 static int count_allocations;
20 template <class T> struct monotonic_allocator
21 {
22 typedef T value_type;
23 monotonic_allocator() {}
24 monotonic_allocator(monotonic_allocator const&) {}
25
26 template <class U> monotonic_allocator(monotonic_allocator<U> const&) {}
27
28 friend bool operator==(
29 monotonic_allocator const&, monotonic_allocator const&)
30 {
31 return true;
32 }
33
34 friend bool operator!=(
35 monotonic_allocator const&, monotonic_allocator const&)
36 {
37 return false;
38 }
39
40 T* allocate(std::size_t n)
41 {
42 ++count_allocations;
43 return static_cast<T*>(::operator new(sizeof(T) * n));
44 }
45
46 void deallocate(T* p, std::size_t) { ::operator delete(p); }
47 };
48
49 void reset_counts() { count_allocations = 0; }
50
51 template <class X> bool postcondition(X const& x, typename X::size_type n)
52 {
53 return static_cast<double>(x.bucket_count()) >=
54 static_cast<double>(x.size()) / x.max_load_factor() &&
55 x.bucket_count() >= n;
56 }
57
58 template <class X> void rehash_empty_test1(X*)
59 {
60 X x;
61
62 x.rehash(10000);
63 BOOST_TEST(postcondition(x, 10000));
64
65 x.rehash(0);
66 BOOST_TEST(postcondition(x, 0));
67
68 x.rehash(10000000);
69 BOOST_TEST(postcondition(x, 10000000));
70 }
71
72 template <class X>
73 void rehash_empty_test2(X*, test::random_generator generator)
74 {
75 test::random_values<X> v(1000, generator);
76 test::ordered<X> tracker;
77
78 X x;
79
80 x.rehash(10000);
81 BOOST_TEST(postcondition(x, 10000));
82
83 tracker.insert_range(v.begin(), v.end());
84 x.insert(v.begin(), v.end());
85 tracker.compare(x);
86
87 BOOST_TEST(postcondition(x, 10000));
88
89 x.rehash(10000000);
90 tracker.compare(x);
91 BOOST_TEST(postcondition(x, 10000000));
92 }
93
94 template <class X>
95 void rehash_empty_test3(X*, test::random_generator generator)
96 {
97 test::random_values<X> v(1000, generator);
98 test::ordered<X> tracker;
99
100 X x;
101
102 x.rehash(0);
103 BOOST_TEST(postcondition(x, 0));
104
105 tracker.insert_range(v.begin(), v.end());
106 x.insert(v.begin(), v.end());
107 tracker.compare(x);
108
109 BOOST_TEST(postcondition(x, 0));
110 }
111
112 template <class X> void rehash_empty_tracking(X*, test::random_generator)
113 {
114 // valid for all load factors
115 float const max_load_factors[] = {
116 0.5f, 1.0f, 1e6f, std::numeric_limits<float>::infinity()};
117
118 std::size_t const max_load_factors_len =
119 sizeof(max_load_factors) / sizeof(*max_load_factors);
120
121 for (std::size_t i = 0; i < max_load_factors_len; ++i) {
122 X x;
123 BOOST_TEST_EQ(x.size(), 0u);
124 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
125
126 x.max_load_factor(max_load_factors[i]);
127
128 {
129 BOOST_TEST_EQ(x.bucket_count(), 0u);
130
131 x.rehash(0);
132 BOOST_TEST_EQ(x.bucket_count(), 0u);
133 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
134 }
135
136 {
137 BOOST_TEST_EQ(x.bucket_count(), 0u);
138
139 x.rehash(1000);
140 BOOST_TEST_GE(x.bucket_count(), 1000u);
141 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
142
143 x.rehash(0);
144 BOOST_TEST_EQ(x.bucket_count(), 0u);
145 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
146 }
147
148 {
149 BOOST_TEST_EQ(x.bucket_count(), 0u);
150
151 x.rehash(1000);
152 BOOST_TEST_GE(x.bucket_count(), 1000u);
153 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
154
155 x.rehash(10);
156 BOOST_TEST_GE(x.bucket_count(), 10u);
157 BOOST_TEST_LT(x.bucket_count(), 1000u);
158 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
159 }
160
161 {
162 BOOST_TEST_GT(x.bucket_count(), 0u);
163 BOOST_TEST_LT(x.bucket_count(), 1000u);
164
165 x.rehash(1000);
166 BOOST_TEST_GE(x.bucket_count(), 1000u);
167 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
168
169 x.rehash(0);
170 BOOST_TEST_EQ(x.bucket_count(), 0u);
171 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
172 }
173 }
174
175 for (std::size_t i = 0; i < max_load_factors_len; ++i) {
176 typedef typename X::size_type size_type;
177
178 X x;
179 BOOST_TEST_EQ(x.size(), 0u);
180 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
181
182#ifdef BOOST_UNORDERED_FOA_TESTS
183 float const mlf = boost::unordered::detail::foa::mlf;
184 x.max_load_factor(max_load_factors[i]);
185#else
186 float const mlf = max_load_factors[i];
187 x.max_load_factor(mlf);
188#endif
189
190 {
191 BOOST_TEST_EQ(x.bucket_count(), 0u);
192
193 x.reserve(0);
194 BOOST_TEST_EQ(x.bucket_count(), 0u);
195 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
196 }
197
198 {
199 BOOST_TEST_EQ(x.bucket_count(), 0u);
200
201 x.reserve(1000);
202 BOOST_TEST_GE(
203 x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
204 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
205
206 x.reserve(0);
207 BOOST_TEST_EQ(x.bucket_count(), 0u);
208 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
209 }
210
211 {
212 BOOST_TEST_EQ(x.bucket_count(), 0u);
213
214 x.reserve(1000);
215 BOOST_TEST_GE(
216 x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
217 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
218
219 x.reserve(10);
220 BOOST_TEST_GE(
221 x.bucket_count(), static_cast<size_type>(std::ceil(10 / mlf)));
222 BOOST_TEST_LT(x.bucket_count(), 1000u);
223 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
224 }
225
226 {
227 BOOST_TEST_GT(x.bucket_count(), 0u);
228 BOOST_TEST_LT(x.bucket_count(), 1000u);
229
230 x.reserve(1000);
231 BOOST_TEST_GE(
232 x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
233 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
234
235 x.reserve(0);
236 BOOST_TEST_EQ(x.bucket_count(), 0u);
237 BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
238 }
239 }
240 }
241
242 template <class X>
243 void rehash_nonempty_tracking(X*, test::random_generator generator)
244 {
245 test::random_values<X> const v(1000, generator);
246
247 typedef typename X::size_type size_type;
248
249 float const max_load_factors[] = {0.5f, 1.0f, 1e2f};
250
251 size_type const max_load_factors_len =
252 sizeof(max_load_factors) / sizeof(*max_load_factors);
253
254 for (size_type i = 0; i < max_load_factors_len; ++i) {
255 float const mlf = max_load_factors[i];
256
257 X x(v.begin(), v.end());
258 BOOST_TEST_GT(x.size(), 0u);
259 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
260
261 x.max_load_factor(mlf);
262
263 size_type bucket_count = x.bucket_count();
264
265 {
266 BOOST_TEST_GT(x.bucket_count(), 0u);
267
268 x.rehash(0);
269 BOOST_TEST_GE(x.bucket_count(),
270 static_cast<size_type>(
271 std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
272 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
273
274 bucket_count = x.bucket_count();
275 }
276
277 {
278 BOOST_TEST_GT(bucket_count, 0u);
279
280 x.rehash(2 * x.bucket_count());
281 BOOST_TEST_GT(x.bucket_count(), bucket_count);
282
283 bucket_count = x.bucket_count();
284 }
285
286 {
287 float const old_mlf = x.max_load_factor();
288
289 BOOST_TEST_GT(bucket_count, 0u);
290
291 x.rehash(bucket_count / 4);
292 BOOST_TEST_LT(x.bucket_count(), bucket_count);
293
294 x.max_load_factor(std::numeric_limits<float>::infinity());
295 x.rehash(0);
296 BOOST_TEST_GT(x.bucket_count(), 0u);
297
298 x.max_load_factor(old_mlf);
299 }
300
301 {
302 std::size_t const max_load =
303 static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
304 static_cast<double>(x.bucket_count()));
305
306 while (x.size() < max_load) {
307 test::random_values<X> const t(max_load, generator);
308 typename test::random_values<X>::const_iterator pos = t.begin();
309 typename test::random_values<X>::const_iterator end = t.end();
310 for (; pos != end; ++pos) {
311 x.insert(*pos);
312 if (x.size() == max_load) {
313 break;
314 }
315 }
316 }
317
318 while (x.size() > max_load) {
319 x.erase(x.begin());
320 }
321
322 BOOST_TEST_EQ(x.size(), max_load);
323
324 bucket_count = x.bucket_count();
325 x.rehash(x.bucket_count());
326 BOOST_TEST_EQ(x.bucket_count(), bucket_count);
327 }
328 }
329
330 for (size_type i = 0; i < max_load_factors_len; ++i) {
331 X x(v.begin(), v.end());
332 BOOST_TEST_GT(x.size(), 0u);
333 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
334
335 float const mlf = max_load_factors[i];
336 x.max_load_factor(mlf);
337
338 size_type bucket_count = x.bucket_count();
339
340 {
341 BOOST_TEST_GT(x.bucket_count(), 0u);
342
343 x.reserve(0);
344 BOOST_TEST_GE(x.bucket_count(),
345 static_cast<size_type>(
346 std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
347 BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
348
349 bucket_count = x.bucket_count();
350 }
351
352 {
353 BOOST_TEST_GT(x.bucket_count(), 0u);
354
355 x.reserve(
356 2 *
357 (static_cast<size_type>(
358 std::floor(static_cast<float>(x.size()) / x.max_load_factor()) +
359 std::floor(static_cast<float>(x.size()) * x.max_load_factor()))));
360
361 BOOST_TEST_GT(x.bucket_count(), bucket_count);
362
363 bucket_count = x.bucket_count();
364 BOOST_TEST_GT(bucket_count, 1u);
365 }
366
367 {
368 float const old_mlf = x.max_load_factor();
369
370 BOOST_TEST_GT(bucket_count, 4u);
371
372 x.reserve(bucket_count / 4);
373 BOOST_TEST_LT(x.bucket_count(), bucket_count);
374
375 x.max_load_factor(std::numeric_limits<float>::infinity());
376 x.reserve(0);
377 BOOST_TEST_GT(x.bucket_count(), 0u);
378
379 x.max_load_factor(old_mlf);
380 }
381
382 {
383 std::size_t const max_load =
384 static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
385 static_cast<double>(x.bucket_count()));
386
387 while (x.size() < max_load) {
388 test::random_values<X> const t(max_load, generator);
389 typename test::random_values<X>::const_iterator pos = t.begin();
390 typename test::random_values<X>::const_iterator end = t.end();
391 for (; pos != end; ++pos) {
392 x.insert(*pos);
393 if (x.size() == max_load) {
394 break;
395 }
396 }
397 }
398
399 while (x.size() > max_load) {
400 x.erase(x.begin());
401 }
402
403 BOOST_TEST_EQ(x.size(), max_load);
404
405 bucket_count = x.bucket_count();
406 x.reserve(x.size());
407 BOOST_TEST_EQ(x.bucket_count(), bucket_count);
408 }
409 }
410 }
411
412 template <class X> void rehash_stability(X*, test::random_generator generator)
413 {
414 reset_counts();
415
416 typedef typename X::size_type size_type;
417
418 size_type bucket_count = 100;
419 X x(bucket_count);
420
421 size_type num_elems = x.bucket_count() - 1;
422
423 test::random_values<X> v(num_elems, generator);
424 test::ordered<X> tracker;
425 tracker.insert_range(v.begin(), v.end());
426
427 typename test::random_values<X>::iterator pos = v.begin();
428 for (size_type i = 0; i < num_elems; ++i) {
429 x.insert(*pos);
430 ++pos;
431 }
432
433 int const old_count = count_allocations;
434 x.rehash(0);
435
436 BOOST_TEST_EQ(count_allocations, old_count);
437 tracker.compare(x);
438 }
439
440 template <class X>
441 void rehash_node_stability(X*, test::random_generator generator)
442 {
443 typedef typename X::value_type value_type;
444 std::set<value_type const*> elements;
445
446 test::random_values<X> v(1000, generator);
447 test::ordered<X> tracker;
448 tracker.insert_range(v.begin(), v.end());
449
450 X x(v.begin(), v.end());
451
452 typedef typename X::iterator iterator;
453 for (iterator pos = x.begin(); pos != x.end(); ++pos) {
454 elements.insert(std::addressof(*pos));
455 }
456
457 x.rehash(2 * x.bucket_count());
458
459 for (iterator pos = x.begin(); pos != x.end(); ++pos) {
460 if (!BOOST_TEST(
461 elements.find(std::addressof(*pos)) != elements.end())) {
462 break;
463 }
464 }
465
466 tracker.compare(x);
467 }
468
469 template <class X> void rehash_test1(X*, test::random_generator generator)
470 {
471 test::random_values<X> v(1000, generator);
472 test::ordered<X> tracker;
473 tracker.insert_range(v.begin(), v.end());
474 X x(v.begin(), v.end());
475
476 x.rehash(0);
477 BOOST_TEST(postcondition(x, 0));
478 tracker.compare(x);
479
480 x.max_load_factor(0.25);
481 x.rehash(0);
482 BOOST_TEST(postcondition(x, 0));
483 tracker.compare(x);
484
485 x.max_load_factor(50.0);
486 x.rehash(0);
487 BOOST_TEST(postcondition(x, 0));
488 tracker.compare(x);
489
490 x.rehash(1000);
491 BOOST_TEST(postcondition(x, 1000));
492 tracker.compare(x);
493 }
494
495 template <class X> void reserve_empty_test1(X*)
496 {
497 X x;
498
499 x.reserve(10000);
500 BOOST_TEST(x.bucket_count() >= 10000);
501
502 x.reserve(0);
503
504 x.reserve(10000000);
505 BOOST_TEST(x.bucket_count() >= 10000000);
506 }
507
508 template <class X> void reserve_empty_test2(X*)
509 {
510 X x;
511 x.max_load_factor(0.25);
512
513#ifdef BOOST_UNORDERED_FOA_TESTS
514 x.reserve(10000);
515 BOOST_TEST(x.bucket_count() >= 10000);
516
517 x.reserve(0);
518
519 x.reserve(10000000);
520 BOOST_TEST(x.bucket_count() >= 10000000);
521#else
522 x.reserve(10000);
523 BOOST_TEST(x.bucket_count() >= 40000);
524
525 x.reserve(0);
526
527 x.reserve(10000000);
528 BOOST_TEST(x.bucket_count() >= 40000000);
529#endif
530 }
531
532 template <class X> void reserve_test1(X*, test::random_generator generator)
533 {
534 for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
535 for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13) {
536 test::random_values<X> v(i, generator);
537
538 test::ordered<X> tracker;
539 tracker.insert_range(v.begin(), v.end());
540
541 X x;
542 x.max_load_factor(
543 random_mlf ? static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f
544 : 1.0f);
545 x.reserve(test::has_unique_keys<X>::value ? i : v.size());
546
547 // Insert an element before the range insert, otherwise there are
548 // no iterators to invalidate in the range insert, and it can
549 // rehash.
550 typename test::random_values<X>::iterator it = v.begin();
551 x.insert(*it);
552 ++it;
553
554 std::size_t bucket_count = x.bucket_count();
555 x.insert(it, v.end());
556 BOOST_TEST(bucket_count == x.bucket_count());
557 tracker.compare(x);
558 }
559 }
560 }
561
562 template <class X> void reserve_test2(X*, test::random_generator generator)
563 {
564 for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
565 for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13) {
566 test::random_values<X> v(i, generator);
567
568 test::ordered<X> tracker;
569 tracker.insert_range(v.begin(), v.end());
570
571 X x;
572 x.max_load_factor(
573 random_mlf ? static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f
574 : 1.0f);
575
576 x.reserve(test::has_unique_keys<X>::value ? i : v.size());
577
578 std::size_t bucket_count = x.bucket_count();
579 for (typename test::random_values<X>::iterator it = v.begin();
580 it != v.end(); ++it) {
581 x.insert(*it);
582 }
583
584 BOOST_TEST(bucket_count == x.bucket_count());
585 tracker.compare(x);
586 }
587 }
588 }
589
590 using test::default_generator;
591 using test::generate_collisions;
592 using test::limited_range;
593
594#ifdef BOOST_UNORDERED_FOA_TESTS
595 boost::unordered_flat_set<int>* int_set_ptr;
596 boost::unordered_flat_map<test::movable, test::movable, test::hash,
597 test::equal_to, test::allocator2<test::movable> >* test_map_ptr;
598
599 boost::unordered_flat_set<test::object, test::hash, test::equal_to,
600 test::allocator1<test::object> >* test_set_tracking;
601 boost::unordered_flat_map<test::object, test::object, test::hash,
602 test::equal_to,
603 test::allocator1<std::pair<test::object const, test::object> > >*
604 test_map_tracking;
605
606 boost::unordered_flat_set<test::object, test::hash, test::equal_to,
607 monotonic_allocator<test::object> >* test_set_monotonic;
608 boost::unordered_flat_map<test::object, test::object, test::hash,
609 test::equal_to,
610 monotonic_allocator<std::pair<test::object const, test::object> > >*
611 test_map_monotonic;
612
613 boost::unordered_node_set<int>* int_node_set_ptr;
614 boost::unordered_node_map<test::movable, test::movable, test::hash,
615 test::equal_to, test::allocator2<test::movable> >* test_node_map_ptr;
616
617 boost::unordered_node_set<test::object, test::hash, test::equal_to,
618 test::allocator1<test::object> >* test_node_set_tracking;
619 boost::unordered_node_map<test::object, test::object, test::hash,
620 test::equal_to,
621 test::allocator1<std::pair<test::object const, test::object> > >*
622 test_node_map_tracking;
623
624 boost::unordered_node_set<test::object, test::hash, test::equal_to,
625 monotonic_allocator<test::object> >* test_node_set_monotonic;
626 boost::unordered_node_map<test::object, test::object, test::hash,
627 test::equal_to,
628 monotonic_allocator<std::pair<test::object const, test::object> > >*
629 test_node_map_monotonic;
630
631 // clang-format off
632 UNORDERED_TEST(rehash_empty_test1,
633 ((int_set_ptr)(test_map_ptr)
634 (int_node_set_ptr)(test_node_map_ptr)))
635 UNORDERED_TEST(rehash_empty_test2,
636 ((int_set_ptr)(test_map_ptr)
637 (int_node_set_ptr)(test_node_map_ptr))(
638 (default_generator)(generate_collisions)(limited_range)))
639 UNORDERED_TEST(rehash_empty_test3,
640 ((int_set_ptr)(test_map_ptr)
641 (int_node_set_ptr)(test_node_map_ptr))(
642 (default_generator)(generate_collisions)(limited_range)))
643 UNORDERED_TEST(rehash_test1,
644 ((int_set_ptr)(test_map_ptr)
645 (int_node_set_ptr)(test_node_map_ptr))(
646 (default_generator)(generate_collisions)(limited_range)))
647 UNORDERED_TEST(reserve_empty_test1,
648 ((int_set_ptr)(test_map_ptr)(int_node_set_ptr)(test_node_map_ptr)))
649 UNORDERED_TEST(reserve_empty_test2,
650 ((int_set_ptr)(test_map_ptr)(int_node_set_ptr)(test_node_map_ptr)))
651 UNORDERED_TEST(reserve_test1,
652 ((int_set_ptr)(test_map_ptr)(int_node_set_ptr)(test_node_map_ptr))(
653 (default_generator)(generate_collisions)(limited_range)))
654 UNORDERED_TEST(reserve_test2,
655 ((int_set_ptr)(test_map_ptr)(int_node_set_ptr)(test_node_map_ptr))(
656 (default_generator)(generate_collisions)(limited_range)))
657 UNORDERED_TEST(rehash_empty_tracking,
658 ((test_set_tracking)(test_map_tracking)
659 (test_node_set_tracking)(test_node_map_tracking))(
660 (default_generator)(generate_collisions)(limited_range)))
661 UNORDERED_TEST(rehash_nonempty_tracking,
662 ((test_set_tracking)(test_map_tracking)
663 (test_node_set_tracking)(test_node_map_tracking))(
664 (default_generator)(limited_range)))
665 UNORDERED_TEST(rehash_stability,
666 ((test_set_monotonic)(test_map_monotonic)
667 (test_node_set_monotonic)(test_node_map_monotonic))(
668 (default_generator)(limited_range)))
669 UNORDERED_TEST(rehash_node_stability,
670 ((int_node_set_ptr)(test_node_map_ptr)
671 (test_node_set_tracking)(test_node_map_tracking))(
672 (default_generator)(generate_collisions)(limited_range)))
673 // clang-format on
674#else
675 boost::unordered_set<int>* int_set_ptr;
676 boost::unordered_multiset<test::object, test::hash, test::equal_to,
677 test::allocator2<test::object> >* test_multiset_ptr;
678 boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to,
679 test::allocator2<test::movable> >* test_map_ptr;
680 boost::unordered_multimap<int, int>* int_multimap_ptr;
681
682 boost::unordered_set<test::object, test::hash, test::equal_to,
683 test::allocator1<test::object> >* test_set_tracking;
684 boost::unordered_multiset<test::object, test::hash, test::equal_to,
685 test::allocator1<test::object> >* test_multiset_tracking;
686 boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
687 test::allocator1<std::pair<test::object const, test::object> > >*
688 test_map_tracking;
689 boost::unordered_multimap<test::object, test::object, test::hash,
690 test::equal_to,
691 test::allocator1<std::pair<test::object const, test::object> > >*
692 test_multimap_tracking;
693
694 boost::unordered_set<test::object, test::hash, test::equal_to,
695 monotonic_allocator<test::object> >* test_set_monotonic;
696 boost::unordered_multiset<test::object, test::hash, test::equal_to,
697 monotonic_allocator<test::object> >* test_multiset_monotonic;
698 boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
699 monotonic_allocator<std::pair<test::object const, test::object> > >*
700 test_map_monotonic;
701 boost::unordered_multimap<test::object, test::object, test::hash,
702 test::equal_to,
703 monotonic_allocator<std::pair<test::object const, test::object> > >*
704 test_multimap_monotonic;
705
706 // clang-format off
707 UNORDERED_TEST(rehash_empty_test1,
708 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
709 UNORDERED_TEST(rehash_empty_test2,
710 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
711 (default_generator)(generate_collisions)(limited_range)))
712 UNORDERED_TEST(rehash_empty_test3,
713 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
714 (default_generator)(generate_collisions)(limited_range)))
715 UNORDERED_TEST(rehash_test1,
716 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
717 (default_generator)(generate_collisions)(limited_range)))
718 UNORDERED_TEST(reserve_empty_test1,
719 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
720 UNORDERED_TEST(reserve_empty_test2,
721 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
722 UNORDERED_TEST(reserve_test1,
723 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
724 (default_generator)(generate_collisions)(limited_range)))
725 UNORDERED_TEST(reserve_test2,
726 ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
727 (default_generator)(generate_collisions)(limited_range)))
728 UNORDERED_TEST(rehash_empty_tracking,
729 ((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
730 (default_generator)(generate_collisions)(limited_range)))
731 UNORDERED_TEST(rehash_nonempty_tracking,
732 ((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
733 (default_generator)(generate_collisions)(limited_range)))
734 UNORDERED_TEST(rehash_stability,
735 ((test_set_monotonic)(test_multiset_monotonic)(test_map_monotonic)(test_multimap_monotonic))(
736 (default_generator)(limited_range)))
737 UNORDERED_TEST(rehash_node_stability,
738 ((int_set_ptr)(test_map_ptr)(test_set_tracking)(test_map_tracking)
739 (test_multiset_ptr)(int_multimap_ptr)
740 (test_multiset_tracking)(test_multimap_tracking))(
741 (default_generator)(generate_collisions)(limited_range)))
742// clang-format on
743#endif
744} // namespace rehash_tests
745
746RUN_TESTS()
747

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