robin_map_tests.cpp
Go to the documentation of this file.
1 
24 #include <tsl/robin_map.h>
25 
26 #include <boost/mpl/list.hpp>
27 #include <boost/test/unit_test.hpp>
28 #include <cstddef>
29 #include <cstdint>
30 #include <functional>
31 #include <iterator>
32 #include <memory>
33 #include <stdexcept>
34 #include <string>
35 #include <tuple>
36 #include <type_traits>
37 #include <utility>
38 #include <vector>
39 
40 #include "utils.h"
41 
42 BOOST_AUTO_TEST_SUITE(test_robin_map)
43 
44 using test_types = boost::mpl::list<
47  // Test with hash having a lot of collisions
53  mod_hash<9>>,
54 
55  // other GrowthPolicy
57  std::equal_to<move_only_test>,
62  std::equal_to<move_only_test>,
65 
67  std::equal_to<copy_only_test>,
72  std::equal_to<copy_only_test>,
75 
80  // insert x values, insert them again, check values
81  using key_t = typename HMap::key_type;
82  using value_t = typename HMap::mapped_type;
83 
84  const std::size_t nb_values = 1000;
85  HMap map(0);
86  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
87 
88  typename HMap::iterator it;
89  bool inserted;
90 
91  for (std::size_t i = 0; i < nb_values; i++) {
92  std::tie(it, inserted) =
93  map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
94 
95  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
96  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
97  BOOST_CHECK(inserted);
98  }
99  BOOST_CHECK_EQUAL(map.size(), nb_values);
100 
101  for (std::size_t i = 0; i < nb_values; i++) {
102  std::tie(it, inserted) = map.insert(
103  {utils::get_key<key_t>(i), utils::get_value<value_t>(i + 1)});
104 
105  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
106  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
107  BOOST_CHECK(!inserted);
108  }
109 
110  for (std::size_t i = 0; i < nb_values; i++) {
111  it = map.find(utils::get_key<key_t>(i));
112 
113  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
114  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
115  }
116 }
117 
118 BOOST_AUTO_TEST_CASE(test_range_insert) {
119  // create a vector<std::pair> of values to insert, insert part of them in the
120  // map, check values
121  const int nb_values = 1000;
122  std::vector<std::pair<int, int>> values_to_insert(nb_values);
123  for (int i = 0; i < nb_values; i++) {
124  values_to_insert[i] = std::make_pair(i, i + 1);
125  }
126 
127  tsl::robin_map<int, int> map = {{-1, 1}, {-2, 2}};
128  map.insert(std::next(values_to_insert.begin(), 10),
129  values_to_insert.end() - 5);
130 
131  BOOST_CHECK_EQUAL(map.size(), 987);
132 
133  BOOST_CHECK_EQUAL(map.at(-1), 1);
134  BOOST_CHECK_EQUAL(map.at(-2), 2);
135 
136  for (int i = 10; i < nb_values - 5; i++) {
137  BOOST_CHECK_EQUAL(map.at(i), i + 1);
138  }
139 }
140 
141 BOOST_AUTO_TEST_CASE(test_rehash_0) {
142  tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
144  map;
145  map.rehash(0);
146 }
147 
148 BOOST_AUTO_TEST_CASE(test_insert_with_hint) {
149  tsl::robin_map<int, int> map{{1, 0}, {2, 1}, {3, 2}};
150 
151  // Wrong hint
152  BOOST_CHECK(map.insert(map.find(2), std::make_pair(3, 4)) == map.find(3));
153 
154  // Good hint
155  BOOST_CHECK(map.insert(map.find(2), std::make_pair(2, 4)) == map.find(2));
156 
157  // end() hint
158  BOOST_CHECK(map.insert(map.find(10), std::make_pair(2, 4)) == map.find(2));
159 
160  BOOST_CHECK_EQUAL(map.size(), 3);
161 
162  // end() hint, new value
163  BOOST_CHECK_EQUAL(map.insert(map.find(10), std::make_pair(4, 3))->first, 4);
164 
165  // Wrong hint, new value
166  BOOST_CHECK_EQUAL(map.insert(map.find(2), std::make_pair(5, 4))->first, 5);
167 
168  BOOST_CHECK_EQUAL(map.size(), 5);
169 }
170 
174 BOOST_AUTO_TEST_CASE(test_emplace_hint) {
175  tsl::robin_map<int, int> map{{1, 0}, {2, 1}, {3, 2}};
176 
177  // Wrong hint
178  BOOST_CHECK(map.emplace_hint(map.find(2), std::piecewise_construct,
179  std::forward_as_tuple(3),
180  std::forward_as_tuple(4)) == map.find(3));
181 
182  // Good hint
183  BOOST_CHECK(map.emplace_hint(map.find(2), std::piecewise_construct,
184  std::forward_as_tuple(2),
185  std::forward_as_tuple(4)) == map.find(2));
186 
187  // end() hint
188  BOOST_CHECK(map.emplace_hint(map.find(10), std::piecewise_construct,
189  std::forward_as_tuple(2),
190  std::forward_as_tuple(4)) == map.find(2));
191 
192  BOOST_CHECK_EQUAL(map.size(), 3);
193 
194  // end() hint, new value
195  BOOST_CHECK_EQUAL(
196  map.emplace_hint(map.find(10), std::piecewise_construct,
197  std::forward_as_tuple(4), std::forward_as_tuple(3))
198  ->first,
199  4);
200 
201  // Wrong hint, new value
202  BOOST_CHECK_EQUAL(
203  map.emplace_hint(map.find(2), std::piecewise_construct,
204  std::forward_as_tuple(5), std::forward_as_tuple(4))
205  ->first,
206  5);
207 
208  BOOST_CHECK_EQUAL(map.size(), 5);
209 }
210 
214 BOOST_AUTO_TEST_CASE(test_emplace) {
217  bool inserted;
218 
219  std::tie(it, inserted) =
220  map.emplace(std::piecewise_construct, std::forward_as_tuple(10),
221  std::forward_as_tuple(1));
222  BOOST_CHECK_EQUAL(it->first, 10);
223  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
224  BOOST_CHECK(inserted);
225 
226  std::tie(it, inserted) =
227  map.emplace(std::piecewise_construct, std::forward_as_tuple(10),
228  std::forward_as_tuple(3));
229  BOOST_CHECK_EQUAL(it->first, 10);
230  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
231  BOOST_CHECK(!inserted);
232 }
233 
237 BOOST_AUTO_TEST_CASE(test_try_emplace) {
240  bool inserted;
241 
242  std::tie(it, inserted) = map.try_emplace(10, 1);
243  BOOST_CHECK_EQUAL(it->first, 10);
244  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
245  BOOST_CHECK(inserted);
246 
247  std::tie(it, inserted) = map.try_emplace(10, 3);
248  BOOST_CHECK_EQUAL(it->first, 10);
249  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
250  BOOST_CHECK(!inserted);
251 }
252 
253 BOOST_AUTO_TEST_CASE(test_try_emplace_2) {
254  // Insert x values with try_emplace, insert them again, check with find.
257  bool inserted;
258 
259  const std::size_t nb_values = 1000;
260  for (std::size_t i = 0; i < nb_values; i++) {
261  std::tie(it, inserted) = map.try_emplace(utils::get_key<std::string>(i), i);
262 
263  BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
264  BOOST_CHECK_EQUAL(it->second, move_only_test(i));
265  BOOST_CHECK(inserted);
266  }
267  BOOST_CHECK_EQUAL(map.size(), nb_values);
268 
269  for (std::size_t i = 0; i < nb_values; i++) {
270  std::tie(it, inserted) =
271  map.try_emplace(utils::get_key<std::string>(i), i + 1);
272 
273  BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
274  BOOST_CHECK_EQUAL(it->second, move_only_test(i));
275  BOOST_CHECK(!inserted);
276  }
277 
278  for (std::size_t i = 0; i < nb_values; i++) {
279  it = map.find(utils::get_key<std::string>(i));
280 
281  BOOST_CHECK_EQUAL(it->first, utils::get_key<std::string>(i));
282  BOOST_CHECK_EQUAL(it->second, move_only_test(i));
283  }
284 }
285 
286 BOOST_AUTO_TEST_CASE(test_try_emplace_hint) {
288 
289  // end() hint, new value
290  auto it = map.try_emplace(map.find(10), 10, 1);
291  BOOST_CHECK_EQUAL(it->first, 10);
292  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
293 
294  // Good hint
295  it = map.try_emplace(map.find(10), 10, 3);
296  BOOST_CHECK_EQUAL(it->first, 10);
297  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
298 
299  // Wrong hint, new value
300  it = map.try_emplace(map.find(10), 1, 3);
301  BOOST_CHECK_EQUAL(it->first, 1);
302  BOOST_CHECK_EQUAL(it->second, move_only_test(3));
303 }
304 
308 BOOST_AUTO_TEST_CASE(test_insert_or_assign) {
311  bool inserted;
312 
313  std::tie(it, inserted) = map.insert_or_assign(10, move_only_test(1));
314  BOOST_CHECK_EQUAL(it->first, 10);
315  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
316  BOOST_CHECK(inserted);
317 
318  std::tie(it, inserted) = map.insert_or_assign(10, move_only_test(3));
319  BOOST_CHECK_EQUAL(it->first, 10);
320  BOOST_CHECK_EQUAL(it->second, move_only_test(3));
321  BOOST_CHECK(!inserted);
322 }
323 
324 BOOST_AUTO_TEST_CASE(test_insert_or_assign_hint) {
326 
327  // end() hint, new value
328  auto it = map.insert_or_assign(map.find(10), 10, move_only_test(1));
329  BOOST_CHECK_EQUAL(it->first, 10);
330  BOOST_CHECK_EQUAL(it->second, move_only_test(1));
331 
332  // Good hint
333  it = map.insert_or_assign(map.find(10), 10, move_only_test(3));
334  BOOST_CHECK_EQUAL(it->first, 10);
335  BOOST_CHECK_EQUAL(it->second, move_only_test(3));
336 
337  // Bad hint, new value
338  it = map.insert_or_assign(map.find(10), 1, move_only_test(3));
339  BOOST_CHECK_EQUAL(it->first, 1);
340  BOOST_CHECK_EQUAL(it->second, move_only_test(3));
341 }
342 
346 BOOST_AUTO_TEST_CASE(test_range_erase_all) {
347  // insert x values, delete all with iterators
349 
350  const std::size_t nb_values = 1000;
351  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
352 
353  auto it = map.erase(map.begin(), map.end());
354  BOOST_CHECK(it == map.end());
355  BOOST_CHECK(map.empty());
356 }
357 
358 BOOST_AUTO_TEST_CASE(test_range_erase) {
359  // insert x values, delete all with iterators except 10 first and 780 last
360  // values
362 
363  const std::size_t nb_values = 1000;
364  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
365 
366  auto it_first = std::next(map.begin(), 10);
367  auto it_last = std::next(map.begin(), 220);
368 
369  auto it = map.erase(it_first, it_last);
370  BOOST_CHECK_EQUAL(std::distance(it, map.end()), 780);
371  BOOST_CHECK_EQUAL(map.size(), 790);
372  BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 790);
373 
374  for (auto& val : map) {
375  BOOST_CHECK_EQUAL(map.count(val.first), 1);
376  }
377 }
378 
379 BOOST_AUTO_TEST_CASE_TEMPLATE(test_erase_loop, HMap, test_types) {
380  // insert x values, delete all one by one with iterator
381  std::size_t nb_values = 1000;
382 
383  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
384  HMap map2 = utils::get_filled_hash_map<HMap>(nb_values);
385 
386  auto it = map.begin();
387  // Use second map to check for key after delete as we may not copy the key
388  // with move-only types.
389  auto it2 = map2.begin();
390  while (it != map.end()) {
391  it = map.erase(it);
392  --nb_values;
393 
394  BOOST_CHECK_EQUAL(map.count(it2->first), 0);
395  BOOST_CHECK_EQUAL(map.size(), nb_values);
396  ++it2;
397  }
398 
399  BOOST_CHECK(map.empty());
400 }
401 
402 BOOST_AUTO_TEST_CASE_TEMPLATE(test_erase_loop_range, HMap, test_types) {
403  // insert x values, delete all five by five with iterators
404  const std::size_t hop = 5;
405  std::size_t nb_values = 1000;
406 
407  BOOST_REQUIRE_EQUAL(nb_values % hop, 0);
408 
409  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
410 
411  auto it = map.begin();
412  while (it != map.end()) {
413  it = map.erase(it, std::next(it, hop));
414  nb_values -= hop;
415 
416  BOOST_CHECK_EQUAL(map.size(), nb_values);
417  }
418 
419  BOOST_CHECK(map.empty());
420 }
421 
422 BOOST_AUTO_TEST_CASE_TEMPLATE(test_insert_erase_insert, HMap, test_types) {
423  // insert x/2 values, delete x/4 values, insert x/2 values, find each value
424  using key_t = typename HMap::key_type;
425  using value_t = typename HMap::mapped_type;
426 
427  const std::size_t nb_values = 2000;
428  HMap map(10);
429  typename HMap::iterator it;
430  bool inserted;
431 
432  // Insert nb_values/2
433  for (std::size_t i = 0; i < nb_values / 2; i++) {
434  std::tie(it, inserted) =
435  map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
436 
437  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
438  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
439  BOOST_CHECK(inserted);
440  }
441  BOOST_CHECK_EQUAL(map.size(), nb_values / 2);
442 
443  // Delete nb_values/4
444  for (std::size_t i = 0; i < nb_values / 2; i++) {
445  if (i % 2 == 0) {
446  BOOST_CHECK_EQUAL(map.erase(utils::get_key<key_t>(i)), 1);
447  }
448  }
449  BOOST_CHECK_EQUAL(map.size(), nb_values / 4);
450 
451  // Insert nb_values/2
452  for (std::size_t i = nb_values / 2; i < nb_values; i++) {
453  std::tie(it, inserted) =
454  map.insert({utils::get_key<key_t>(i), utils::get_value<value_t>(i)});
455 
456  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
457  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
458  BOOST_CHECK(inserted);
459  }
460  BOOST_CHECK_EQUAL(map.size(), nb_values - nb_values / 4);
461 
462  // Find
463  for (std::size_t i = 0; i < nb_values; i++) {
464  if (i % 2 == 0 && i < nb_values / 2) {
465  it = map.find(utils::get_key<key_t>(i));
466 
467  BOOST_CHECK(it == map.end());
468  } else {
469  it = map.find(utils::get_key<key_t>(i));
470 
471  BOOST_REQUIRE(it != map.end());
472  BOOST_CHECK_EQUAL(it->first, utils::get_key<key_t>(i));
473  BOOST_CHECK_EQUAL(it->second, utils::get_value<value_t>(i));
474  }
475  }
476 }
477 
478 BOOST_AUTO_TEST_CASE(test_range_erase_same_iterators) {
479  // insert x values, test erase with same iterator as each parameter, check if
480  // returned mutable iterator is valid.
481  const std::size_t nb_values = 100;
482  auto map =
483  utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
484  nb_values);
485 
487  map.cbegin();
488  std::advance(it_const, 10);
489 
491  map.erase(it_const, it_const);
492  BOOST_CHECK(it_const == it_mutable);
493  BOOST_CHECK(map.mutable_iterator(it_const) == it_mutable);
494  BOOST_CHECK_EQUAL(map.size(), 100);
495 
496  it_mutable.value() = -100;
497  BOOST_CHECK_EQUAL(it_const.value(), -100);
498 }
499 
503 BOOST_AUTO_TEST_CASE(test_max_load_factor_extreme_factors) {
505 
506  map.max_load_factor(0.0f);
507  BOOST_CHECK_GT(map.max_load_factor(), 0.0f);
508 
509  map.max_load_factor(10.0f);
510  BOOST_CHECK_LT(map.max_load_factor(), 1.0f);
511 }
512 
516 BOOST_AUTO_TEST_CASE(test_min_load_factor_extreme_factors) {
518 
519  BOOST_CHECK_EQUAL(map.min_load_factor(), 0.0f);
520  BOOST_CHECK_LT(map.min_load_factor(), map.max_load_factor());
521 
522  map.min_load_factor(-10.0f);
523  BOOST_CHECK_EQUAL(map.min_load_factor(), 0.0f);
524 
525  map.min_load_factor(0.9f);
526  map.max_load_factor(0.1f);
527 
528  // max_load_factor should always be > min_load_factor.
529  // Factors should have been clamped.
530  BOOST_CHECK_LT(map.min_load_factor(), map.max_load_factor());
531 }
532 
533 BOOST_AUTO_TEST_CASE(test_min_load_factor) {
534  // set min_load_factor to 0.15 and max_load_factor to 0.5.
535  // rehash to 100 buckets, insert 50 elements, erase until load_factor() <
536  // min_load_factor(), insert an element, check if map has shrinked.
537  const std::size_t nb_values = 50;
539 
540  map.min_load_factor(0.15f);
541  BOOST_CHECK_EQUAL(map.min_load_factor(), 0.15f);
542 
543  map.max_load_factor(0.5f);
544  BOOST_CHECK_EQUAL(map.max_load_factor(), 0.5f);
545 
546  map.rehash(nb_values * 2);
547  for (std::size_t i = 0; i < nb_values; i++) {
548  map.insert(
549  {utils::get_key<std::int64_t>(i), utils::get_value<std::int64_t>(i)});
550  }
551  BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
552 
553  while (map.load_factor() >= map.min_load_factor()) {
554  map.erase(map.begin());
555  }
556 
557  // Shrink is done on insert.
558  map.insert({utils::get_key<std::int64_t>(map.bucket_count()),
559  utils::get_value<std::int64_t>(map.bucket_count())});
560  BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
561 }
562 
563 BOOST_AUTO_TEST_CASE(test_min_load_factor_range_erase) {
564  // set min_load_factor to 0.15 and max_load_factor to 0.5.
565  // rehash to 100 buckets, insert 50 elements, erase 40 with range erase,
566  // insert an element, check if map has shrinked.
567  const std::size_t nb_values = 50;
568  const std::size_t nb_values_erase = 40;
570 
571  map.min_load_factor(0.15f);
572  BOOST_CHECK_EQUAL(map.min_load_factor(), 0.15f);
573 
574  map.max_load_factor(0.5f);
575  BOOST_CHECK_EQUAL(map.max_load_factor(), 0.5f);
576 
577  map.rehash(nb_values * 2);
578  for (std::size_t i = 0; i < nb_values; i++) {
579  map.insert(
580  {utils::get_key<std::int64_t>(i), utils::get_value<std::int64_t>(i)});
581  }
582  BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
583 
584  map.erase(std::next(map.begin(), nb_values - nb_values_erase), map.end());
585 
586  // Shrink is done on insert.
587  map.insert({utils::get_key<std::int64_t>(map.bucket_count()),
588  utils::get_value<std::int64_t>(map.bucket_count())});
589  BOOST_CHECK_GT(map.load_factor(), map.min_load_factor());
590  BOOST_CHECK_LT(map.bucket_count(), nb_values * 2);
591 }
592 
596 BOOST_AUTO_TEST_CASE(test_rehash_empty) {
597  // test rehash(0), test find/erase/insert on map.
598  const std::size_t nb_values = 100;
599  auto map =
600  utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
601  nb_values);
602 
603  const std::size_t bucket_count = map.bucket_count();
604  BOOST_CHECK(bucket_count >= nb_values);
605 
606  map.clear();
607  BOOST_CHECK_EQUAL(map.bucket_count(), bucket_count);
608  BOOST_CHECK(map.empty());
609 
610  map.rehash(0);
611  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
612  BOOST_CHECK(map.empty());
613 
614  BOOST_CHECK(map.find(1) == map.end());
615  BOOST_CHECK_EQUAL(map.erase(1), 0);
616  BOOST_CHECK(map.insert({1, 10}).second);
617  BOOST_CHECK_EQUAL(map.at(1), 10);
618 }
619 
623 BOOST_AUTO_TEST_CASE(test_compare) {
625  {"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"b", 2}};
627  {"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}, {"d", 4}};
629  {"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}, {"d", 4}, {"f", 6}};
631  {"e", 5}, {"c", 3}, {"b", 2}, {"a", 1}};
633  {"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"b", 26}};
635  {"a", 1}, {"e", 5}, {"d", 4}, {"c", 3}, {"z", 2}};
636 
637  BOOST_CHECK(map1 == map1_copy);
638  BOOST_CHECK(map1_copy == map1);
639 
640  BOOST_CHECK(map1 != map2);
641  BOOST_CHECK(map2 != map1);
642 
643  BOOST_CHECK(map1 != map3);
644  BOOST_CHECK(map3 != map1);
645 
646  BOOST_CHECK(map1 != map4);
647  BOOST_CHECK(map4 != map1);
648 
649  BOOST_CHECK(map1 != map5);
650  BOOST_CHECK(map5 != map1);
651 
652  BOOST_CHECK(map2 != map3);
653  BOOST_CHECK(map3 != map2);
654 
655  BOOST_CHECK(map2 != map4);
656  BOOST_CHECK(map4 != map2);
657 
658  BOOST_CHECK(map2 != map5);
659  BOOST_CHECK(map5 != map2);
660 
661  BOOST_CHECK(map3 != map4);
662  BOOST_CHECK(map4 != map3);
663 
664  BOOST_CHECK(map3 != map5);
665  BOOST_CHECK(map5 != map3);
666 
667  BOOST_CHECK(map4 != map5);
668  BOOST_CHECK(map5 != map4);
669 }
670 
674 BOOST_AUTO_TEST_CASE(test_clear) {
675  // insert x values, clear map, test insert
677 
678  const std::size_t nb_values = 1000;
679  auto map = utils::get_filled_hash_map<HMap>(nb_values);
680 
681  map.clear();
682  BOOST_CHECK_EQUAL(map.size(), 0);
683  BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 0);
684 
685  map.insert({5, -5});
686  map.insert({{1, -1}, {2, -1}, {4, -4}, {3, -3}});
687 
688  BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}})));
689 }
690 
691 BOOST_AUTO_TEST_CASE(test_clear_with_min_load_factor) {
692  // insert x values, clear map, test insert
694 
695  const std::size_t nb_values = 1000;
696  auto map = utils::get_filled_hash_map<HMap>(nb_values);
697  map.min_load_factor(0.1f);
698 
699  map.clear();
700  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
701  BOOST_CHECK_EQUAL(map.size(), 0);
702  BOOST_CHECK_EQUAL(std::distance(map.begin(), map.end()), 0);
703 
704  map.insert({5, -5});
705  map.insert({{1, -1}, {2, -1}, {4, -4}, {3, -3}});
706 
707  BOOST_CHECK(map == (HMap({{5, -5}, {1, -1}, {2, -1}, {4, -4}, {3, -3}})));
708 }
709 
713 BOOST_AUTO_TEST_CASE(test_modify_value_through_iterator) {
714  // insert x values, modify value of even keys with iterators, check values
715  const std::size_t nb_values = 100;
716  auto map =
717  utils::get_filled_hash_map<tsl::robin_map<std::int64_t, std::int64_t>>(
718  nb_values);
719 
720  for (auto it = map.begin(); it != map.end(); it++) {
721  if (it.key() % 2 == 0) {
722  it.value() = -1;
723  }
724  }
725 
726  for (auto& val : map) {
727  if (val.first % 2 == 0) {
728  BOOST_CHECK_EQUAL(val.second, -1);
729  } else {
730  BOOST_CHECK_NE(val.second, -1);
731  }
732  }
733 }
734 
735 BOOST_AUTO_TEST_CASE(test_modify_value_through_iterator_with_const_qualifier) {
736  tsl::robin_map<int, int> map = {{0, 1}};
737  const auto it = map.begin();
738 
739  BOOST_CHECK_EQUAL(it->second, 1);
740  it.value() += 10;
741  BOOST_CHECK_EQUAL(it->second, 11);
742 }
743 
748 BOOST_AUTO_TEST_CASE(test_extreme_bucket_count_value_construction) {
749  // std::bad_alloc or std::length_error will be thrown depending on the
750  // platform overcommit
752  (tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
753  std::allocator<std::pair<int, int>>, false,
755  std::numeric_limits<std::size_t>::max())),
756  std::bad_alloc, std::length_error);
757 
759  (tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
760  std::allocator<std::pair<int, int>>, false,
762  std::numeric_limits<std::size_t>::max() / 2 + 1)),
763  std::bad_alloc, std::length_error);
764 
766  (tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
767  std::allocator<std::pair<int, int>>, false,
769  std::numeric_limits<std::size_t>::max())),
770  std::bad_alloc, std::length_error);
771 
773  (tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
774  std::allocator<std::pair<int, int>>, false,
776  std::numeric_limits<std::size_t>::max() / 2)),
777  std::bad_alloc, std::length_error);
778 
780  (tsl::robin_map<int, int, std::hash<int>, std::equal_to<int>,
781  std::allocator<std::pair<int, int>>, false,
783  std::numeric_limits<std::size_t>::max())),
784  std::bad_alloc, std::length_error);
785 }
786 
787 BOOST_AUTO_TEST_CASE(test_range_construct) {
788  tsl::robin_map<int, int> map = {{2, 1}, {1, 0}, {3, 2}};
789 
790  tsl::robin_map<int, int> map2(map.begin(), map.end());
791  tsl::robin_map<int, int> map3(map.cbegin(), map.cend());
792 }
793 
797 BOOST_AUTO_TEST_CASE(test_assign_operator) {
798  tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
799  BOOST_CHECK_EQUAL(map.size(), 2);
800 
801  map = {{1, 3}, {2, 4}};
802  BOOST_CHECK_EQUAL(map.size(), 2);
803  BOOST_CHECK_EQUAL(map.at(1), 3);
804  BOOST_CHECK_EQUAL(map.at(2), 4);
805  BOOST_CHECK(map.find(0) == map.end());
806 
807  map = {};
808  BOOST_CHECK(map.empty());
809 }
810 
814 BOOST_AUTO_TEST_CASE(test_move_constructor) {
815  // insert x values in map, move map into map_move with move constructor, check
816  // map and map_move, insert additional values in map_move, check map_move
818 
819  const std::size_t nb_values = 100;
820  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
821  HMap map_move(std::move(map));
822 
823  BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values));
824  BOOST_CHECK(map == (HMap()));
825 
826  for (std::size_t i = nb_values; i < nb_values * 2; i++) {
827  map_move.insert(
828  {utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
829  }
830 
831  BOOST_CHECK_EQUAL(map_move.size(), nb_values * 2);
832  BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values * 2));
833 }
834 
835 BOOST_AUTO_TEST_CASE(test_move_constructor_empty) {
837  tsl::robin_map<std::string, move_only_test> map_move(std::move(map));
838 
839  BOOST_CHECK(map.empty());
840  BOOST_CHECK(map_move.empty());
841 
842  BOOST_CHECK(map.find("") == map.end());
843  BOOST_CHECK(map_move.find("") == map_move.end());
844 }
845 
846 BOOST_AUTO_TEST_CASE(test_move_operator) {
847  // insert x values in map, move map into map_move with move operator, check
848  // map and map_move, insert additional values in map_move, check map_move
850 
851  const std::size_t nb_values = 100;
852  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
853  HMap map_move = utils::get_filled_hash_map<HMap>(1);
854  map_move = std::move(map);
855 
856  BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values));
857  BOOST_CHECK(map == (HMap()));
858 
859  for (std::size_t i = nb_values; i < nb_values * 2; i++) {
860  map_move.insert(
861  {utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
862  }
863 
864  BOOST_CHECK_EQUAL(map_move.size(), nb_values * 2);
865  BOOST_CHECK(map_move == utils::get_filled_hash_map<HMap>(nb_values * 2));
866 }
867 
868 BOOST_AUTO_TEST_CASE(test_move_operator_empty) {
871  map_move = (std::move(map));
872 
873  BOOST_CHECK(map.empty());
874  BOOST_CHECK(map_move.empty());
875 
876  BOOST_CHECK(map.find("") == map.end());
877  BOOST_CHECK(map_move.find("") == map_move.end());
878 }
879 
880 BOOST_AUTO_TEST_CASE(test_reassign_moved_object_move_constructor) {
882 
883  HMap map = {{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
884  HMap map_move(std::move(map));
885 
886  BOOST_CHECK_EQUAL(map_move.size(), 3);
887  BOOST_CHECK_EQUAL(map.size(), 0);
888 
889  map = {{"Key4", "Value4"}, {"Key5", "Value5"}};
890  BOOST_CHECK(map == (HMap({{"Key4", "Value4"}, {"Key5", "Value5"}})));
891 }
892 
893 BOOST_AUTO_TEST_CASE(test_reassign_moved_object_move_operator) {
895 
896  HMap map = {{"Key1", "Value1"}, {"Key2", "Value2"}, {"Key3", "Value3"}};
897  HMap map_move = std::move(map);
898 
899  BOOST_CHECK_EQUAL(map_move.size(), 3);
900  BOOST_CHECK_EQUAL(map.size(), 0);
901 
902  map = {{"Key4", "Value4"}, {"Key5", "Value5"}};
903  BOOST_CHECK(map == (HMap({{"Key4", "Value4"}, {"Key5", "Value5"}})));
904 }
905 
906 BOOST_AUTO_TEST_CASE(test_use_after_move_constructor) {
908 
909  const std::size_t nb_values = 100;
910  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
911  HMap map_move(std::move(map));
912 
913  BOOST_CHECK(map == (HMap()));
914  BOOST_CHECK_EQUAL(map.size(), 0);
915  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
916  BOOST_CHECK_EQUAL(map.erase("a"), 0);
917  BOOST_CHECK(map.find("a") == map.end());
918 
919  for (std::size_t i = 0; i < nb_values; i++) {
920  map.insert(
921  {utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
922  }
923 
924  BOOST_CHECK_EQUAL(map.size(), nb_values);
925  BOOST_CHECK(map == map_move);
926 }
927 
928 BOOST_AUTO_TEST_CASE(test_use_after_move_operator) {
930 
931  const std::size_t nb_values = 100;
932  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
933  HMap map_move(0);
934  map_move = std::move(map);
935 
936  BOOST_CHECK(map == (HMap()));
937  BOOST_CHECK_EQUAL(map.size(), 0);
938  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
939  BOOST_CHECK_EQUAL(map.erase("a"), 0);
940  BOOST_CHECK(map.find("a") == map.end());
941 
942  for (std::size_t i = 0; i < nb_values; i++) {
943  map.insert(
944  {utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
945  }
946 
947  BOOST_CHECK_EQUAL(map.size(), nb_values);
948  BOOST_CHECK(map == map_move);
949 }
950 
951 BOOST_AUTO_TEST_CASE(test_copy_constructor_and_operator) {
953 
954  const std::size_t nb_values = 100;
955  HMap map = utils::get_filled_hash_map<HMap>(nb_values);
956 
957  HMap map_copy = map;
958  HMap map_copy2(map);
959  HMap map_copy3 = utils::get_filled_hash_map<HMap>(1);
960  map_copy3 = map;
961 
962  BOOST_CHECK(map == map_copy);
963  map.clear();
964 
965  BOOST_CHECK(map_copy == map_copy2);
966  BOOST_CHECK(map_copy == map_copy3);
967 }
968 
969 BOOST_AUTO_TEST_CASE(test_copy_constructor_empty) {
971  tsl::robin_map<std::string, int> map_copy(map);
972 
973  BOOST_CHECK(map.empty());
974  BOOST_CHECK(map_copy.empty());
975 
976  BOOST_CHECK(map.find("") == map.end());
977  BOOST_CHECK(map_copy.find("") == map_copy.end());
978 }
979 
980 BOOST_AUTO_TEST_CASE(test_copy_operator_empty) {
983  map_copy = map;
984 
985  BOOST_CHECK(map.empty());
986  BOOST_CHECK(map_copy.empty());
987 
988  BOOST_CHECK(map.find("") == map.end());
989  BOOST_CHECK(map_copy.find("") == map_copy.end());
990 }
991 
996  // insert x values, use at for known and unknown values.
997  const tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
998 
999  BOOST_CHECK_EQUAL(map.at(0), 10);
1000  BOOST_CHECK_EQUAL(map.at(-2), 20);
1001  TSL_RH_CHECK_THROW(map.at(1), std::out_of_range);
1002 }
1003 
1007 BOOST_AUTO_TEST_CASE(test_contains) {
1008  tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
1009 
1010  BOOST_CHECK(map.contains(0));
1011  BOOST_CHECK(map.contains(-2));
1012  BOOST_CHECK(!map.contains(-3));
1013 }
1014 
1018 BOOST_AUTO_TEST_CASE(test_equal_range) {
1019  const tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
1020 
1021  auto it_pair = map.equal_range(0);
1022  BOOST_REQUIRE_EQUAL(std::distance(it_pair.first, it_pair.second), 1);
1023  BOOST_CHECK_EQUAL(it_pair.first->second, 10);
1024 
1025  it_pair = map.equal_range(1);
1026  BOOST_CHECK(it_pair.first == it_pair.second);
1027  BOOST_CHECK(it_pair.first == map.end());
1028 }
1029 
1033 BOOST_AUTO_TEST_CASE(test_access_operator) {
1034  // insert x values, use at for known and unknown values.
1035  tsl::robin_map<std::int64_t, std::int64_t> map = {{0, 10}, {-2, 20}};
1036 
1037  BOOST_CHECK_EQUAL(map[0], 10);
1038  BOOST_CHECK_EQUAL(map[-2], 20);
1039  BOOST_CHECK_EQUAL(map[2], std::int64_t());
1040 
1041  BOOST_CHECK_EQUAL(map.size(), 3);
1042 }
1043 
1048  tsl::robin_map<std::int64_t, std::int64_t> map = {{1, 10}, {8, 80}, {3, 30}};
1049  tsl::robin_map<std::int64_t, std::int64_t> map2 = {{4, 40}, {5, 50}};
1050 
1051  using std::swap;
1052  swap(map, map2);
1053 
1054  BOOST_CHECK(map ==
1055  (tsl::robin_map<std::int64_t, std::int64_t>{{4, 40}, {5, 50}}));
1056  BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
1057  {1, 10}, {8, 80}, {3, 30}}));
1058 
1059  map.insert({6, 60});
1060  map2.insert({4, 40});
1061 
1062  BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{
1063  {4, 40}, {5, 50}, {6, 60}}));
1064  BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
1065  {1, 10}, {8, 80}, {3, 30}, {4, 40}}));
1066 }
1067 
1068 BOOST_AUTO_TEST_CASE(test_swap_empty) {
1069  tsl::robin_map<std::int64_t, std::int64_t> map = {{1, 10}, {8, 80}, {3, 30}};
1071 
1072  using std::swap;
1073  swap(map, map2);
1074 
1075  BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{}));
1076  BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
1077  {1, 10}, {8, 80}, {3, 30}}));
1078 
1079  map.insert({6, 60});
1080  map2.insert({4, 40});
1081 
1082  BOOST_CHECK(map == (tsl::robin_map<std::int64_t, std::int64_t>{{6, 60}}));
1083  BOOST_CHECK(map2 == (tsl::robin_map<std::int64_t, std::int64_t>{
1084  {1, 10}, {8, 80}, {3, 30}, {4, 40}}));
1085 }
1086 
1090 BOOST_AUTO_TEST_CASE(test_serialize_desearialize_empty) {
1091  // serialize empty map; deserialize in new map; check equal.
1092  // for deserialization, test it with and without hash compatibility.
1094 
1095  serializer serial;
1096  empty_map.serialize(serial);
1097 
1098  deserializer dserial(serial.str());
1099  auto empty_map_deserialized = decltype(empty_map)::deserialize(dserial, true);
1100  BOOST_CHECK(empty_map_deserialized == empty_map);
1101 
1102  deserializer dserial2(serial.str());
1103  empty_map_deserialized = decltype(empty_map)::deserialize(dserial2, false);
1104  BOOST_CHECK(empty_map_deserialized == empty_map);
1105 }
1106 
1107 BOOST_AUTO_TEST_CASE(test_serialize_desearialize) {
1108  // insert x values; delete some values; serialize map; deserialize in new map;
1109  // check equal. for deserialization, test it with and without hash
1110  // compatibility.
1111  const std::size_t nb_values = 1000;
1112 
1114  for (std::size_t i = 0; i < nb_values + 40; i++) {
1115  map.insert(
1116  {utils::get_key<std::int32_t>(i), utils::get_value<move_only_test>(i)});
1117  }
1118 
1119  for (std::size_t i = nb_values; i < nb_values + 40; i++) {
1120  map.erase(utils::get_key<std::int32_t>(i));
1121  }
1122  BOOST_CHECK_EQUAL(map.size(), nb_values);
1123 
1124  serializer serial;
1125  map.serialize(serial);
1126 
1127  deserializer dserial(serial.str());
1128  auto map_deserialized = decltype(map)::deserialize(dserial, true);
1129  BOOST_CHECK(map == map_deserialized);
1130 
1131  deserializer dserial2(serial.str());
1132  map_deserialized = decltype(map)::deserialize(dserial2, false);
1133  BOOST_CHECK(map_deserialized == map);
1134 
1135  // Deserializing a map with StoreHash=true from a map serialized with
1136  // StoreHash=false with hash_compatible=true should throw an exception.
1137  deserializer dserial3(serial.str());
1139  (tsl::robin_map<std::int32_t, move_only_test, std::hash<std::int32_t>,
1140  std::equal_to<std::int32_t>,
1141  std::allocator<std::pair<std::int32_t, move_only_test>>,
1142  true>::deserialize(dserial3, true)),
1143  std::runtime_error);
1144 }
1145 
1146 BOOST_AUTO_TEST_CASE(test_serialize_desearialize_with_store_hash) {
1147  // insert x values; delete some values; serialize map; deserialize in new map;
1148  // check equal. for deserialization, test it with and without hash
1149  // compatibility.
1150  const std::size_t nb_values = 1000;
1151 
1153  std::equal_to<std::int32_t>,
1155  map;
1156  for (std::size_t i = 0; i < nb_values + 40; i++) {
1157  map.insert(
1158  {utils::get_key<std::int32_t>(i), utils::get_value<move_only_test>(i)});
1159  }
1160 
1161  for (std::size_t i = nb_values; i < nb_values + 40; i++) {
1162  map.erase(utils::get_key<std::int32_t>(i));
1163  }
1164  BOOST_CHECK_EQUAL(map.size(), nb_values);
1165 
1166  serializer serial;
1167  map.serialize(serial);
1168 
1169  deserializer dserial(serial.str());
1170  auto map_deserialized = decltype(map)::deserialize(dserial, true);
1171  BOOST_CHECK(map == map_deserialized);
1172 
1173  deserializer dserial2(serial.str());
1174  map_deserialized = decltype(map)::deserialize(dserial2, false);
1175  BOOST_CHECK(map_deserialized == map);
1176 
1177  // Deserializing a map with StoreHash=false from a map serialized with
1178  // StoreHash=true with hash_compatible=true should throw an exception.
1179  deserializer dserial3(serial.str());
1181  dserial3, true)),
1182  std::runtime_error);
1183 }
1184 
1185 BOOST_AUTO_TEST_CASE(test_serialize_desearialize_with_different_hash) {
1186  // insert x values; serialize map; deserialize in new map which has a
1187  // different hash; check equal
1188  struct hash_str_diff {
1189  std::size_t operator()(const std::string& str) const {
1190  return std::hash<std::string>()(str) + 123;
1191  }
1192  };
1193 
1194  const std::size_t nb_values = 1000;
1195 
1197  for (std::size_t i = 0; i < nb_values; i++) {
1198  map.insert(
1199  {utils::get_key<std::string>(i), utils::get_value<move_only_test>(i)});
1200  }
1201  BOOST_CHECK_EQUAL(map.size(), nb_values);
1202 
1203  serializer serial;
1204  map.serialize(serial);
1205 
1206  deserializer dserial(serial.str());
1207  auto map_deserialized =
1209  dserial, false);
1210 
1211  BOOST_CHECK_EQUAL(map_deserialized.size(), map.size());
1212  for (const auto& val : map) {
1213  BOOST_CHECK(map_deserialized.find(val.first) != map_deserialized.end());
1214  }
1215 }
1216 
1220 BOOST_AUTO_TEST_CASE(test_key_equal) {
1221  // Use a KeyEqual and Hash where any odd unsigned number 'x' is equal to
1222  // 'x-1'. Make sure that KeyEqual is called (and not ==).
1223  struct hash {
1224  std::size_t operator()(std::uint64_t v) const {
1225  if (v % 2u == 1u) {
1226  return std::hash<std::uint64_t>()(v - 1);
1227  } else {
1228  return std::hash<std::uint64_t>()(v);
1229  }
1230  }
1231  };
1232 
1233  struct key_equal {
1234  bool operator()(std::uint64_t lhs, std::uint64_t rhs) const {
1235  if (lhs % 2u == 1u) {
1236  lhs--;
1237  }
1238 
1239  if (rhs % 2u == 1u) {
1240  rhs--;
1241  }
1242 
1243  return lhs == rhs;
1244  }
1245  };
1246 
1248  BOOST_CHECK(map.insert({2, 10}).second);
1249  BOOST_CHECK_EQUAL(map.at(2), 10);
1250  BOOST_CHECK_EQUAL(map.at(3), 10);
1251  BOOST_CHECK(!map.insert({3, 10}).second);
1252 
1253  BOOST_CHECK_EQUAL(map.size(), 1);
1254 }
1255 
1259 BOOST_AUTO_TEST_CASE(test_heterogeneous_lookups) {
1260  struct hash_ptr {
1261  std::size_t operator()(const std::unique_ptr<int>& p) const {
1262  return std::hash<std::uintptr_t>()(
1263  reinterpret_cast<std::uintptr_t>(p.get()));
1264  }
1265 
1266  std::size_t operator()(std::uintptr_t p) const {
1267  return std::hash<std::uintptr_t>()(p);
1268  }
1269 
1270  std::size_t operator()(const int* const& p) const {
1271  return std::hash<std::uintptr_t>()(reinterpret_cast<std::uintptr_t>(p));
1272  }
1273  };
1274 
1275  struct equal_to_ptr {
1276  using is_transparent = std::true_type;
1277 
1278  bool operator()(const std::unique_ptr<int>& p1,
1279  const std::unique_ptr<int>& p2) const {
1280  return p1 == p2;
1281  }
1282 
1283  bool operator()(const std::unique_ptr<int>& p1, std::uintptr_t p2) const {
1284  return reinterpret_cast<std::uintptr_t>(p1.get()) == p2;
1285  }
1286 
1287  bool operator()(std::uintptr_t p1, const std::unique_ptr<int>& p2) const {
1288  return p1 == reinterpret_cast<std::uintptr_t>(p2.get());
1289  }
1290 
1291  bool operator()(const std::unique_ptr<int>& p1,
1292  const int* const& p2) const {
1293  return p1.get() == p2;
1294  }
1295 
1296  bool operator()(const int* const& p1,
1297  const std::unique_ptr<int>& p2) const {
1298  return p1 == p2.get();
1299  }
1300  };
1301 
1302  std::unique_ptr<int> ptr1(new int(1));
1303  std::unique_ptr<int> ptr2(new int(2));
1304  std::unique_ptr<int> ptr3(new int(3));
1305  int other = -1;
1306 
1307  const std::uintptr_t addr1 = reinterpret_cast<std::uintptr_t>(ptr1.get());
1308  const int* const addr2 = ptr2.get();
1309  const int* const addr_unknown = &other;
1310 
1311  tsl::robin_map<std::unique_ptr<int>, int, hash_ptr, equal_to_ptr> map;
1312  map.insert({std::move(ptr1), 4});
1313  map.insert({std::move(ptr2), 5});
1314  map.insert({std::move(ptr3), 6});
1315 
1316  BOOST_CHECK_EQUAL(map.size(), 3);
1317 
1318  BOOST_CHECK_EQUAL(map.at(addr1), 4);
1319  BOOST_CHECK_EQUAL(map.at(addr2), 5);
1320  TSL_RH_CHECK_THROW(map.at(addr_unknown), std::out_of_range);
1321 
1322  BOOST_REQUIRE(map.find(addr1) != map.end());
1323  BOOST_CHECK_EQUAL(*map.find(addr1)->first, 1);
1324 
1325  BOOST_REQUIRE(map.find(addr2) != map.end());
1326  BOOST_CHECK_EQUAL(*map.find(addr2)->first, 2);
1327 
1328  BOOST_CHECK(map.find(addr_unknown) == map.end());
1329 
1330  BOOST_CHECK_EQUAL(map.count(addr1), 1);
1331  BOOST_CHECK_EQUAL(map.count(addr2), 1);
1332  BOOST_CHECK_EQUAL(map.count(addr_unknown), 0);
1333 
1334  BOOST_CHECK_EQUAL(map.erase(addr1), 1);
1335  BOOST_CHECK_EQUAL(map.erase(addr2), 1);
1336  BOOST_CHECK_EQUAL(map.erase(addr_unknown), 0);
1337 
1338  BOOST_CHECK_EQUAL(map.size(), 1);
1339 }
1340 
1344 BOOST_AUTO_TEST_CASE(test_empty_map) {
1346 
1347  BOOST_CHECK_EQUAL(map.bucket_count(), 0);
1348  BOOST_CHECK_EQUAL(map.size(), 0);
1349  BOOST_CHECK_EQUAL(map.load_factor(), 0);
1350  BOOST_CHECK(map.empty());
1351 
1352  BOOST_CHECK(map.begin() == map.end());
1353  BOOST_CHECK(map.begin() == map.cend());
1354  BOOST_CHECK(map.cbegin() == map.cend());
1355 
1356  BOOST_CHECK(map.find("") == map.end());
1357  BOOST_CHECK(map.find("test") == map.end());
1358 
1359  BOOST_CHECK_EQUAL(map.count(""), 0);
1360  BOOST_CHECK_EQUAL(map.count("test"), 0);
1361 
1362  BOOST_CHECK(!map.contains(""));
1363  BOOST_CHECK(!map.contains("test"));
1364 
1365  TSL_RH_CHECK_THROW(map.at(""), std::out_of_range);
1366  TSL_RH_CHECK_THROW(map.at("test"), std::out_of_range);
1367 
1368  auto range = map.equal_range("test");
1369  BOOST_CHECK(range.first == range.second);
1370 
1371  BOOST_CHECK_EQUAL(map.erase("test"), 0);
1372  BOOST_CHECK(map.erase(map.begin(), map.end()) == map.end());
1373 
1374  BOOST_CHECK_EQUAL(map["new value"], int{});
1375 }
1376 
1380 BOOST_AUTO_TEST_CASE(test_precalculated_hash) {
1382  {1, -1}, {2, -2}, {3, -3}, {4, -4}, {5, -5}, {6, -6}};
1383  const tsl::robin_map<int, int, identity_hash<int>> map_const = map;
1384 
1388  BOOST_REQUIRE(map.find(3, map.hash_function()(3)) != map.end());
1389  BOOST_CHECK_EQUAL(map.find(3, map.hash_function()(3))->second, -3);
1390 
1391  BOOST_REQUIRE(map_const.find(3, map_const.hash_function()(3)) !=
1392  map_const.end());
1393  BOOST_CHECK_EQUAL(map_const.find(3, map_const.hash_function()(3))->second,
1394  -3);
1395 
1396  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
1397  BOOST_CHECK(map.find(3, map.hash_function()(2)) == map.end());
1398 
1402  BOOST_CHECK_EQUAL(map.at(3, map.hash_function()(3)), -3);
1403  BOOST_CHECK_EQUAL(map_const.at(3, map_const.hash_function()(3)), -3);
1404 
1405  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
1406  TSL_RH_CHECK_THROW(map.at(3, map.hash_function()(2)), std::out_of_range);
1407 
1411  BOOST_CHECK(map.contains(3, map.hash_function()(3)));
1412  BOOST_CHECK(map_const.contains(3, map_const.hash_function()(3)));
1413 
1414  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
1415  BOOST_CHECK(!map.contains(3, map.hash_function()(2)));
1416 
1420  BOOST_CHECK_EQUAL(map.count(3, map.hash_function()(3)), 1);
1421  BOOST_CHECK_EQUAL(map_const.count(3, map_const.hash_function()(3)), 1);
1422 
1423  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
1424  BOOST_CHECK_EQUAL(map.count(3, map.hash_function()(2)), 0);
1425 
1429  auto it_range = map.equal_range(3, map.hash_function()(3));
1430  BOOST_REQUIRE_EQUAL(std::distance(it_range.first, it_range.second), 1);
1431  BOOST_CHECK_EQUAL(it_range.first->second, -3);
1432 
1433  auto it_range_const = map_const.equal_range(3, map_const.hash_function()(3));
1434  BOOST_REQUIRE_EQUAL(
1435  std::distance(it_range_const.first, it_range_const.second), 1);
1436  BOOST_CHECK_EQUAL(it_range_const.first->second, -3);
1437 
1438  it_range = map.equal_range(3, map.hash_function()(2));
1439  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(3));
1440  BOOST_CHECK_EQUAL(std::distance(it_range.first, it_range.second), 0);
1441 
1445  BOOST_CHECK_EQUAL(map.erase(3, map.hash_function()(3)), 1);
1446 
1447  BOOST_REQUIRE_NE(map.hash_function()(2), map.hash_function()(4));
1448  BOOST_CHECK_EQUAL(map.erase(4, map.hash_function()(2)), 0);
1449 }
1450 
1451 BOOST_AUTO_TEST_CASE(test_erase_fast) {
1452  using Map = tsl::robin_map<int, int>;
1453  Map map;
1454  map.emplace(4, 5);
1455  auto it = map.find(4);
1456  BOOST_CHECK(it != map.end());
1457  map.erase_fast(it);
1458  BOOST_CHECK(map.size() == 0);
1459 }
1460 
1461 
1462 BOOST_AUTO_TEST_SUITE_END()
tsl::robin_map::min_load_factor
float min_load_factor() const
Definition: robin_map.h:688
tsl::rh::prime_growth_policy
Definition: robin_growth_policy.h:369
tsl::robin_map::emplace
std::pair< iterator, bool > emplace(Args &&... args)
Definition: robin_map.h:298
tsl::robin_map::serialize
void serialize(Serializer &serializer) const
Definition: robin_map.h:737
deserialize
void deserialize(Stream &stream, boost::array< T, N > &t)
tsl::robin_map::end
iterator end() noexcept
Definition: robin_map.h:217
tsl::robin_map::hash_function
hasher hash_function() const
Definition: robin_map.h:709
std::swap
void swap(linb::any &lhs, linb::any &rhs) noexcept
Definition: any.hpp:452
robin_map.h
kitti-run-seq.f
string f
Definition: kitti-run-seq.py:12
tsl::robin_map::begin
iterator begin() noexcept
Definition: robin_map.h:213
tsl::robin_map::contains
bool contains(const Key &key) const
Definition: robin_map.h:566
self_reference_member_test
Definition: robin-map/tests/utils.h:70
tsl::robin_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: robin_map.h:233
testing::internal::true_type
bool_constant< true > true_type
Definition: gtest.h:2725
serializer
Definition: robin-map/tests/utils.h:349
tsl::robin_map::insert_or_assign
std::pair< iterator, bool > insert_or_assign(const key_type &k, M &&obj)
Definition: robin_map.h:271
tsl::robin_map::bucket_count
size_type bucket_count() const
Definition: robin_map.h:680
tsl::robin_map::empty
bool empty() const noexcept
Definition: robin_map.h:224
std::allocator
tsl::robin_map::equal_range
std::pair< iterator, iterator > equal_range(const Key &key)
Definition: robin_map.h:603
testing::internal::string
::std::string string
Definition: gtest.h:1979
move_only_test
Definition: robin-map/tests/utils.h:128
test_types
boost::mpl::list< tsl::rh::power_of_two_growth_policy< 2 >, tsl::rh::power_of_two_growth_policy< 4 >, tsl::rh::prime_growth_policy, tsl::rh::mod_growth_policy<>, tsl::rh::mod_growth_policy< std::ratio< 7, 2 > >> test_types
Definition: policy_tests.cpp:41
tsl::robin_map::try_emplace
std::pair< iterator, bool > try_emplace(const key_type &k, Args &&... args)
Definition: robin_map.h:315
utils.h
tsl::robin_map::at
T & at(const Key &key)
Definition: robin_map.h:390
tsl::robin_map::find
iterator find(const Key &key)
Definition: robin_map.h:496
tsl::robin_map::load_factor
float load_factor() const
Definition: robin_map.h:686
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(test_range_insert)
Definition: robin_map_tests.cpp:118
tsl::robin_map::iterator
typename ht::iterator iterator
Definition: robin_map.h:141
tsl::robin_map::cbegin
const_iterator cbegin() const noexcept
Definition: robin_map.h:215
TSL_RH_CHECK_THROW
#define TSL_RH_CHECK_THROW(S, E)
Definition: robin-map/tests/utils.h:41
tsl::robin_map::count
size_type count(const Key &key) const
Definition: robin_map.h:459
tsl::rh::power_of_two_growth_policy
Definition: robin_growth_policy.h:95
TSL_RH_CHECK_THROW_EITHER
#define TSL_RH_CHECK_THROW_EITHER(S, E1, E2)
Definition: robin-map/tests/utils.h:42
tsl::robin_map::deserialize
static robin_map deserialize(Deserializer &deserializer, bool hash_compatible=false)
Definition: robin_map.h:768
mod_hash
Definition: robin-map/tests/utils.h:62
tsl::robin_map
Definition: robin_map.h:91
BOOST_AUTO_TEST_CASE_TEMPLATE
BOOST_AUTO_TEST_CASE_TEMPLATE(test_insert, HMap, test_types)
Definition: robin_map_tests.cpp:79
serializer::str
std::string str() const
Definition: robin-map/tests/utils.h:358
tsl::rh::mod_growth_policy
Definition: robin_growth_policy.h:190
tsl::robin_map::size
size_type size() const noexcept
Definition: robin_map.h:225
deserializer
Definition: robin-map/tests/utils.h:387
tsl::robin_map::erase
iterator erase(iterator pos)
Definition: robin_map.h:335
tsl::robin_map::const_iterator
typename ht::const_iterator const_iterator
Definition: robin_map.h:142
tsl::robin_map::rehash
void rehash(size_type count_)
Definition: robin_map.h:703
tsl::robin_map::max_load_factor
float max_load_factor() const
Definition: robin_map.h:689
tsl::robin_map::cend
const_iterator cend() const noexcept
Definition: robin_map.h:219


mp2p_icp
Author(s): Jose-Luis Blanco-Claraco
autogenerated on Wed Jun 26 2024 02:47:09