2 // Copyright 2008-2009 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
6 #include "../helpers/prefix.hpp"
7 #include <boost/unordered_set.hpp>
8 #include <boost/unordered_map.hpp>
9 #include "../helpers/postfix.hpp"
11 #include "../helpers/test.hpp"
12 #include "../objects/test.hpp"
13 #include "../objects/cxx11_allocator.hpp"
14 #include "../helpers/random_values.hpp"
15 #include "../helpers/tracker.hpp"
16 #include "../helpers/equivalent.hpp"
17 #include "../helpers/invariants.hpp"
19 #if defined(BOOST_MSVC)
20 #pragma warning(disable:4127) // conditional expression is constant
25 test::seed_t initialize_seed(98624);
26 #if defined(BOOST_UNORDERED_USE_MOVE) || !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
27 #define BOOST_UNORDERED_TEST_MOVING 1
29 #define BOOST_UNORDERED_TEST_MOVING 0
38 T create(test::random_values<T> const& v,
39 test::object_count& count) {
40 T x(v.begin(), v.end());
41 count = test::global_object_count;
46 T create(test::random_values<T> const& v,
47 test::object_count& count,
48 BOOST_DEDUCED_TYPENAME T::hasher hf,
49 BOOST_DEDUCED_TYPENAME T::key_equal eq,
50 BOOST_DEDUCED_TYPENAME T::allocator_type al,
53 x.max_load_factor(mlf);
54 x.insert(v.begin(), v.end());
55 count = test::global_object_count;
60 void move_construct_tests1(T* ptr, test::random_generator const& generator)
62 BOOST_DEDUCED_TYPENAME T::hasher hf;
63 BOOST_DEDUCED_TYPENAME T::key_equal eq;
64 BOOST_DEDUCED_TYPENAME T::allocator_type al;
67 test::check_instances check_;
70 BOOST_TEST(y.empty());
71 BOOST_TEST(test::equivalent(y.hash_function(), hf));
72 BOOST_TEST(test::equivalent(y.key_eq(), eq));
73 BOOST_TEST(test::equivalent(y.get_allocator(), al));
74 BOOST_TEST(y.max_load_factor() == 1.0);
75 test::check_equivalent_keys(y);
79 test::check_instances check_;
81 test::random_values<T> v(1000, generator);
82 test::object_count count;
83 T y(create(v, count));
84 #if defined(BOOST_HAS_NRVO)
85 BOOST_TEST(count == test::global_object_count);
87 test::check_container(y, v);
88 test::check_equivalent_keys(y);
93 void move_assign_tests1(T*, test::random_generator const& generator)
96 test::check_instances check_;
98 test::random_values<T> v(500, generator);
99 test::object_count count;
101 y = create(v, count);
102 #if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
103 BOOST_TEST(count == test::global_object_count);
105 test::check_container(y, v);
106 test::check_equivalent_keys(y);
111 void move_construct_tests2(T*, test::random_generator const& generator)
113 BOOST_DEDUCED_TYPENAME T::hasher hf(1);
114 BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
115 BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
116 BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
118 test::object_count count;
121 test::check_instances check_;
123 test::random_values<T> v(500, generator);
124 T y(create(v, count, hf, eq, al, 0.5));
125 #if defined(BOOST_HAS_NRVO)
126 BOOST_TEST(count == test::global_object_count);
128 test::check_container(y, v);
129 BOOST_TEST(test::equivalent(y.hash_function(), hf));
130 BOOST_TEST(test::equivalent(y.key_eq(), eq));
131 BOOST_TEST(test::equivalent(y.get_allocator(), al));
132 BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
133 test::check_equivalent_keys(y);
137 test::check_instances check_;
139 // TODO: To do this correctly requires the fancy new allocator
141 test::random_values<T> v(500, generator);
142 T y(create(v, count, hf, eq, al, 2.0), al2);
143 BOOST_TEST(count != test::global_object_count);
144 test::check_container(y, v);
145 BOOST_TEST(test::equivalent(y.hash_function(), hf));
146 BOOST_TEST(test::equivalent(y.key_eq(), eq));
147 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
148 BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
149 test::check_equivalent_keys(y);
153 test::check_instances check_;
155 test::random_values<T> v(25, generator);
156 T y(create(v, count, hf, eq, al, 1.0), al);
157 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
158 BOOST_TEST(count == test::global_object_count);
159 #elif defined(BOOST_HAS_NRVO)
161 static_cast<std::size_t>(test::global_object_count.constructions
162 - count.constructions) <=
163 (test::is_set<T>::value ? 1 : 2) *
164 (test::has_unique_keys<T>::value ? 25 : v.size()));
165 BOOST_TEST(count.instances == test::global_object_count.instances);
168 static_cast<std::size_t>(test::global_object_count.constructions
169 - count.constructions) <=
170 (test::is_set<T>::value ? 2 : 4) *
171 (test::has_unique_keys<T>::value ? 25 : v.size()));
172 BOOST_TEST(count.instances == test::global_object_count.instances);
174 test::check_container(y, v);
175 BOOST_TEST(test::equivalent(y.hash_function(), hf));
176 BOOST_TEST(test::equivalent(y.key_eq(), eq));
177 BOOST_TEST(test::equivalent(y.get_allocator(), al));
178 BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
179 test::check_equivalent_keys(y);
184 void move_assign_tests2(T*, test::random_generator const& generator)
186 BOOST_DEDUCED_TYPENAME T::hasher hf(1);
187 BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
188 BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
189 BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
190 typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
193 test::random_values<T> v(500, generator);
194 test::random_values<T> v2(0, generator);
195 T y(v.begin(), v.end(), 0, hf, eq, al1);
196 test::object_count count;
197 y = create(v2, count, hf, eq, al2, 2.0);
198 BOOST_TEST(y.empty());
199 test::check_container(y, v2);
200 test::check_equivalent_keys(y);
201 BOOST_TEST(y.max_load_factor() == 2.0);
203 #if defined(BOOST_HAS_NRVO)
204 if (BOOST_UNORDERED_TEST_MOVING ?
205 (bool) allocator_type::is_propagate_on_move :
206 (bool) allocator_type::is_propagate_on_assign)
208 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
211 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
217 test::random_values<T> v(500, generator);
218 test::object_count count;
220 y = create(v, count, hf, eq, al2, 0.5);
221 #if defined(BOOST_HAS_NRVO)
222 if (BOOST_UNORDERED_TEST_MOVING &&
223 allocator_type::is_propagate_on_move)
225 BOOST_TEST(count == test::global_object_count);
228 test::check_container(y, v);
229 test::check_equivalent_keys(y);
230 BOOST_TEST(y.max_load_factor() == 0.5);
232 #if defined(BOOST_HAS_NRVO)
233 if (BOOST_UNORDERED_TEST_MOVING ?
234 (bool) allocator_type::is_propagate_on_move :
235 (bool) allocator_type::is_propagate_on_assign)
237 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
240 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
246 test::check_instances check_;
248 test::random_values<T> v(500, generator);
252 x.max_load_factor(0.25);
253 x.insert(v.begin(), v.end());
255 test::object_count count = test::global_object_count;
257 if (BOOST_UNORDERED_TEST_MOVING &&
258 allocator_type::is_propagate_on_move)
260 BOOST_TEST(count == test::global_object_count);
262 test::check_container(y, v);
263 test::check_equivalent_keys(y);
264 BOOST_TEST(y.max_load_factor() == 0.25);
266 if (BOOST_UNORDERED_TEST_MOVING ?
267 (bool) allocator_type::is_propagate_on_move :
268 (bool) allocator_type::is_propagate_on_assign)
270 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
273 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
278 test::check_instances check_;
280 test::random_values<T> v1(1000, generator);
281 test::random_values<T> v2(200, generator);
284 x.max_load_factor(0.5);
285 x.insert(v2.begin(), v2.end());
287 test::object_count count1 = test::global_object_count;
289 T y(v1.begin(), v1.end(), 0, hf, eq, al1);
292 test::object_count count2 = test::global_object_count;
294 if (BOOST_UNORDERED_TEST_MOVING &&
295 allocator_type::is_propagate_on_move)
297 BOOST_TEST(count1.instances ==
298 test::global_object_count.instances);
299 BOOST_TEST(count2.constructions ==
300 test::global_object_count.constructions);
303 test::check_container(y, v2);
304 test::check_equivalent_keys(y);
305 BOOST_TEST(y.max_load_factor() == 0.5);
307 if (BOOST_UNORDERED_TEST_MOVING ?
308 (bool) allocator_type::is_propagate_on_move :
309 (bool) allocator_type::is_propagate_on_assign)
311 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
314 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
319 boost::unordered_map<test::object, test::object,
320 test::hash, test::equal_to,
321 std::allocator<test::object> >* test_map_std_alloc;
323 boost::unordered_set<test::object,
324 test::hash, test::equal_to,
325 test::allocator2<test::object> >* test_set;
326 boost::unordered_multiset<test::object,
327 test::hash, test::equal_to,
328 test::allocator1<test::object> >* test_multiset;
329 boost::unordered_map<test::object, test::object,
330 test::hash, test::equal_to,
331 test::allocator1<test::object> >* test_map;
332 boost::unordered_multimap<test::object, test::object,
333 test::hash, test::equal_to,
334 test::allocator2<test::object> >* test_multimap;
336 boost::unordered_set<test::object,
337 test::hash, test::equal_to,
338 test::cxx11_allocator<test::object, test::propagate_move> >*
340 boost::unordered_multiset<test::object,
341 test::hash, test::equal_to,
342 test::cxx11_allocator<test::object, test::propagate_move> >*
343 test_multiset_prop_move;
344 boost::unordered_map<test::object, test::object,
345 test::hash, test::equal_to,
346 test::cxx11_allocator<test::object, test::propagate_move> >*
348 boost::unordered_multimap<test::object, test::object,
349 test::hash, test::equal_to,
350 test::cxx11_allocator<test::object, test::propagate_move> >*
351 test_multimap_prop_move;
353 boost::unordered_set<test::object,
354 test::hash, test::equal_to,
355 test::cxx11_allocator<test::object, test::no_propagate_move> >*
356 test_set_no_prop_move;
357 boost::unordered_multiset<test::object,
358 test::hash, test::equal_to,
359 test::cxx11_allocator<test::object, test::no_propagate_move> >*
360 test_multiset_no_prop_move;
361 boost::unordered_map<test::object, test::object,
362 test::hash, test::equal_to,
363 test::cxx11_allocator<test::object, test::no_propagate_move> >*
364 test_map_no_prop_move;
365 boost::unordered_multimap<test::object, test::object,
366 test::hash, test::equal_to,
367 test::cxx11_allocator<test::object, test::no_propagate_move> >*
368 test_multimap_no_prop_move;
370 using test::default_generator;
371 using test::generate_collisions;
373 UNORDERED_TEST(move_construct_tests1, (
375 (test_set)(test_multiset)(test_map)(test_multimap)
376 (test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
377 (test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
379 ((default_generator)(generate_collisions))
381 UNORDERED_TEST(move_assign_tests1, (
383 (test_set)(test_multiset)(test_map)(test_multimap)
384 (test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
385 (test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
387 ((default_generator)(generate_collisions))
389 UNORDERED_TEST(move_construct_tests2, (
390 (test_set)(test_multiset)(test_map)(test_multimap)
391 (test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
392 (test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
394 ((default_generator)(generate_collisions))
396 UNORDERED_TEST(move_assign_tests2, (
397 (test_set)(test_multiset)(test_map)(test_multimap)
398 (test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
399 (test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
401 ((default_generator)(generate_collisions))