1 ////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/container for documentation.
9 ////////////////////////////////////////
11 #ifndef BOOST_CONTAINER_TEST_SET_TEST_HEADER
12 #define BOOST_CONTAINER_TEST_SET_TEST_HEADER
14 #include <boost/container/detail/config_begin.hpp>
15 #include "check_equal_containers.hpp"
19 #include "print_container.hpp"
20 #include <boost/move/utility_core.hpp>
21 #include <boost/move/iterator.hpp>
22 #include <boost/move/make_unique.hpp>
25 #include <boost/intrusive/detail/has_member_function_callable_with.hpp>
26 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
27 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace test {
28 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
29 #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
30 #include BOOST_PP_ITERATE()
38 void set_test_rebalanceable(C &, boost::container::container_detail::false_type)
42 void set_test_rebalanceable(C &c, boost::container::container_detail::true_type)
47 template<class MyBoostSet
49 ,class MyBoostMultiSet
51 int set_test_copyable(boost::container::container_detail::false_type)
54 template<class MyBoostSet
56 ,class MyBoostMultiSet
58 int set_test_copyable(boost::container::container_detail::true_type)
60 typedef typename MyBoostSet::value_type IntType;
63 ::boost::movelib::unique_ptr<MyBoostSet> const pboostset = ::boost::movelib::make_unique<MyBoostSet>();
64 ::boost::movelib::unique_ptr<MyStdSet> const pstdset = ::boost::movelib::make_unique<MyStdSet>();
65 ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset = ::boost::movelib::make_unique<MyBoostMultiSet>();
66 ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset = ::boost::movelib::make_unique<MyStdMultiSet>();
68 MyBoostSet &boostset = *pboostset;
69 MyStdSet &stdset = *pstdset;
70 MyBoostMultiSet &boostmultiset = *pboostmultiset;
71 MyStdMultiSet &stdmultiset = *pstdmultiset;
73 for(int i = 0; i < max; ++i){
75 boostset.insert(boost::move(move_me));
78 boostmultiset.insert(boost::move(move_me2));
79 stdmultiset.insert(i);
81 if(!CheckEqualContainers(boostset, stdset)) return 1;
82 if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
85 //Now, test copy constructor
86 MyBoostSet boostsetcopy(boostset);
87 MyStdSet stdsetcopy(stdset);
89 if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
92 MyBoostMultiSet boostmsetcopy(boostmultiset);
93 MyStdMultiSet stdmsetcopy(stdmultiset);
95 if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
99 boostsetcopy =boostset;
102 if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
105 boostmsetcopy = boostmultiset;
106 stdmsetcopy = stdmultiset;
108 if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
115 template<class MyBoostSet
117 ,class MyBoostMultiSet
118 ,class MyStdMultiSet>
121 typedef typename MyBoostSet::value_type IntType;
124 ::boost::movelib::unique_ptr<MyBoostSet> const pboostset = ::boost::movelib::make_unique<MyBoostSet>();
125 ::boost::movelib::unique_ptr<MyStdSet> const pstdset = ::boost::movelib::make_unique<MyStdSet>();
126 ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset = ::boost::movelib::make_unique<MyBoostMultiSet>();
127 ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset = ::boost::movelib::make_unique<MyStdMultiSet>();
129 MyBoostSet &boostset = *pboostset;
130 MyStdSet &stdset = *pstdset;
131 MyBoostMultiSet &boostmultiset = *pboostmultiset;
132 MyStdMultiSet &stdmultiset = *pstdmultiset;
134 //Test construction from a range
136 IntType aux_vect[50];
137 for(int i = 0; i < 50; ++i){
138 IntType move_me(i/2);
139 aux_vect[i] = boost::move(move_me);
142 for(int i = 0; i < 50; ++i){
145 IntType aux_vect3[50];
146 for(int i = 0; i < 50; ++i){
147 IntType move_me(i/2);
148 aux_vect3[i] = boost::move(move_me);
151 ::boost::movelib::unique_ptr<MyBoostSet> const pboostset2 = ::boost::movelib::make_unique<MyBoostSet>
152 ( boost::make_move_iterator(&aux_vect[0])
153 , boost::make_move_iterator(aux_vect + 50));
154 ::boost::movelib::unique_ptr<MyStdSet> const pstdset2 = ::boost::movelib::make_unique<MyStdSet>
155 (&aux_vect2[0], &aux_vect2[0] + 50);
156 ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset2 = ::boost::movelib::make_unique<MyBoostMultiSet>
157 ( boost::make_move_iterator(&aux_vect3[0])
158 , boost::make_move_iterator(aux_vect3 + 50));
159 ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset2 = ::boost::movelib::make_unique<MyStdMultiSet>
160 (&aux_vect2[0], &aux_vect2[0] + 50);
162 MyBoostSet &boostset2 = *pboostset2;
163 MyStdSet &stdset2 = *pstdset2;
164 MyBoostMultiSet &boostmultiset2 = *pboostmultiset2;
165 MyStdMultiSet &stdmultiset2 = *pstdmultiset2;
167 if(!CheckEqualContainers(boostset2, stdset2)){
168 std::cout << "Error in construct<MyBoostSet>(MyBoostSet2)" << std::endl;
171 if(!CheckEqualContainers(boostmultiset2, stdmultiset2)){
172 std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet2)" << std::endl;
176 //ordered range insertion
177 for(int i = 0; i < 50; ++i){
179 aux_vect[i] = boost::move(move_me);
182 for(int i = 0; i < 50; ++i){
186 for(int i = 0; i < 50; ++i){
188 aux_vect3[i] = boost::move(move_me);
193 ::boost::movelib::unique_ptr<MyBoostSet> const pboostset3 = ::boost::movelib::make_unique<MyBoostSet>
194 ( ordered_unique_range
195 , boost::make_move_iterator(&aux_vect[0])
196 , boost::make_move_iterator(&aux_vect[0] + 50));
197 ::boost::movelib::unique_ptr<MyStdSet> const pstdset3 = ::boost::movelib::make_unique<MyStdSet>
198 (&aux_vect2[0], &aux_vect2[0] + 50);
199 ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset3 = ::boost::movelib::make_unique<MyBoostMultiSet>
201 , boost::make_move_iterator(&aux_vect3[0])
202 , boost::make_move_iterator(aux_vect3 + 50));
203 ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset3 = ::boost::movelib::make_unique<MyStdMultiSet>
204 (&aux_vect2[0], &aux_vect2[0] + 50);
206 MyBoostSet &boostset3 = *pboostset3;
207 MyStdSet &stdset3 = *pstdset3;
208 MyBoostMultiSet &boostmultiset3 = *pboostmultiset3;
209 MyStdMultiSet &stdmultiset3 = *pstdmultiset3;
211 if(!CheckEqualContainers(boostset3, stdset3)){
212 std::cout << "Error in construct<MyBoostSet>(MyBoostSet3)" << std::endl;
215 if(!CheckEqualContainers(boostmultiset3, stdmultiset3)){
216 std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
221 for(int i = 0; i < max; ++i){
223 boostset.insert(boost::move(move_me));
225 boostset.insert(IntType(i));
228 boostmultiset.insert(boost::move(move_me2));
229 stdmultiset.insert(i);
230 boostmultiset.insert(IntType(i));
231 stdmultiset.insert(i);
234 if(!CheckEqualContainers(boostset, stdset)){
235 std::cout << "Error in boostset.insert(boost::move(move_me)" << std::endl;
239 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
240 std::cout << "Error in boostmultiset.insert(boost::move(move_me)" << std::endl;
244 typename MyBoostSet::iterator it = boostset.begin();
245 typename MyBoostSet::const_iterator cit = it;
248 boostset.erase(boostset.begin());
249 stdset.erase(stdset.begin());
250 boostmultiset.erase(boostmultiset.begin());
251 stdmultiset.erase(stdmultiset.begin());
252 if(!CheckEqualContainers(boostset, stdset)){
253 std::cout << "Error in boostset.erase(boostset.begin())" << std::endl;
256 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
257 std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
261 boostset.erase(boostset.begin());
262 stdset.erase(stdset.begin());
263 boostmultiset.erase(boostmultiset.begin());
264 stdmultiset.erase(stdmultiset.begin());
265 if(!CheckEqualContainers(boostset, stdset)){
266 std::cout << "Error in boostset.erase(boostset.begin())" << std::endl;
269 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
270 std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
275 MyBoostSet tmpboosteset2;
277 MyBoostMultiSet tmpboostemultiset2;
278 MyStdMultiSet tmpstdmultiset2;
279 boostset.swap(tmpboosteset2);
280 stdset.swap(tmpstdset2);
281 boostmultiset.swap(tmpboostemultiset2);
282 stdmultiset.swap(tmpstdmultiset2);
283 boostset.swap(tmpboosteset2);
284 stdset.swap(tmpstdset2);
285 boostmultiset.swap(tmpboostemultiset2);
286 stdmultiset.swap(tmpstdmultiset2);
287 if(!CheckEqualContainers(boostset, stdset)){
288 std::cout << "Error in boostset.swap(tmpboosteset2)" << std::endl;
291 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
292 std::cout << "Error in boostmultiset.swap(tmpboostemultiset2)" << std::endl;
296 //Insertion from other container
299 IntType aux_vect[50];
300 for(int i = 0; i < 50; ++i){
302 aux_vect[i] = boost::move(move_me);
305 for(int i = 0; i < 50; ++i){
308 IntType aux_vect3[50];
309 for(int i = 0; i < 50; ++i){
311 aux_vect3[i] = boost::move(move_me);
314 boostset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + 50));
315 stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
316 boostmultiset.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
317 stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
318 if(!CheckEqualContainers(boostset, stdset)){
319 std::cout << "Error in boostset.insert(boost::make_move_iterator(&aux_vect[0])..." << std::endl;
322 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
323 std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
327 for(int i = 0, j = static_cast<int>(boostset.size()); i < j; ++i){
329 boostset.erase(erase_me);
331 boostmultiset.erase(erase_me);
332 stdmultiset.erase(i);
333 if(!CheckEqualContainers(boostset, stdset)){
334 std::cout << "Error in boostset.erase(erase_me)" << boostset.size() << " " << stdset.size() << std::endl;
337 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
338 std::cout << "Error in boostmultiset.erase(erase_me)" << std::endl;
344 IntType aux_vect[50];
345 for(int i = 0; i < 50; ++i){
347 aux_vect[i] = boost::move(move_me);
350 for(int i = 0; i < 50; ++i){
353 IntType aux_vect3[50];
354 for(int i = 0; i < 50; ++i){
356 aux_vect3[i] = boost::move(move_me);
359 IntType aux_vect4[50];
360 for(int i = 0; i < 50; ++i){
362 aux_vect4[i] = boost::move(move_me);
365 IntType aux_vect5[50];
366 for(int i = 0; i < 50; ++i){
368 aux_vect5[i] = boost::move(move_me);
371 boostset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + 50));
372 boostset.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0] + 50));
373 stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
374 stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
375 boostmultiset.insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(&aux_vect4[0] + 50));
376 boostmultiset.insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(&aux_vect5[0] + 50));
377 stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
378 stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
379 if(!CheckEqualContainers(boostset, stdset)){
380 std::cout << "Error in boostset.insert(boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
383 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
384 std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
388 boostset.erase(*boostset.begin());
389 stdset.erase(*stdset.begin());
390 boostmultiset.erase(*boostmultiset.begin());
391 stdmultiset.erase(*stdmultiset.begin());
392 if(!CheckEqualContainers(boostset, stdset)){
393 std::cout << "Error in boostset.erase(*boostset.begin())" << std::endl;
396 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
397 std::cout << "Error in boostmultiset.erase(*boostmultiset.begin())" << std::endl;
402 for(int i = 0; i < max; ++i){
404 boostset.insert(boost::move(move_me));
407 boostmultiset.insert(boost::move(move_me2));
408 stdmultiset.insert(i);
411 if(!CheckEqualContainers(boostset, stdset)){
412 std::cout << "Error in boostset.insert(boost::move(move_me)) try 2" << std::endl;
415 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
416 std::cout << "Error in boostmultiset.insert(boost::move(move_me2)) try 2" << std::endl;
420 for(int i = 0; i < max; ++i){
423 boostset.insert(boostset.begin(), boost::move(move_me));
424 stdset.insert(stdset.begin(), i);
425 //PrintContainers(boostset, stdset);
427 boostmultiset.insert(boostmultiset.begin(), boost::move(move_me2));
428 stdmultiset.insert(stdmultiset.begin(), i);
429 //PrintContainers(boostmultiset, stdmultiset);
430 if(!CheckEqualContainers(boostset, stdset)){
431 std::cout << "Error in boostset.insert(boostset.begin(), boost::move(move_me))" << std::endl;
434 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
435 std::cout << "Error in boostmultiset.insert(boostmultiset.begin(), boost::move(move_me2))" << std::endl;
440 boostset.insert(boostset.end(), boost::move(move_me3));
441 stdset.insert(stdset.end(), i);
443 boostmultiset.insert(boostmultiset.end(), boost::move(move_me4));
444 stdmultiset.insert(stdmultiset.end(), i);
445 if(!CheckEqualContainers(boostset, stdset)){
446 std::cout << "Error in boostset.insert(boostset.end(), boost::move(move_me3))" << std::endl;
449 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
450 std::cout << "Error in boostmultiset.insert(boostmultiset.end(), boost::move(move_me4))" << std::endl;
456 boostset.insert(boostset.upper_bound(move_me), boost::move(move_me));
457 stdset.insert(stdset.upper_bound(i), i);
458 //PrintContainers(boostset, stdset);
460 boostmultiset.insert(boostmultiset.upper_bound(move_me2), boost::move(move_me2));
461 stdmultiset.insert(stdmultiset.upper_bound(i), i);
462 //PrintContainers(boostmultiset, stdmultiset);
463 if(!CheckEqualContainers(boostset, stdset)){
464 std::cout << "Error in boostset.insert(boostset.upper_bound(move_me), boost::move(move_me))" << std::endl;
467 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
468 std::cout << "Error in boostmultiset.insert(boostmultiset.upper_bound(move_me2), boost::move(move_me2))" << std::endl;
476 boostset.insert(boostset.lower_bound(move_me), boost::move(move_me2));
477 stdset.insert(stdset.lower_bound(i), i);
478 //PrintContainers(boostset, stdset);
480 boostmultiset.insert(boostmultiset.lower_bound(move_me2), boost::move(move_me2));
481 stdmultiset.insert(stdmultiset.lower_bound(i), i);
482 //PrintContainers(boostmultiset, stdmultiset);
483 if(!CheckEqualContainers(boostset, stdset)){
484 std::cout << "Error in boostset.insert(boostset.lower_bound(move_me), boost::move(move_me2))" << std::endl;
487 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
488 std::cout << "Error in boostmultiset.insert(boostmultiset.lower_bound(move_me2), boost::move(move_me2))" << std::endl;
491 set_test_rebalanceable(boostset
492 , container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostSet>::value>());
493 if(!CheckEqualContainers(boostset, stdset)){
494 std::cout << "Error in boostset.rebalance()" << std::endl;
497 set_test_rebalanceable(boostmultiset
498 , container_detail::bool_<has_member_function_callable_with_rebalance<MyBoostMultiSet>::value>());
499 if(!CheckEqualContainers(boostmultiset, stdmultiset)){
500 std::cout << "Error in boostmultiset.rebalance()" << std::endl;
506 //Compare count with std containers
507 for(int i = 0; i < max; ++i){
509 if(boostset.count(count_me) != stdset.count(i)){
512 if(boostmultiset.count(count_me) != stdmultiset.count(i)){
517 //Compare find/lower_bound/upper_bound in set
519 typename MyBoostSet::iterator bs_b = boostset.begin();
520 typename MyBoostSet::iterator bs_e = boostset.end();
521 typename MyStdSet::iterator ss_b = stdset.begin();
526 typename MyBoostSet::iterator bs_i;
527 typename MyStdSet::iterator ss_i;
529 bs_i = boostset.find(*bs_b);
530 ss_i = stdset.find(*ss_b);
531 if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
535 bs_i = boostset.lower_bound(*bs_b);
536 ss_i = stdset.lower_bound(*ss_b);
537 if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
541 bs_i = boostset.upper_bound(*bs_b);
542 ss_i = stdset.upper_bound(*ss_b);
543 if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
547 std::pair<typename MyBoostSet::iterator
548 ,typename MyBoostSet::iterator> bs_ip;
549 std::pair<typename MyStdSet::iterator
550 ,typename MyStdSet::iterator> ss_ip;
551 bs_ip = boostset.equal_range(*bs_b);
552 ss_ip = stdset.equal_range(*ss_b);
553 if(!CheckEqualIt(bs_ip.first, ss_ip.first, boostset, stdset)){
556 if(!CheckEqualIt(bs_ip.second, ss_ip.second, boostset, stdset)){
563 //Compare find/lower_bound/upper_bound in multiset
565 typename MyBoostMultiSet::iterator bm_b = boostmultiset.begin();
566 typename MyBoostMultiSet::iterator bm_e = boostmultiset.end();
567 typename MyStdMultiSet::iterator sm_b = stdmultiset.begin();
570 typename MyBoostMultiSet::iterator bm_i;
571 typename MyStdMultiSet::iterator sm_i;
573 bm_i = boostmultiset.find(*bm_b);
574 sm_i = stdmultiset.find(*sm_b);
575 if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
579 bm_i = boostmultiset.lower_bound(*bm_b);
580 sm_i = stdmultiset.lower_bound(*sm_b);
581 if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
585 bm_i = boostmultiset.upper_bound(*bm_b);
586 sm_i = stdmultiset.upper_bound(*sm_b);
587 if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
591 std::pair<typename MyBoostMultiSet::iterator
592 ,typename MyBoostMultiSet::iterator> bm_ip;
593 std::pair<typename MyStdMultiSet::iterator
594 ,typename MyStdMultiSet::iterator> sm_ip;
595 bm_ip = boostmultiset.equal_range(*bm_b);
596 sm_ip = stdmultiset.equal_range(*sm_b);
597 if(!CheckEqualIt(bm_ip.first, sm_ip.first, boostmultiset, stdmultiset)){
600 if(!CheckEqualIt(bm_ip.second, sm_ip.second, boostmultiset, stdmultiset)){
608 //Now do count exercise
609 boostset.erase(boostset.begin(), boostset.end());
610 boostmultiset.erase(boostmultiset.begin(), boostmultiset.end());
612 boostmultiset.clear();
614 for(int j = 0; j < 3; ++j)
615 for(int i = 0; i < 100; ++i){
617 boostset.insert(boost::move(move_me));
619 boostmultiset.insert(boost::move(move_me2));
621 if(boostset.count(count_me) != typename MyBoostMultiSet::size_type(1)){
622 std::cout << "Error in boostset.count(count_me)" << std::endl;
625 if(boostmultiset.count(count_me) != typename MyBoostMultiSet::size_type(j+1)){
626 std::cout << "Error in boostmultiset.count(count_me)" << std::endl;
631 if(set_test_copyable<MyBoostSet, MyStdSet, MyBoostMultiSet, MyStdMultiSet>
632 (container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
640 } //namespace container {
643 #include <boost/container/detail/config_end.hpp>