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)
7 #include "../helpers/prefix.hpp"
8 #include <boost/unordered_set.hpp>
9 #include <boost/unordered_map.hpp>
10 #include "../helpers/postfix.hpp"
13 #include "../helpers/test.hpp"
14 #include "../objects/test.hpp"
15 #include "../objects/cxx11_allocator.hpp"
16 #include "../helpers/random_values.hpp"
17 #include "../helpers/tracker.hpp"
18 #include "../helpers/equivalent.hpp"
19 #include "../helpers/invariants.hpp"
21 #if defined(BOOST_MSVC)
22 #pragma warning(disable : 4127) // conditional expression is constant
25 namespace move_tests
{
26 test::seed_t
initialize_seed(98624);
27 #if defined(BOOST_UNORDERED_USE_MOVE) || \
28 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
29 #define BOOST_UNORDERED_TEST_MOVING 1
31 #define BOOST_UNORDERED_TEST_MOVING 0
34 template <class T
> T
empty(T
*) { return T(); }
37 T
create(test::random_values
<T
> const& v
, test::object_count
& count
)
39 T
x(v
.begin(), v
.end());
40 count
= test::global_object_count
;
45 T
create(test::random_values
<T
> const& v
, test::object_count
& count
,
46 BOOST_DEDUCED_TYPENAME
T::hasher hf
, BOOST_DEDUCED_TYPENAME
T::key_equal eq
,
47 BOOST_DEDUCED_TYPENAME
T::allocator_type al
, float mlf
)
50 x
.max_load_factor(mlf
);
51 x
.insert(v
.begin(), v
.end());
52 count
= test::global_object_count
;
57 void move_construct_tests1(T
* ptr
, test::random_generator
const& generator
)
59 BOOST_DEDUCED_TYPENAME
T::hasher hf
;
60 BOOST_DEDUCED_TYPENAME
T::key_equal eq
;
61 BOOST_DEDUCED_TYPENAME
T::allocator_type al
;
64 test::check_instances check_
;
67 BOOST_TEST(y
.empty());
68 BOOST_TEST(test::equivalent(y
.hash_function(), hf
));
69 BOOST_TEST(test::equivalent(y
.key_eq(), eq
));
70 BOOST_TEST(test::equivalent(y
.get_allocator(), al
));
71 BOOST_TEST(y
.max_load_factor() == 1.0);
72 test::check_equivalent_keys(y
);
76 test::check_instances check_
;
78 test::random_values
<T
> v(1000, generator
);
79 test::object_count count
;
80 T
y(create(v
, count
));
81 #if defined(BOOST_HAS_NRVO)
82 BOOST_TEST(count
== test::global_object_count
);
84 test::check_container(y
, v
);
85 test::check_equivalent_keys(y
);
90 void move_assign_tests1(T
*, test::random_generator
const& generator
)
93 test::check_instances check_
;
95 test::random_values
<T
> v(500, generator
);
96 test::object_count count
;
99 #if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
100 BOOST_TEST(count
== test::global_object_count
);
102 test::check_container(y
, v
);
103 test::check_equivalent_keys(y
);
108 void move_construct_tests2(T
*, test::random_generator
const& generator
)
110 BOOST_DEDUCED_TYPENAME
T::hasher
hf(1);
111 BOOST_DEDUCED_TYPENAME
T::key_equal
eq(1);
112 BOOST_DEDUCED_TYPENAME
T::allocator_type
al(1);
113 BOOST_DEDUCED_TYPENAME
T::allocator_type
al2(2);
115 test::object_count count
;
118 test::check_instances check_
;
120 test::random_values
<T
> v(500, generator
);
121 T
y(create(v
, count
, hf
, eq
, al
, 0.5));
122 #if defined(BOOST_HAS_NRVO)
123 BOOST_TEST(count
== test::global_object_count
);
125 test::check_container(y
, v
);
126 BOOST_TEST(test::equivalent(y
.hash_function(), hf
));
127 BOOST_TEST(test::equivalent(y
.key_eq(), eq
));
128 BOOST_TEST(test::equivalent(y
.get_allocator(), al
));
129 BOOST_TEST(y
.max_load_factor() == 0.5); // Not necessarily required.
130 test::check_equivalent_keys(y
);
134 test::check_instances check_
;
136 // TODO: To do this correctly requires the fancy new allocator
138 test::random_values
<T
> v(500, generator
);
139 T
y(create(v
, count
, hf
, eq
, al
, 2.0), al2
);
140 BOOST_TEST(count
!= test::global_object_count
);
141 test::check_container(y
, v
);
142 BOOST_TEST(test::equivalent(y
.hash_function(), hf
));
143 BOOST_TEST(test::equivalent(y
.key_eq(), eq
));
144 BOOST_TEST(test::equivalent(y
.get_allocator(), al2
));
145 BOOST_TEST(y
.max_load_factor() == 2.0); // Not necessarily required.
146 test::check_equivalent_keys(y
);
150 test::check_instances check_
;
152 test::random_values
<T
> v(25, generator
);
153 T
y(create(v
, count
, hf
, eq
, al
, 1.0), al
);
154 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
155 BOOST_TEST(count
== test::global_object_count
);
156 #elif defined(BOOST_HAS_NRVO)
158 static_cast<std::size_t>(
159 test::global_object_count
.constructions
- count
.constructions
) <=
160 (test::is_set
<T
>::value
? 1 : 2) *
161 (test::has_unique_keys
<T
>::value
? 25 : v
.size()));
162 BOOST_TEST(count
.instances
== test::global_object_count
.instances
);
165 static_cast<std::size_t>(
166 test::global_object_count
.constructions
- count
.constructions
) <=
167 (test::is_set
<T
>::value
? 2 : 4) *
168 (test::has_unique_keys
<T
>::value
? 25 : v
.size()));
169 BOOST_TEST(count
.instances
== test::global_object_count
.instances
);
171 test::check_container(y
, v
);
172 BOOST_TEST(test::equivalent(y
.hash_function(), hf
));
173 BOOST_TEST(test::equivalent(y
.key_eq(), eq
));
174 BOOST_TEST(test::equivalent(y
.get_allocator(), al
));
175 BOOST_TEST(y
.max_load_factor() == 1.0); // Not necessarily required.
176 test::check_equivalent_keys(y
);
181 void move_assign_tests2(T
*, test::random_generator
const& generator
)
183 BOOST_DEDUCED_TYPENAME
T::hasher
hf(1);
184 BOOST_DEDUCED_TYPENAME
T::key_equal
eq(1);
185 BOOST_DEDUCED_TYPENAME
T::allocator_type
al1(1);
186 BOOST_DEDUCED_TYPENAME
T::allocator_type
al2(2);
187 typedef BOOST_DEDUCED_TYPENAME
T::allocator_type allocator_type
;
190 test::random_values
<T
> v(500, generator
);
191 test::random_values
<T
> v2(0, generator
);
192 T
y(v
.begin(), v
.end(), 0, hf
, eq
, al1
);
193 test::object_count count
;
194 y
= create(v2
, count
, hf
, eq
, al2
, 2.0);
195 BOOST_TEST(y
.empty());
196 test::check_container(y
, v2
);
197 test::check_equivalent_keys(y
);
198 BOOST_TEST(y
.max_load_factor() == 2.0);
200 #if defined(BOOST_HAS_NRVO)
201 if (BOOST_UNORDERED_TEST_MOVING
202 ? (bool)allocator_type::is_propagate_on_move
203 : (bool)allocator_type::is_propagate_on_assign
) {
204 BOOST_TEST(test::equivalent(y
.get_allocator(), al2
));
206 BOOST_TEST(test::equivalent(y
.get_allocator(), al1
));
212 test::random_values
<T
> v(500, generator
);
213 test::object_count count
;
215 y
= create(v
, count
, hf
, eq
, al2
, 0.5);
216 #if defined(BOOST_HAS_NRVO)
217 if (BOOST_UNORDERED_TEST_MOVING
&& allocator_type::is_propagate_on_move
) {
218 BOOST_TEST(count
== test::global_object_count
);
221 test::check_container(y
, v
);
222 test::check_equivalent_keys(y
);
223 BOOST_TEST(y
.max_load_factor() == 0.5);
225 #if defined(BOOST_HAS_NRVO)
226 if (BOOST_UNORDERED_TEST_MOVING
227 ? (bool)allocator_type::is_propagate_on_move
228 : (bool)allocator_type::is_propagate_on_assign
) {
229 BOOST_TEST(test::equivalent(y
.get_allocator(), al2
));
231 BOOST_TEST(test::equivalent(y
.get_allocator(), al1
));
237 test::check_instances check_
;
239 test::random_values
<T
> v(500, generator
);
243 x
.max_load_factor(0.25);
244 x
.insert(v
.begin(), v
.end());
246 test::object_count count
= test::global_object_count
;
248 if (BOOST_UNORDERED_TEST_MOVING
&& allocator_type::is_propagate_on_move
) {
249 BOOST_TEST(count
== test::global_object_count
);
251 test::check_container(y
, v
);
252 test::check_equivalent_keys(y
);
253 BOOST_TEST(y
.max_load_factor() == 0.25);
255 if (BOOST_UNORDERED_TEST_MOVING
256 ? (bool)allocator_type::is_propagate_on_move
257 : (bool)allocator_type::is_propagate_on_assign
) {
258 BOOST_TEST(test::equivalent(y
.get_allocator(), al2
));
260 BOOST_TEST(test::equivalent(y
.get_allocator(), al1
));
265 test::check_instances check_
;
267 test::random_values
<T
> v1(1000, generator
);
268 test::random_values
<T
> v2(200, generator
);
271 x
.max_load_factor(0.5);
272 x
.insert(v2
.begin(), v2
.end());
274 test::object_count count1
= test::global_object_count
;
276 T
y(v1
.begin(), v1
.end(), 0, hf
, eq
, al1
);
279 test::object_count count2
= test::global_object_count
;
281 if (BOOST_UNORDERED_TEST_MOVING
&& allocator_type::is_propagate_on_move
) {
282 BOOST_TEST(count1
.instances
== test::global_object_count
.instances
);
284 count2
.constructions
== test::global_object_count
.constructions
);
287 test::check_container(y
, v2
);
288 test::check_equivalent_keys(y
);
289 BOOST_TEST(y
.max_load_factor() == 0.5);
291 if (BOOST_UNORDERED_TEST_MOVING
292 ? (bool)allocator_type::is_propagate_on_move
293 : (bool)allocator_type::is_propagate_on_assign
) {
294 BOOST_TEST(test::equivalent(y
.get_allocator(), al2
));
296 BOOST_TEST(test::equivalent(y
.get_allocator(), al1
));
301 boost::unordered_map
<test::object
, test::object
, test::hash
, test::equal_to
,
302 std::allocator
<test::object
> >* test_map_std_alloc
;
304 boost::unordered_set
<test::object
, test::hash
, test::equal_to
,
305 test::allocator2
<test::object
> >* test_set
;
306 boost::unordered_multiset
<test::object
, test::hash
, test::equal_to
,
307 test::allocator1
<test::object
> >* test_multiset
;
308 boost::unordered_map
<test::object
, test::object
, test::hash
, test::equal_to
,
309 test::allocator1
<test::object
> >* test_map
;
310 boost::unordered_multimap
<test::object
, test::object
, test::hash
,
311 test::equal_to
, test::allocator2
<test::object
> >* test_multimap
;
313 boost::unordered_set
<test::object
, test::hash
, test::equal_to
,
314 test::cxx11_allocator
<test::object
, test::propagate_move
> >*
316 boost::unordered_multiset
<test::object
, test::hash
, test::equal_to
,
317 test::cxx11_allocator
<test::object
, test::propagate_move
> >*
318 test_multiset_prop_move
;
319 boost::unordered_map
<test::object
, test::object
, test::hash
, test::equal_to
,
320 test::cxx11_allocator
<test::object
, test::propagate_move
> >*
322 boost::unordered_multimap
<test::object
, test::object
, test::hash
,
323 test::equal_to
, test::cxx11_allocator
<test::object
, test::propagate_move
> >*
324 test_multimap_prop_move
;
326 boost::unordered_set
<test::object
, test::hash
, test::equal_to
,
327 test::cxx11_allocator
<test::object
, test::no_propagate_move
> >*
328 test_set_no_prop_move
;
329 boost::unordered_multiset
<test::object
, test::hash
, test::equal_to
,
330 test::cxx11_allocator
<test::object
, test::no_propagate_move
> >*
331 test_multiset_no_prop_move
;
332 boost::unordered_map
<test::object
, test::object
, test::hash
, test::equal_to
,
333 test::cxx11_allocator
<test::object
, test::no_propagate_move
> >*
334 test_map_no_prop_move
;
335 boost::unordered_multimap
<test::object
, test::object
, test::hash
,
337 test::cxx11_allocator
<test::object
, test::no_propagate_move
> >*
338 test_multimap_no_prop_move
;
340 using test::default_generator
;
341 using test::generate_collisions
;
342 using test::limited_range
;
344 UNORDERED_TEST(move_construct_tests1
,
345 ((test_map_std_alloc
)(test_set
)(test_multiset
)(test_map
)(test_multimap
)(
346 test_set_prop_move
)(test_multiset_prop_move
)(test_map_prop_move
)(
347 test_multimap_prop_move
)(test_set_no_prop_move
)(
348 test_multiset_no_prop_move
)(test_map_no_prop_move
)(
349 test_multimap_no_prop_move
))(
350 (default_generator
)(generate_collisions
)(limited_range
)))
351 UNORDERED_TEST(move_assign_tests1
,
352 ((test_map_std_alloc
)(test_set
)(test_multiset
)(test_map
)(test_multimap
)(
353 test_set_prop_move
)(test_multiset_prop_move
)(test_map_prop_move
)(
354 test_multimap_prop_move
)(test_set_no_prop_move
)(
355 test_multiset_no_prop_move
)(test_map_no_prop_move
)(
356 test_multimap_no_prop_move
))(
357 (default_generator
)(generate_collisions
)(limited_range
)))
358 UNORDERED_TEST(move_construct_tests2
,
359 ((test_set
)(test_multiset
)(test_map
)(test_multimap
)(test_set_prop_move
)(
360 test_multiset_prop_move
)(test_map_prop_move
)(test_multimap_prop_move
)(
361 test_set_no_prop_move
)(test_multiset_no_prop_move
)(test_map_no_prop_move
)(
362 test_multimap_no_prop_move
))(
363 (default_generator
)(generate_collisions
)(limited_range
)))
364 UNORDERED_TEST(move_assign_tests2
,
365 ((test_set
)(test_multiset
)(test_map
)(test_multimap
)(test_set_prop_move
)(
366 test_multiset_prop_move
)(test_map_prop_move
)(test_multimap_prop_move
)(
367 test_set_no_prop_move
)(test_multiset_no_prop_move
)(test_map_no_prop_move
)(
368 test_multimap_no_prop_move
))(
369 (default_generator
)(generate_collisions
)(limited_range
)))