Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / unordered / test / unordered / move_tests.cpp
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
6 #include "../helpers/prefix.hpp"
7 #include <boost/unordered_set.hpp>
8 #include <boost/unordered_map.hpp>
9 #include "../helpers/postfix.hpp"
10
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"
18
19 #if defined(BOOST_MSVC)
20 #pragma warning(disable:4127) // conditional expression is constant
21 #endif
22
23 namespace move_tests
24 {
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
28 #else
29 #define BOOST_UNORDERED_TEST_MOVING 0
30 #endif
31
32     template<class T>
33     T empty(T*) {
34         return T();
35     }
36
37     template<class T>
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;
42         return x;
43     }
44
45     template<class T>
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,
51             float mlf) {
52         T x(0, hf, eq, al);
53         x.max_load_factor(mlf);
54         x.insert(v.begin(), v.end());
55         count = test::global_object_count;
56         return x;
57     }
58
59     template <class T>
60     void move_construct_tests1(T* ptr, test::random_generator const& generator)
61     {
62         BOOST_DEDUCED_TYPENAME T::hasher hf;
63         BOOST_DEDUCED_TYPENAME T::key_equal eq;
64         BOOST_DEDUCED_TYPENAME T::allocator_type al;
65
66         {
67             test::check_instances check_;
68
69             T y(empty(ptr));
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);
76         }
77
78         {
79             test::check_instances check_;
80
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);
86 #endif
87             test::check_container(y, v);
88             test::check_equivalent_keys(y);
89         }
90     }
91
92     template <class T>
93     void move_assign_tests1(T*, test::random_generator const& generator)
94     {
95         {
96             test::check_instances check_;
97
98             test::random_values<T> v(500, generator);
99             test::object_count count;
100             T y;
101             y = create(v, count);
102 #if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
103             BOOST_TEST(count == test::global_object_count);
104 #endif
105             test::check_container(y, v);
106             test::check_equivalent_keys(y);
107         }
108     }
109
110     template <class T>
111     void move_construct_tests2(T*, test::random_generator const& generator)
112     {
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);
117
118         test::object_count count;
119
120         {
121             test::check_instances check_;
122
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);
127 #endif
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);
134         }
135
136         {
137             test::check_instances check_;
138
139             // TODO: To do this correctly requires the fancy new allocator
140             // stuff.
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);
150         }
151
152         {
153             test::check_instances check_;
154
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)
160             BOOST_TEST(
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);
166 #else
167             BOOST_TEST(
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);
173 #endif
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);
180         }
181     }
182
183     template <class T>
184     void move_assign_tests2(T*, test::random_generator const& generator)
185     {
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;
191
192         {
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);
202
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)
207             {
208                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
209             }
210             else {
211                 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
212             }
213 #endif
214         }
215
216         {
217             test::random_values<T> v(500, generator);
218             test::object_count count;
219             T y(0, hf, eq, al1);
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)
224             {
225                 BOOST_TEST(count == test::global_object_count);
226             }
227 #endif
228             test::check_container(y, v);
229             test::check_equivalent_keys(y);
230             BOOST_TEST(y.max_load_factor() == 0.5);
231
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)
236             {
237                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
238             }
239             else {
240                 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
241             }
242 #endif
243         }
244
245         {
246             test::check_instances check_;
247
248             test::random_values<T> v(500, generator);
249             T y(0, hf, eq, al1);
250
251             T x(0, hf, eq, al2);
252             x.max_load_factor(0.25);
253             x.insert(v.begin(), v.end());
254
255             test::object_count count = test::global_object_count;
256             y = boost::move(x);
257             if (BOOST_UNORDERED_TEST_MOVING &&
258                     allocator_type::is_propagate_on_move)
259             {
260                 BOOST_TEST(count == test::global_object_count);
261             }
262             test::check_container(y, v);
263             test::check_equivalent_keys(y);
264             BOOST_TEST(y.max_load_factor() == 0.25);
265
266             if (BOOST_UNORDERED_TEST_MOVING ?
267                     (bool) allocator_type::is_propagate_on_move :
268                     (bool) allocator_type::is_propagate_on_assign)
269             {
270                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
271             }
272             else {
273                 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
274             }
275         }
276
277         {
278             test::check_instances check_;
279
280             test::random_values<T> v1(1000, generator);
281             test::random_values<T> v2(200, generator);
282
283             T x(0, hf, eq, al2);
284             x.max_load_factor(0.5);
285             x.insert(v2.begin(), v2.end());
286
287             test::object_count count1 = test::global_object_count;
288
289             T y(v1.begin(), v1.end(), 0, hf, eq, al1);
290             y = boost::move(x);
291
292             test::object_count count2 = test::global_object_count;
293
294             if (BOOST_UNORDERED_TEST_MOVING &&
295                     allocator_type::is_propagate_on_move)
296             {
297                 BOOST_TEST(count1.instances ==
298                     test::global_object_count.instances);
299                 BOOST_TEST(count2.constructions ==
300                     test::global_object_count.constructions);
301             }
302
303             test::check_container(y, v2);
304             test::check_equivalent_keys(y);
305             BOOST_TEST(y.max_load_factor() == 0.5);
306
307             if (BOOST_UNORDERED_TEST_MOVING ?
308                     (bool) allocator_type::is_propagate_on_move :
309                     (bool) allocator_type::is_propagate_on_assign)
310             {
311                 BOOST_TEST(test::equivalent(y.get_allocator(), al2));
312             }
313             else {
314                 BOOST_TEST(test::equivalent(y.get_allocator(), al1));
315             }
316         }
317     }
318
319     boost::unordered_map<test::object, test::object,
320         test::hash, test::equal_to,
321         std::allocator<test::object> >* test_map_std_alloc;
322
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;
335
336 boost::unordered_set<test::object,
337         test::hash, test::equal_to,
338         test::cxx11_allocator<test::object, test::propagate_move> >*
339     test_set_prop_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> >*
347     test_map_prop_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;
352
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;
369
370     using test::default_generator;
371     using test::generate_collisions;
372
373     UNORDERED_TEST(move_construct_tests1, (
374             (test_map_std_alloc)
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)
378         )
379         ((default_generator)(generate_collisions))
380     )
381     UNORDERED_TEST(move_assign_tests1, (
382             (test_map_std_alloc)
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)
386         )
387         ((default_generator)(generate_collisions))
388     )
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)
393         )
394         ((default_generator)(generate_collisions))
395     )
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)
400         )
401         ((default_generator)(generate_collisions))
402     )
403 }
404
405 RUN_TESTS()