1 2 // Copyright 2006-2009 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 // clang-format off 7 #include "../helpers/prefix.hpp" 8 #include <boost/unordered_set.hpp> 9 #include <boost/unordered_map.hpp> 10 #include "../helpers/postfix.hpp" 11 // clang-format on 12 13 #include <boost/config.hpp> 14 #include <algorithm> 15 #include <iterator> 16 #include "../helpers/test.hpp" 17 #include "../objects/test.hpp" 18 #include "../objects/cxx11_allocator.hpp" 19 #include "../helpers/random_values.hpp" 20 #include "../helpers/tracker.hpp" 21 #include "../helpers/invariants.hpp" 22 23 #if defined(BOOST_MSVC) 24 #pragma warning(disable : 4127) // conditional expression is constant 25 #endif 26 27 namespace swap_tests { 28 29 test::seed_t initialize_seed(783472); 30 swap_test_impl(X & x1,X & x2)31 template <class X> void swap_test_impl(X& x1, X& x2) 32 { 33 test::ordered<X> tracker1 = test::create_ordered(x1); 34 test::ordered<X> tracker2 = test::create_ordered(x2); 35 tracker1.insert_range(x1.begin(), x1.end()); 36 tracker2.insert_range(x2.begin(), x2.end()); 37 x1.swap(x2); 38 tracker1.compare(x2); 39 tracker2.compare(x1); 40 } 41 swap_tests1(X *,test::random_generator generator)42 template <class X> void swap_tests1(X*, test::random_generator generator) 43 { 44 { 45 test::check_instances check_; 46 47 X x; 48 swap_test_impl(x, x); 49 } 50 51 { 52 test::check_instances check_; 53 54 X x, y; 55 swap_test_impl(x, y); 56 } 57 58 { 59 test::check_instances check_; 60 61 test::random_values<X> v(1000, generator); 62 X x, y(v.begin(), v.end()); 63 swap_test_impl(x, y); 64 swap_test_impl(x, y); 65 } 66 67 { 68 test::check_instances check_; 69 70 test::random_values<X> vx(1000, generator), vy(1000, generator); 71 X x(vx.begin(), vx.end()), y(vy.begin(), vy.end()); 72 swap_test_impl(x, y); 73 swap_test_impl(x, y); 74 } 75 } 76 swap_tests2(X * ptr,test::random_generator generator)77 template <class X> void swap_tests2(X* ptr, test::random_generator generator) 78 { 79 swap_tests1(ptr, generator); 80 81 typedef typename X::hasher hasher; 82 typedef typename X::key_equal key_equal; 83 typedef typename X::allocator_type allocator_type; 84 85 { 86 test::check_instances check_; 87 88 X x(0, hasher(1), key_equal(1)); 89 X y(0, hasher(2), key_equal(2)); 90 swap_test_impl(x, y); 91 } 92 93 { 94 test::check_instances check_; 95 96 test::random_values<X> v(1000, generator); 97 X x(v.begin(), v.end(), 0, hasher(1), key_equal(1)); 98 X y(0, hasher(2), key_equal(2)); 99 swap_test_impl(x, y); 100 } 101 102 { 103 test::check_instances check_; 104 105 test::random_values<X> vx(100, generator), vy(50, generator); 106 X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1)); 107 X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2)); 108 swap_test_impl(x, y); 109 swap_test_impl(x, y); 110 } 111 112 { 113 test::force_equal_allocator force_(!allocator_type::is_propagate_on_swap); 114 test::check_instances check_; 115 116 test::random_values<X> vx(50, generator), vy(100, generator); 117 X x(vx.begin(), vx.end(), 0, hasher(), key_equal(), allocator_type(1)); 118 X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2)); 119 120 if (allocator_type::is_propagate_on_swap || 121 x.get_allocator() == y.get_allocator()) { 122 swap_test_impl(x, y); 123 } 124 } 125 126 { 127 test::force_equal_allocator force_(!allocator_type::is_propagate_on_swap); 128 test::check_instances check_; 129 130 test::random_values<X> vx(100, generator), vy(100, generator); 131 X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1), allocator_type(1)); 132 X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2), allocator_type(2)); 133 134 if (allocator_type::is_propagate_on_swap || 135 x.get_allocator() == y.get_allocator()) { 136 swap_test_impl(x, y); 137 swap_test_impl(x, y); 138 } 139 } 140 } 141 142 boost::unordered_map<test::object, test::object, test::hash, test::equal_to, 143 std::allocator<test::object> >* test_map_std_alloc; 144 145 boost::unordered_set<test::object, test::hash, test::equal_to, 146 test::allocator1<test::object> >* test_set; 147 boost::unordered_multiset<test::object, test::hash, test::equal_to, 148 test::allocator2<test::object> >* test_multiset; 149 boost::unordered_map<test::object, test::object, test::hash, test::equal_to, 150 test::allocator1<test::object> >* test_map; 151 boost::unordered_multimap<test::object, test::object, test::hash, 152 test::equal_to, test::allocator2<test::object> >* test_multimap; 153 154 boost::unordered_set<test::object, test::hash, test::equal_to, 155 test::cxx11_allocator<test::object, test::propagate_swap> >* 156 test_set_prop_swap; 157 boost::unordered_multiset<test::object, test::hash, test::equal_to, 158 test::cxx11_allocator<test::object, test::propagate_swap> >* 159 test_multiset_prop_swap; 160 boost::unordered_map<test::object, test::object, test::hash, test::equal_to, 161 test::cxx11_allocator<test::object, test::propagate_swap> >* 162 test_map_prop_swap; 163 boost::unordered_multimap<test::object, test::object, test::hash, 164 test::equal_to, test::cxx11_allocator<test::object, test::propagate_swap> >* 165 test_multimap_prop_swap; 166 167 boost::unordered_set<test::object, test::hash, test::equal_to, 168 test::cxx11_allocator<test::object, test::no_propagate_swap> >* 169 test_set_no_prop_swap; 170 boost::unordered_multiset<test::object, test::hash, test::equal_to, 171 test::cxx11_allocator<test::object, test::no_propagate_swap> >* 172 test_multiset_no_prop_swap; 173 boost::unordered_map<test::object, test::object, test::hash, test::equal_to, 174 test::cxx11_allocator<test::object, test::no_propagate_swap> >* 175 test_map_no_prop_swap; 176 boost::unordered_multimap<test::object, test::object, test::hash, 177 test::equal_to, 178 test::cxx11_allocator<test::object, test::no_propagate_swap> >* 179 test_multimap_no_prop_swap; 180 is_propagate(T *)181 template <typename T> bool is_propagate(T*) 182 { 183 return T::allocator_type::is_propagate_on_swap; 184 } 185 186 using test::default_generator; 187 using test::generate_collisions; 188 using test::limited_range; 189 UNORDERED_AUTO_TEST(check_traits)190 UNORDERED_AUTO_TEST (check_traits) { 191 BOOST_TEST(!is_propagate(test_set)); 192 BOOST_TEST(is_propagate(test_set_prop_swap)); 193 BOOST_TEST(!is_propagate(test_set_no_prop_swap)); 194 } 195 196 UNORDERED_TEST( 197 swap_tests1, ((test_map_std_alloc)(test_set)(test_multiset)(test_map)( 198 test_multimap)(test_set_prop_swap)(test_multiset_prop_swap)( 199 test_map_prop_swap)(test_multimap_prop_swap)( 200 test_set_no_prop_swap)(test_multiset_no_prop_swap)( 201 test_map_no_prop_swap)(test_multimap_no_prop_swap))( 202 (default_generator)(generate_collisions)(limited_range))) 203 204 UNORDERED_TEST(swap_tests2, 205 ((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_swap)( 206 test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap)( 207 test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)( 208 test_multimap_no_prop_swap))( 209 (default_generator)(generate_collisions)(limited_range))) 210 } 211 RUN_TESTS() 212