]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
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) | |
5 | ||
b32b8144 | 6 | // clang-format off |
7c673cae FG |
7 | #include "../helpers/prefix.hpp" |
8 | #include <boost/unordered_set.hpp> | |
9 | #include <boost/unordered_map.hpp> | |
10 | #include "../helpers/postfix.hpp" | |
b32b8144 | 11 | // clang-format on |
7c673cae FG |
12 | |
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" | |
20 | ||
21 | #if defined(BOOST_MSVC) | |
b32b8144 | 22 | #pragma warning(disable : 4127) // conditional expression is constant |
7c673cae FG |
23 | #endif |
24 | ||
b32b8144 FG |
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) | |
7c673cae FG |
29 | #define BOOST_UNORDERED_TEST_MOVING 1 |
30 | #else | |
31 | #define BOOST_UNORDERED_TEST_MOVING 0 | |
32 | #endif | |
33 | ||
b32b8144 FG |
34 | template <class T> T empty(T*) { return T(); } |
35 | ||
36 | template <class T> | |
37 | T create(test::random_values<T> const& v, test::object_count& count) | |
38 | { | |
39 | T x(v.begin(), v.end()); | |
40 | count = test::global_object_count; | |
41 | return x; | |
42 | } | |
43 | ||
44 | template <class T> | |
45 | T create(test::random_values<T> const& v, test::object_count& count, | |
11fdf7f2 TL |
46 | typename T::hasher hf, typename T::key_equal eq, |
47 | typename T::allocator_type al, float mlf) | |
b32b8144 FG |
48 | { |
49 | T x(0, hf, eq, al); | |
50 | x.max_load_factor(mlf); | |
51 | x.insert(v.begin(), v.end()); | |
52 | count = test::global_object_count; | |
53 | return x; | |
54 | } | |
55 | ||
56 | template <class T> | |
57 | void move_construct_tests1(T* ptr, test::random_generator const& generator) | |
58 | { | |
11fdf7f2 TL |
59 | typename T::hasher hf; |
60 | typename T::key_equal eq; | |
61 | typename T::allocator_type al; | |
7c673cae | 62 | |
b32b8144 FG |
63 | { |
64 | test::check_instances check_; | |
65 | ||
66 | T y(empty(ptr)); | |
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); | |
7c673cae FG |
73 | } |
74 | ||
7c673cae | 75 | { |
b32b8144 FG |
76 | test::check_instances check_; |
77 | ||
78 | test::random_values<T> v(1000, generator); | |
79 | test::object_count count; | |
80 | T y(create(v, count)); | |
7c673cae | 81 | #if defined(BOOST_HAS_NRVO) |
b32b8144 | 82 | BOOST_TEST(count == test::global_object_count); |
7c673cae | 83 | #endif |
b32b8144 FG |
84 | test::check_container(y, v); |
85 | test::check_equivalent_keys(y); | |
7c673cae | 86 | } |
b32b8144 | 87 | } |
7c673cae | 88 | |
b32b8144 FG |
89 | template <class T> |
90 | void move_assign_tests1(T*, test::random_generator const& generator) | |
91 | { | |
7c673cae | 92 | { |
b32b8144 | 93 | test::check_instances check_; |
7c673cae | 94 | |
b32b8144 FG |
95 | test::random_values<T> v(500, generator); |
96 | test::object_count count; | |
97 | T y; | |
98 | y = create(v, count); | |
7c673cae | 99 | #if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO) |
b32b8144 | 100 | BOOST_TEST(count == test::global_object_count); |
7c673cae | 101 | #endif |
b32b8144 FG |
102 | test::check_container(y, v); |
103 | test::check_equivalent_keys(y); | |
7c673cae | 104 | } |
b32b8144 | 105 | } |
7c673cae | 106 | |
b32b8144 FG |
107 | template <class T> |
108 | void move_construct_tests2(T*, test::random_generator const& generator) | |
109 | { | |
11fdf7f2 TL |
110 | typename T::hasher hf(1); |
111 | typename T::key_equal eq(1); | |
112 | typename T::allocator_type al(1); | |
113 | typename T::allocator_type al2(2); | |
7c673cae | 114 | |
b32b8144 | 115 | test::object_count count; |
7c673cae | 116 | |
b32b8144 FG |
117 | { |
118 | test::check_instances check_; | |
7c673cae | 119 | |
b32b8144 FG |
120 | test::random_values<T> v(500, generator); |
121 | T y(create(v, count, hf, eq, al, 0.5)); | |
7c673cae | 122 | #if defined(BOOST_HAS_NRVO) |
b32b8144 | 123 | BOOST_TEST(count == test::global_object_count); |
7c673cae | 124 | #endif |
b32b8144 FG |
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); | |
131 | } | |
132 | ||
133 | { | |
134 | test::check_instances check_; | |
135 | ||
136 | // TODO: To do this correctly requires the fancy new allocator | |
137 | // stuff. | |
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); | |
147 | } | |
148 | ||
149 | { | |
150 | test::check_instances check_; | |
151 | ||
152 | test::random_values<T> v(25, generator); | |
153 | T y(create(v, count, hf, eq, al, 1.0), al); | |
7c673cae | 154 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
b32b8144 | 155 | BOOST_TEST(count == test::global_object_count); |
7c673cae | 156 | #elif defined(BOOST_HAS_NRVO) |
b32b8144 FG |
157 | BOOST_TEST( |
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); | |
7c673cae | 163 | #else |
b32b8144 FG |
164 | BOOST_TEST( |
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); | |
7c673cae | 170 | #endif |
b32b8144 FG |
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); | |
7c673cae | 177 | } |
b32b8144 FG |
178 | } |
179 | ||
180 | template <class T> | |
181 | void move_assign_tests2(T*, test::random_generator const& generator) | |
182 | { | |
11fdf7f2 TL |
183 | typename T::hasher hf(1); |
184 | typename T::key_equal eq(1); | |
185 | typename T::allocator_type al1(1); | |
186 | typename T::allocator_type al2(2); | |
187 | typedef typename T::allocator_type allocator_type; | |
7c673cae | 188 | |
7c673cae | 189 | { |
b32b8144 FG |
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); | |
7c673cae FG |
199 | |
200 | #if defined(BOOST_HAS_NRVO) | |
b32b8144 FG |
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)); | |
205 | } else { | |
206 | BOOST_TEST(test::equivalent(y.get_allocator(), al1)); | |
207 | } | |
7c673cae | 208 | #endif |
b32b8144 | 209 | } |
7c673cae | 210 | |
b32b8144 FG |
211 | { |
212 | test::random_values<T> v(500, generator); | |
213 | test::object_count count; | |
214 | T y(0, hf, eq, al1); | |
215 | y = create(v, count, hf, eq, al2, 0.5); | |
7c673cae | 216 | #if defined(BOOST_HAS_NRVO) |
b32b8144 FG |
217 | if (BOOST_UNORDERED_TEST_MOVING && allocator_type::is_propagate_on_move) { |
218 | BOOST_TEST(count == test::global_object_count); | |
219 | } | |
7c673cae | 220 | #endif |
b32b8144 FG |
221 | test::check_container(y, v); |
222 | test::check_equivalent_keys(y); | |
223 | BOOST_TEST(y.max_load_factor() == 0.5); | |
7c673cae FG |
224 | |
225 | #if defined(BOOST_HAS_NRVO) | |
b32b8144 FG |
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)); | |
230 | } else { | |
231 | BOOST_TEST(test::equivalent(y.get_allocator(), al1)); | |
232 | } | |
7c673cae | 233 | #endif |
7c673cae FG |
234 | } |
235 | ||
b32b8144 FG |
236 | { |
237 | test::check_instances check_; | |
238 | ||
239 | test::random_values<T> v(500, generator); | |
240 | T y(0, hf, eq, al1); | |
241 | ||
242 | T x(0, hf, eq, al2); | |
243 | x.max_load_factor(0.25); | |
244 | x.insert(v.begin(), v.end()); | |
245 | ||
246 | test::object_count count = test::global_object_count; | |
247 | y = boost::move(x); | |
248 | if (BOOST_UNORDERED_TEST_MOVING && allocator_type::is_propagate_on_move) { | |
249 | BOOST_TEST(count == test::global_object_count); | |
250 | } | |
251 | test::check_container(y, v); | |
252 | test::check_equivalent_keys(y); | |
253 | BOOST_TEST(y.max_load_factor() == 0.25); | |
254 | ||
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)); | |
259 | } else { | |
260 | BOOST_TEST(test::equivalent(y.get_allocator(), al1)); | |
261 | } | |
262 | } | |
263 | ||
264 | { | |
265 | test::check_instances check_; | |
266 | ||
267 | test::random_values<T> v1(1000, generator); | |
268 | test::random_values<T> v2(200, generator); | |
269 | ||
270 | T x(0, hf, eq, al2); | |
271 | x.max_load_factor(0.5); | |
272 | x.insert(v2.begin(), v2.end()); | |
273 | ||
274 | test::object_count count1 = test::global_object_count; | |
275 | ||
276 | T y(v1.begin(), v1.end(), 0, hf, eq, al1); | |
277 | y = boost::move(x); | |
278 | ||
279 | test::object_count count2 = test::global_object_count; | |
280 | ||
281 | if (BOOST_UNORDERED_TEST_MOVING && allocator_type::is_propagate_on_move) { | |
282 | BOOST_TEST(count1.instances == test::global_object_count.instances); | |
283 | BOOST_TEST( | |
284 | count2.constructions == test::global_object_count.constructions); | |
285 | } | |
286 | ||
287 | test::check_container(y, v2); | |
288 | test::check_equivalent_keys(y); | |
289 | BOOST_TEST(y.max_load_factor() == 0.5); | |
290 | ||
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)); | |
295 | } else { | |
296 | BOOST_TEST(test::equivalent(y.get_allocator(), al1)); | |
297 | } | |
298 | } | |
299 | } | |
300 | ||
301 | boost::unordered_map<test::object, test::object, test::hash, test::equal_to, | |
302 | std::allocator<test::object> >* test_map_std_alloc; | |
303 | ||
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; | |
312 | ||
313 | boost::unordered_set<test::object, test::hash, test::equal_to, | |
314 | test::cxx11_allocator<test::object, test::propagate_move> >* | |
7c673cae | 315 | test_set_prop_move; |
b32b8144 FG |
316 | boost::unordered_multiset<test::object, test::hash, test::equal_to, |
317 | test::cxx11_allocator<test::object, test::propagate_move> >* | |
7c673cae | 318 | test_multiset_prop_move; |
b32b8144 FG |
319 | boost::unordered_map<test::object, test::object, test::hash, test::equal_to, |
320 | test::cxx11_allocator<test::object, test::propagate_move> >* | |
7c673cae | 321 | test_map_prop_move; |
b32b8144 FG |
322 | boost::unordered_multimap<test::object, test::object, test::hash, |
323 | test::equal_to, test::cxx11_allocator<test::object, test::propagate_move> >* | |
7c673cae FG |
324 | test_multimap_prop_move; |
325 | ||
b32b8144 FG |
326 | boost::unordered_set<test::object, test::hash, test::equal_to, |
327 | test::cxx11_allocator<test::object, test::no_propagate_move> >* | |
7c673cae | 328 | test_set_no_prop_move; |
b32b8144 FG |
329 | boost::unordered_multiset<test::object, test::hash, test::equal_to, |
330 | test::cxx11_allocator<test::object, test::no_propagate_move> >* | |
7c673cae | 331 | test_multiset_no_prop_move; |
b32b8144 FG |
332 | boost::unordered_map<test::object, test::object, test::hash, test::equal_to, |
333 | test::cxx11_allocator<test::object, test::no_propagate_move> >* | |
7c673cae | 334 | test_map_no_prop_move; |
b32b8144 FG |
335 | boost::unordered_multimap<test::object, test::object, test::hash, |
336 | test::equal_to, | |
337 | test::cxx11_allocator<test::object, test::no_propagate_move> >* | |
7c673cae FG |
338 | test_multimap_no_prop_move; |
339 | ||
b32b8144 FG |
340 | using test::default_generator; |
341 | using test::generate_collisions; | |
342 | using test::limited_range; | |
343 | ||
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))) | |
7c673cae FG |
370 | } |
371 | ||
372 | RUN_TESTS() |