1 
2 // Copyright 2017-2018 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include "../helpers/exception_test.hpp"
7 #include "../helpers/invariants.hpp"
8 #include "../helpers/metafunctions.hpp"
9 #include "../helpers/random_values.hpp"
10 #include "./containers.hpp"
11 
merge_exception_test(T1 x,T2 y)12 template <typename T1, typename T2> void merge_exception_test(T1 x, T2 y)
13 {
14   std::size_t size = x.size() + y.size();
15 
16   try {
17     ENABLE_EXCEPTIONS;
18     x.merge(y);
19   } catch (...) {
20     test::check_equivalent_keys(x);
21     test::check_equivalent_keys(y);
22     throw;
23   }
24 
25   // Not a full check, just want to make sure the merge completed.
26   BOOST_TEST(size == x.size() + y.size());
27   if (y.size()) {
28     BOOST_TEST(test::has_unique_keys<T1>::value);
29     for (typename T2::iterator it = y.begin(); it != y.end(); ++it) {
30       BOOST_TEST(x.find(test::get_key<T2>(*it)) != x.end());
31     }
32   }
33   test::check_equivalent_keys(x);
34   test::check_equivalent_keys(y);
35 }
36 
37 template <typename T1, typename T2>
merge_exception_test(T1 const *,T2 const *,std::size_t count12,int tag12,test::random_generator gen1,test::random_generator gen2)38 void merge_exception_test(T1 const*, T2 const*, std::size_t count12, int tag12,
39   test::random_generator gen1, test::random_generator gen2)
40 {
41   std::size_t count1 = count12 / 256;
42   std::size_t count2 = count12 % 256;
43   int tag1 = tag12 / 256;
44   int tag2 = tag12 % 256;
45   test::random_values<T1> v1(count1, gen1);
46   test::random_values<T2> v2(count2, gen2);
47   T1 x(v1.begin(), v1.end(), 0, test::exception::hash(tag1),
48     test::exception::equal_to(tag1));
49   T2 y(v2.begin(), v2.end(), 0, test::exception::hash(tag2),
50     test::exception::equal_to(tag2));
51 
52   EXCEPTION_LOOP(merge_exception_test(x, y))
53 }
54 
55 boost::unordered_set<test::exception::object, test::exception::hash,
56   test::exception::equal_to,
57   test::exception::allocator<test::exception::object> >* test_set_;
58 boost::unordered_multiset<test::exception::object, test::exception::hash,
59   test::exception::equal_to,
60   test::exception::allocator<test::exception::object> >* test_multiset_;
61 boost::unordered_map<test::exception::object, test::exception::object,
62   test::exception::hash, test::exception::equal_to,
63   test::exception::allocator2<test::exception::object> >* test_map_;
64 boost::unordered_multimap<test::exception::object, test::exception::object,
65   test::exception::hash, test::exception::equal_to,
66   test::exception::allocator2<test::exception::object> >* test_multimap_;
67 
68 using test::default_generator;
69 using test::generate_collisions;
70 using test::limited_range;
71 
72 // clang-format off
73 UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
74     ((test_set_)(test_multiset_))
75     ((test_set_)(test_multiset_))
76     ((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
77     ((0x0000)(0x0001)(0x0102))
78     ((default_generator)(limited_range))
79     ((default_generator)(limited_range))
80 )
81 UNORDERED_MULTI_TEST(map_merge, merge_exception_test,
82     ((test_map_)(test_multimap_))
83     ((test_map_)(test_multimap_))
84     ((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
85     ((0x0101)(0x0200)(0x0201))
86     ((default_generator)(limited_range))
87     ((default_generator)(limited_range))
88 )
89 // Run fewer generate_collisions tests, as they're slow.
90 UNORDERED_MULTI_TEST(set_merge_collisions, merge_exception_test,
91     ((test_set_)(test_multiset_))
92     ((test_set_)(test_multiset_))
93     ((0x0a0a))
94     ((0x0202)(0x0100)(0x0201))
95     ((generate_collisions))
96     ((generate_collisions))
97 )
98 UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
99     ((test_map_)(test_multimap_))
100     ((test_map_)(test_multimap_))
101     ((0x0a0a))
102     ((0x0000)(0x0002)(0x0102))
103     ((generate_collisions))
104     ((generate_collisions))
105 )
106 // clang-format on
107 
108 RUN_TESTS_QUIET()
109