1 ////////////////////////////////////////
2 //
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)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 ////////////////////////////////////////
10 
11 #ifndef BOOST_CONTAINER_TEST_SET_TEST_HEADER
12 #define BOOST_CONTAINER_TEST_SET_TEST_HEADER
13 
14 #include <boost/container/detail/config_begin.hpp>
15 #include "check_equal_containers.hpp"
16 #include "print_container.hpp"
17 #include "movable_int.hpp"
18 #include <boost/move/utility_core.hpp>
19 #include <boost/move/iterator.hpp>
20 #include <boost/move/make_unique.hpp>
21 
22 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wunused-result"
25 #endif
26 
27 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME rebalance
28 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace test {
29 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
30 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
31 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
32 #include <boost/intrusive/detail/has_member_function_callable_with.hpp>
33 
34 //#pragma GCC diagnostic ignored "-Wunused-result"
35 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
36 #pragma GCC diagnostic pop
37 #endif
38 
39 namespace boost{
40 namespace container {
41 namespace test{
42 
43 template<class C>
set_test_rebalanceable(C &,boost::container::dtl::false_type)44 void set_test_rebalanceable(C &, boost::container::dtl::false_type)
45 {}
46 
47 template<class C>
set_test_rebalanceable(C & c,boost::container::dtl::true_type)48 void set_test_rebalanceable(C &c, boost::container::dtl::true_type)
49 {
50    c.rebalance();
51 }
52 
53 template<class MyBoostSet
54         ,class MyStdSet
55         ,class MyBoostMultiSet
56         ,class MyStdMultiSet>
set_test_copyable(boost::container::dtl::false_type)57 int set_test_copyable(boost::container::dtl::false_type)
58 {  return 0; }
59 
60 const int MaxElem = 50;
61 
62 template<class MyBoostSet
63         ,class MyStdSet
64         ,class MyBoostMultiSet
65         ,class MyStdMultiSet>
set_test_copyable(boost::container::dtl::true_type)66 int set_test_copyable(boost::container::dtl::true_type)
67 {
68    typedef typename MyBoostSet::value_type IntType;
69 
70    ::boost::movelib::unique_ptr<MyBoostSet> const pboostset = ::boost::movelib::make_unique<MyBoostSet>();
71    ::boost::movelib::unique_ptr<MyStdSet>   const pstdset = ::boost::movelib::make_unique<MyStdSet>();
72    ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset = ::boost::movelib::make_unique<MyBoostMultiSet>();
73    ::boost::movelib::unique_ptr<MyStdMultiSet>   const pstdmultiset   = ::boost::movelib::make_unique<MyStdMultiSet>();
74 
75    MyBoostSet &boostset = *pboostset;
76    MyStdSet   &stdset   = *pstdset;
77    MyBoostMultiSet &boostmultiset = *pboostmultiset;
78    MyStdMultiSet   &stdmultiset   = *pstdmultiset;
79 
80    //Just to test move aware catch conversions
81    boostset.insert(boostset.cbegin(), boostset.cend());
82    boostmultiset.insert(boostmultiset.cbegin(), boostmultiset.cend());
83    boostset.insert(boostset.begin(), boostset.end());
84    boostmultiset.insert(boostmultiset.begin(), boostmultiset.end());
85 
86    for(int i = 0; i < MaxElem; ++i){
87       IntType move_me(i);
88       boostset.insert(boost::move(move_me));
89       stdset.insert(i);
90       IntType move_me2(i);
91       boostmultiset.insert(boost::move(move_me2));
92       stdmultiset.insert(i);
93    }
94    if(!CheckEqualContainers(boostset, stdset)) return 1;
95    if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
96 
97    {
98       //Now, test copy constructor
99       MyBoostSet boostsetcopy(boostset);
100       MyStdSet stdsetcopy(stdset);
101 
102       if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
103          return 1;
104 
105       MyBoostMultiSet boostmsetcopy(boostmultiset);
106       MyStdMultiSet stdmsetcopy(stdmultiset);
107 
108       if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
109          return 1;
110 
111       //And now assignment
112       boostsetcopy  =boostset;
113       stdsetcopy  = stdset;
114 
115       if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
116          return 1;
117 
118       boostmsetcopy = boostmultiset;
119       stdmsetcopy = stdmultiset;
120 
121       if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
122          return 1;
123    }
124    {
125       //Now, test copy constructor with allocator
126       MyBoostSet boostsetcopy(boostset, typename MyBoostSet::allocator_type());
127       MyStdSet stdsetcopy(stdset);
128 
129       if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
130          return 1;
131 
132       MyBoostMultiSet boostmsetcopy(boostmultiset, typename MyBoostSet::allocator_type());
133       MyStdMultiSet stdmsetcopy(stdmultiset);
134 
135       if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
136          return 1;
137    }
138    return 0;
139 }
140 
141 
142 template<class MyBoostSet
143         ,class MyStdSet
144         ,class MyBoostMultiSet
145         ,class MyStdMultiSet>
set_test()146 int set_test ()
147 {
148    typedef typename MyBoostSet::value_type IntType;
149 
150    ::boost::movelib::unique_ptr<MyBoostSet> const pboostset = ::boost::movelib::make_unique<MyBoostSet>();
151    ::boost::movelib::unique_ptr<MyStdSet>   const pstdset = ::boost::movelib::make_unique<MyStdSet>();
152    ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset = ::boost::movelib::make_unique<MyBoostMultiSet>();
153    ::boost::movelib::unique_ptr<MyStdMultiSet>   const pstdmultiset   = ::boost::movelib::make_unique<MyStdMultiSet>();
154 
155    MyBoostSet &boostset = *pboostset;
156    MyStdSet   &stdset   = *pstdset;
157    MyBoostMultiSet &boostmultiset = *pboostmultiset;
158    MyStdMultiSet   &stdmultiset   = *pstdmultiset;
159 
160    //Test construction from a range
161    {  //Set(beg, end, compare)
162       IntType aux_vect[50];
163       for(int i = 0; i < 50; ++i){
164          IntType move_me(i/2);
165          aux_vect[i] = boost::move(move_me);
166       }
167       int aux_vect2[50];
168       for(int i = 0; i < 50; ++i){
169          aux_vect2[i] = i/2;
170       }
171       IntType aux_vect3[50];
172       for(int i = 0; i < 50; ++i){
173          IntType move_me(i/2);
174          aux_vect3[i] = boost::move(move_me);
175       }
176       ::boost::movelib::unique_ptr<MyBoostSet> const pboostset2 = ::boost::movelib::make_unique<MyBoostSet>
177          (boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0]+50), typename MyBoostSet::key_compare());
178       ::boost::movelib::unique_ptr<MyStdSet> const pstdset2 = ::boost::movelib::make_unique<MyStdSet>(&aux_vect2[0], &aux_vect2[0]+50);
179       if(!test::CheckEqualContainers(*pboostset2, *pstdset2)) return 1;
180       ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset2 = ::boost::movelib::make_unique<MyBoostMultiSet>
181          (boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0]+50), typename MyBoostMultiSet::key_compare());
182       ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset2 = ::boost::movelib::make_unique<MyStdMultiSet>(&aux_vect2[0], &aux_vect2[0]+50);
183       if(!test::CheckEqualContainers(*pboostmultiset2, *pstdmultiset2)) return 1;
184    }
185    {  //Set(beg, end, alloc)
186       IntType aux_vect[50];
187       for(int i = 0; i < 50; ++i){
188          IntType move_me(i/2);
189          aux_vect[i] = boost::move(move_me);
190       }
191       int aux_vect2[50];
192       for(int i = 0; i < 50; ++i){
193          aux_vect2[i] = i/2;
194       }
195       IntType aux_vect3[50];
196       for(int i = 0; i < 50; ++i){
197          IntType move_me(i/2);
198          aux_vect3[i] = boost::move(move_me);
199       }
200       ::boost::movelib::unique_ptr<MyBoostSet> const pboostset2 = ::boost::movelib::make_unique<MyBoostSet>
201          (boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0]+50), typename MyBoostSet::allocator_type());
202       ::boost::movelib::unique_ptr<MyStdSet> const pstdset2 = ::boost::movelib::make_unique<MyStdSet>(&aux_vect2[0], &aux_vect2[0]+50);
203       if(!test::CheckEqualContainers(*pboostset2, *pstdset2)) return 1;
204       ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset2 = ::boost::movelib::make_unique<MyBoostMultiSet>
205          (boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0]+50), typename MyBoostMultiSet::allocator_type());
206       ::boost::movelib::unique_ptr<MyStdMultiSet> const pstdmultiset2 = ::boost::movelib::make_unique<MyStdMultiSet>(&aux_vect2[0], &aux_vect2[0]+50);
207       if(!test::CheckEqualContainers(*pboostmultiset2, *pstdmultiset2)) return 1;
208    }
209    {
210       IntType aux_vect[50];
211       for(int i = 0; i < 50; ++i){
212          IntType move_me(i/2);
213          aux_vect[i] = boost::move(move_me);
214       }
215       int aux_vect2[50];
216       for(int i = 0; i < 50; ++i){
217          aux_vect2[i] = i/2;
218       }
219       IntType aux_vect3[50];
220       for(int i = 0; i < 50; ++i){
221          IntType move_me(i/2);
222          aux_vect3[i] = boost::move(move_me);
223       }
224 
225       ::boost::movelib::unique_ptr<MyBoostSet> const pboostset2 = ::boost::movelib::make_unique<MyBoostSet>
226             ( boost::make_move_iterator(&aux_vect[0])
227             , boost::make_move_iterator(aux_vect + 50));
228       ::boost::movelib::unique_ptr<MyStdSet>  const pstdset2 = ::boost::movelib::make_unique<MyStdSet>
229             (&aux_vect2[0], &aux_vect2[0] + 50);
230       ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset2 = ::boost::movelib::make_unique<MyBoostMultiSet>
231             ( boost::make_move_iterator(&aux_vect3[0])
232             , boost::make_move_iterator(aux_vect3 + 50));
233       ::boost::movelib::unique_ptr<MyStdMultiSet>   const pstdmultiset2   = ::boost::movelib::make_unique<MyStdMultiSet>
234             (&aux_vect2[0], &aux_vect2[0] + 50);
235 
236       MyBoostSet &boostset2 = *pboostset2;
237       MyStdSet   &stdset2   = *pstdset2;
238       MyBoostMultiSet &boostmultiset2 = *pboostmultiset2;
239       MyStdMultiSet   &stdmultiset2   = *pstdmultiset2;
240 
241       if(!CheckEqualContainers(boostset2, stdset2)){
242          std::cout << "Error in construct<MyBoostSet>(MyBoostSet2)" << std::endl;
243          return 1;
244       }
245       if(!CheckEqualContainers(boostmultiset2, stdmultiset2)){
246          std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet2)" << std::endl;
247          return 1;
248       }
249 
250       //ordered range insertion
251       for(int i = 0; i < 50; ++i){
252          IntType move_me(i);
253          aux_vect[i] = boost::move(move_me);
254       }
255 
256       for(int i = 0; i < 50; ++i){
257          aux_vect2[i] = i;
258       }
259 
260       for(int i = 0; i < 50; ++i){
261          IntType move_me(i);
262          aux_vect3[i] = boost::move(move_me);
263       }
264 
265       //some comparison operators
266       if(!(boostset2 == boostset2))
267          return 1;
268       if(boostset2 != boostset2)
269          return 1;
270       if(boostset2 < boostset2)
271          return 1;
272       if(boostset2 > boostset2)
273          return 1;
274       if(!(boostset2 <= boostset2))
275          return 1;
276       if(!(boostset2 >= boostset2))
277          return 1;
278 
279       ::boost::movelib::unique_ptr<MyBoostSet> const pboostset3 = ::boost::movelib::make_unique<MyBoostSet>
280             ( ordered_unique_range
281             , boost::make_move_iterator(&aux_vect[0])
282             , boost::make_move_iterator(&aux_vect[0] + 50));
283       ::boost::movelib::unique_ptr<MyStdSet>   const pstdset3 = ::boost::movelib::make_unique<MyStdSet>
284             (&aux_vect2[0], &aux_vect2[0] + 50);
285       ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset3 = ::boost::movelib::make_unique<MyBoostMultiSet>
286             ( ordered_range
287             , boost::make_move_iterator(&aux_vect3[0])
288             , boost::make_move_iterator(aux_vect3 + 50));
289       ::boost::movelib::unique_ptr<MyStdMultiSet>   const pstdmultiset3   = ::boost::movelib::make_unique<MyStdMultiSet>
290             (&aux_vect2[0], &aux_vect2[0] + 50);
291 
292       MyBoostSet &boostset3 = *pboostset3;
293       MyStdSet   &stdset3   = *pstdset3;
294       MyBoostMultiSet &boostmultiset3 = *pboostmultiset3;
295       MyStdMultiSet   &stdmultiset3   = *pstdmultiset3;
296 
297       if(!CheckEqualContainers(boostset3, stdset3)){
298          std::cout << "Error in construct<MyBoostSet>(MyBoostSet3)" << std::endl;
299          return 1;
300       }
301       if(!CheckEqualContainers(boostmultiset3, stdmultiset3)){
302          std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
303          return 1;
304       }
305    }
306 
307    for(int i = 0; i < MaxElem; ++i){
308       IntType move_me(i);
309       boostset.insert(boost::move(move_me));
310       stdset.insert(i);
311       boostset.insert(IntType(i));
312       stdset.insert(i);
313       IntType move_me2(i);
314       boostmultiset.insert(boost::move(move_me2));
315       stdmultiset.insert(i);
316       boostmultiset.insert(IntType(i));
317       stdmultiset.insert(i);
318    }
319 
320    if(!CheckEqualContainers(boostset, stdset)){
321       std::cout << "Error in boostset.insert(boost::move(move_me)" << std::endl;
322       return 1;
323    }
324 
325    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
326       std::cout << "Error in boostmultiset.insert(boost::move(move_me)" << std::endl;
327       return 1;
328    }
329 
330    typename MyBoostSet::iterator it = boostset.begin();
331    typename MyBoostSet::const_iterator cit = it;
332    (void)cit;
333 
334    boostset.erase(boostset.begin());
335    stdset.erase(stdset.begin());
336    boostmultiset.erase(boostmultiset.begin());
337    stdmultiset.erase(stdmultiset.begin());
338    if(!CheckEqualContainers(boostset, stdset)){
339       std::cout << "Error in boostset.erase(boostset.begin())" << std::endl;
340       return 1;
341    }
342    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
343       std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
344       return 1;
345    }
346 
347    boostset.erase(boostset.begin());
348    stdset.erase(stdset.begin());
349    boostmultiset.erase(boostmultiset.begin());
350    stdmultiset.erase(stdmultiset.begin());
351    if(!CheckEqualContainers(boostset, stdset)){
352       std::cout << "Error in boostset.erase(boostset.begin())" << std::endl;
353       return 1;
354    }
355    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
356       std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
357       return 1;
358    }
359 
360    {
361       //Swapping test
362       MyBoostSet tmpboosteset2;
363       MyStdSet tmpstdset2;
364       MyBoostMultiSet tmpboostemultiset2;
365       MyStdMultiSet tmpstdmultiset2;
366       boostset.swap(tmpboosteset2);
367       stdset.swap(tmpstdset2);
368       boostmultiset.swap(tmpboostemultiset2);
369       stdmultiset.swap(tmpstdmultiset2);
370       boostset.swap(tmpboosteset2);
371       stdset.swap(tmpstdset2);
372       boostmultiset.swap(tmpboostemultiset2);
373       stdmultiset.swap(tmpstdmultiset2);
374       if(!CheckEqualContainers(boostset, stdset)){
375          std::cout << "Error in boostset.swap(tmpboosteset2)" << std::endl;
376          return 1;
377       }
378       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
379          std::cout << "Error in boostmultiset.swap(tmpboostemultiset2)" << std::endl;
380          return 1;
381       }
382    }
383 
384    //move constructor/assignment
385    {
386       MyBoostSet tmpboosteset2(boost::move(boostset));
387       if(!CheckEqualContainers(tmpboosteset2, stdset)){
388          std::cout << "Error in boostset move constructor " << std::endl;
389          return 1;
390       }
391       MyBoostMultiSet tmpboostemultiset2(boost::move(boostmultiset));
392       if(!CheckEqualContainers(tmpboostemultiset2, stdmultiset)){
393          std::cout << "Error in boostmultiset move constructor " << std::endl;
394          return 1;
395       }
396 
397       boostset = boost::move(tmpboosteset2);
398       if(!CheckEqualContainers(boostset, stdset)){
399          std::cout << "Error in boostset move assignment" << std::endl;
400          return 1;
401       }
402       boostmultiset = boost::move(tmpboostemultiset2);
403       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
404          std::cout << "Error in boostmultiset move assignment" << std::endl;
405          return 1;
406       }
407    }
408    //Insertion from other container
409    //Initialize values
410    {
411       IntType aux_vect[50];
412       for(int i = 0; i < 50; ++i){
413          IntType move_me(-1);
414          aux_vect[i] = boost::move(move_me);
415       }
416       int aux_vect2[50];
417       for(int i = 0; i < 50; ++i){
418          aux_vect2[i] = -1;
419       }
420       IntType aux_vect3[50];
421       for(int i = 0; i < 50; ++i){
422          IntType move_me(-1);
423          aux_vect3[i] = boost::move(move_me);
424       }
425 
426       boostset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + 50));
427       stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
428       if(!CheckEqualContainers(boostset, stdset)){
429          std::cout << "Error in boostset.insert(boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
430          return 1;
431       }
432       boostmultiset.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(aux_vect3 + 50));
433       stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
434       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
435          std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
436          return 1;
437       }
438 
439       for(int i = 0, j = static_cast<int>(boostset.size()); i < j; ++i){
440          IntType erase_me(i);
441          boostset.erase(erase_me);
442          stdset.erase(i);
443          boostmultiset.erase(erase_me);
444          stdmultiset.erase(i);
445          if(!CheckEqualContainers(boostset, stdset)){
446             std::cout << "Error in boostset.erase(erase_me)" << boostset.size() << " " << stdset.size() << std::endl;
447             return 1;
448          }
449          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
450             std::cout << "Error in boostmultiset.erase(erase_me)" << std::endl;
451             return 1;
452          }
453       }
454    }
455    {
456       IntType aux_vect[50];
457       for(int i = 0; i < 50; ++i){
458          IntType move_me(-1);
459          aux_vect[i] = boost::move(move_me);
460       }
461       int aux_vect2[50];
462       for(int i = 0; i < 50; ++i){
463          aux_vect2[i] = -1;
464       }
465       IntType aux_vect3[50];
466       for(int i = 0; i < 50; ++i){
467          IntType move_me(-1);
468          aux_vect3[i] = boost::move(move_me);
469       }
470 
471       IntType aux_vect4[50];
472       for(int i = 0; i < 50; ++i){
473          IntType move_me(-1);
474          aux_vect4[i] = boost::move(move_me);
475       }
476 
477       IntType aux_vect5[50];
478       for(int i = 0; i < 50; ++i){
479          IntType move_me(-1);
480          aux_vect5[i] = boost::move(move_me);
481       }
482 
483       boostset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + 50));
484       boostset.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0] + 50));
485       stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
486       stdset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
487       if(!CheckEqualContainers(boostset, stdset)){
488          std::cout << "Error in boostset.insert(boost::make_move_iterator(&aux_vect3[0])..." << std::endl;
489          return 1;
490       }
491       boostmultiset.insert(boost::make_move_iterator(&aux_vect4[0]), boost::make_move_iterator(&aux_vect4[0] + 50));
492       boostmultiset.insert(boost::make_move_iterator(&aux_vect5[0]), boost::make_move_iterator(&aux_vect5[0] + 50));
493       stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
494       stdmultiset.insert(&aux_vect2[0], &aux_vect2[0] + 50);
495       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
496          std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
497          return 1;
498       }
499 
500       boostset.erase(*boostset.begin());
501       stdset.erase(*stdset.begin());
502       if(!CheckEqualContainers(boostset, stdset)){
503          std::cout << "Error in boostset.erase(*boostset.begin())" << std::endl;
504          return 1;
505       }
506       boostmultiset.erase(*boostmultiset.begin());
507       stdmultiset.erase(*stdmultiset.begin());
508       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
509          std::cout << "Error in boostmultiset.erase(*boostmultiset.begin())" << std::endl;
510          return 1;
511       }
512    }
513 
514    for(int i = 0; i < MaxElem; ++i){
515       IntType move_me(i);
516       boostset.insert(boost::move(move_me));
517       stdset.insert(i);
518       IntType move_me2(i);
519       boostmultiset.insert(boost::move(move_me2));
520       stdmultiset.insert(i);
521    }
522 
523    if(!CheckEqualContainers(boostset, stdset)){
524       std::cout << "Error in boostset.insert(boost::move(move_me)) try 2" << std::endl;
525       return 1;
526    }
527    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
528       std::cout << "Error in boostmultiset.insert(boost::move(move_me2)) try 2" << std::endl;
529       return 1;
530    }
531 
532    for(int i = 0; i < MaxElem; ++i){
533       {
534          IntType move_me(i);
535          boostset.insert(boostset.begin(), boost::move(move_me));
536          stdset.insert(stdset.begin(), i);
537          //PrintContainers(boostset, stdset);
538          IntType move_me2(i);
539          boostmultiset.insert(boostmultiset.begin(), boost::move(move_me2));
540          stdmultiset.insert(stdmultiset.begin(), i);
541          //PrintContainers(boostmultiset, stdmultiset);
542          if(!CheckEqualContainers(boostset, stdset)){
543             std::cout << "Error in boostset.insert(boostset.begin(), boost::move(move_me))" << std::endl;
544             return 1;
545          }
546          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
547             std::cout << "Error in boostmultiset.insert(boostmultiset.begin(), boost::move(move_me2))" << std::endl;
548             return 1;
549          }
550 
551          IntType move_me3(i);
552          boostset.insert(boostset.end(), boost::move(move_me3));
553          stdset.insert(stdset.end(), i);
554          IntType move_me4(i);
555          boostmultiset.insert(boostmultiset.end(), boost::move(move_me4));
556          stdmultiset.insert(stdmultiset.end(), i);
557          if(!CheckEqualContainers(boostset, stdset)){
558             std::cout << "Error in boostset.insert(boostset.end(), boost::move(move_me3))" << std::endl;
559             return 1;
560          }
561          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
562             std::cout << "Error in boostmultiset.insert(boostmultiset.end(), boost::move(move_me4))" << std::endl;
563             return 1;
564          }
565       }
566       {
567          IntType move_me(i);
568          boostset.insert(boostset.upper_bound(move_me), boost::move(move_me));
569          stdset.insert(stdset.upper_bound(i), i);
570          //PrintContainers(boostset, stdset);
571          IntType move_me2(i);
572          boostmultiset.insert(boostmultiset.upper_bound(move_me2), boost::move(move_me2));
573          stdmultiset.insert(stdmultiset.upper_bound(i), i);
574          //PrintContainers(boostmultiset, stdmultiset);
575          if(!CheckEqualContainers(boostset, stdset)){
576             std::cout << "Error in boostset.insert(boostset.upper_bound(move_me), boost::move(move_me))" << std::endl;
577             return 1;
578          }
579          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
580             std::cout << "Error in boostmultiset.insert(boostmultiset.upper_bound(move_me2), boost::move(move_me2))" << std::endl;
581             return 1;
582          }
583 
584       }
585       {
586          IntType move_me(i);
587          IntType move_me2(i);
588          boostset.insert(boostset.lower_bound(move_me), boost::move(move_me2));
589          stdset.insert(stdset.lower_bound(i), i);
590          //PrintContainers(boostset, stdset);
591          move_me2 = i;
592          boostmultiset.insert(boostmultiset.lower_bound(move_me2), boost::move(move_me2));
593          stdmultiset.insert(stdmultiset.lower_bound(i), i);
594          //PrintContainers(boostmultiset, stdmultiset);
595          if(!CheckEqualContainers(boostset, stdset)){
596             std::cout << "Error in boostset.insert(boostset.lower_bound(move_me), boost::move(move_me2))" << std::endl;
597             return 1;
598          }
599          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
600             std::cout << "Error in boostmultiset.insert(boostmultiset.lower_bound(move_me2), boost::move(move_me2))" << std::endl;
601             return 1;
602          }
603          set_test_rebalanceable(boostset
604             , dtl::bool_<has_member_function_callable_with_rebalance<MyBoostSet>::value>());
605          if(!CheckEqualContainers(boostset, stdset)){
606             std::cout << "Error in boostset.rebalance()" << std::endl;
607             return 1;
608          }
609          set_test_rebalanceable(boostmultiset
610             , dtl::bool_<has_member_function_callable_with_rebalance<MyBoostMultiSet>::value>());
611          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
612             std::cout << "Error in boostmultiset.rebalance()" << std::endl;
613             return 1;
614          }
615       }
616    }
617 
618    //Compare count with std containers
619    for(int i = 0; i < MaxElem; ++i){
620       IntType k(i);
621       if(boostset.count(k) != stdset.count(i)){
622          return -1;
623       }
624 
625       if(boostset.contains(k) != (stdset.find(i) != stdset.end())){
626          return -1;
627       }
628 
629       if(boostmultiset.count(k) != stdmultiset.count(i)){
630          return -1;
631       }
632 
633       if(boostmultiset.contains(k) != (stdmultiset.find(i) != stdmultiset.end())){
634          return -1;
635       }
636    }
637 
638    //Compare find/lower_bound/upper_bound in set
639    {
640       typename MyBoostSet::iterator bs_b = boostset.begin();
641       typename MyBoostSet::iterator bs_e = boostset.end();
642       typename MyStdSet::iterator ss_b   = stdset.begin();
643 
644       std::size_t i = 0;
645       while(bs_b != bs_e){
646          ++i;
647          typename MyBoostSet::iterator bs_i;
648          typename MyStdSet::iterator ss_i;
649          //find
650          bs_i = boostset.find(*bs_b);
651          ss_i = stdset.find(*ss_b);
652          if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
653             return -1;
654          }
655          //lower bound
656          bs_i = boostset.lower_bound(*bs_b);
657          ss_i = stdset.lower_bound(*ss_b);
658          if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
659             return -1;
660          }
661          //upper bound
662          bs_i = boostset.upper_bound(*bs_b);
663          ss_i = stdset.upper_bound(*ss_b);
664          if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
665             return -1;
666          }
667          //equal range
668          std::pair<typename MyBoostSet::iterator
669                   ,typename MyBoostSet::iterator> bs_ip;
670          std::pair<typename MyStdSet::iterator
671                   ,typename MyStdSet::iterator>   ss_ip;
672          bs_ip = boostset.equal_range(*bs_b);
673          ss_ip = stdset.equal_range(*ss_b);
674          if(!CheckEqualIt(bs_ip.first, ss_ip.first, boostset, stdset)){
675             return -1;
676          }
677          if(!CheckEqualIt(bs_ip.second, ss_ip.second, boostset, stdset)){
678             return -1;
679          }
680          ++bs_b;
681          ++ss_b;
682       }
683    }
684    //Compare find/lower_bound/upper_bound in multiset
685    {
686       typename MyBoostMultiSet::iterator bm_b = boostmultiset.begin();
687       typename MyBoostMultiSet::iterator bm_e = boostmultiset.end();
688       typename MyStdMultiSet::iterator sm_b   = stdmultiset.begin();
689 
690       while(bm_b != bm_e){
691          typename MyBoostMultiSet::iterator bm_i;
692          typename MyStdMultiSet::iterator sm_i;
693          //find
694          bm_i = boostmultiset.find(*bm_b);
695          sm_i = stdmultiset.find(*sm_b);
696          if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
697             return -1;
698          }
699          //lower bound
700          bm_i = boostmultiset.lower_bound(*bm_b);
701          sm_i = stdmultiset.lower_bound(*sm_b);
702          if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
703             return -1;
704          }
705          //upper bound
706          bm_i = boostmultiset.upper_bound(*bm_b);
707          sm_i = stdmultiset.upper_bound(*sm_b);
708          if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
709             return -1;
710          }
711          //equal range
712          std::pair<typename MyBoostMultiSet::iterator
713                   ,typename MyBoostMultiSet::iterator> bm_ip;
714          std::pair<typename MyStdMultiSet::iterator
715                   ,typename MyStdMultiSet::iterator>   sm_ip;
716          bm_ip = boostmultiset.equal_range(*bm_b);
717          sm_ip = stdmultiset.equal_range(*sm_b);
718          if(!CheckEqualIt(bm_ip.first, sm_ip.first, boostmultiset, stdmultiset)){
719             return -1;
720          }
721          if(!CheckEqualIt(bm_ip.second, sm_ip.second, boostmultiset, stdmultiset)){
722             return -1;
723          }
724          ++bm_b;
725          ++sm_b;
726       }
727    }
728 
729    //Now do count exercise
730    boostset.erase(boostset.begin(), boostset.end());
731    boostmultiset.erase(boostmultiset.begin(), boostmultiset.end());
732    boostset.clear();
733    boostmultiset.clear();
734 
735    for(int j = 0; j < 3; ++j)
736    for(int i = 0; i < 100; ++i){
737       IntType move_me(i);
738       boostset.insert(boost::move(move_me));
739       IntType move_me2(i);
740       boostmultiset.insert(boost::move(move_me2));
741       IntType count_me(i);
742       if(boostset.count(count_me) != typename MyBoostMultiSet::size_type(1)){
743          std::cout << "Error in boostset.count(count_me)" << std::endl;
744          return 1;
745       }
746       if(boostmultiset.count(count_me) != typename MyBoostMultiSet::size_type(j+1)){
747          std::cout << "Error in boostmultiset.count(count_me)" << std::endl;
748          return 1;
749       }
750    }
751 
752    {  //merge
753       ::boost::movelib::unique_ptr<MyBoostSet> const pboostset2 = ::boost::movelib::make_unique<MyBoostSet>();
754       ::boost::movelib::unique_ptr<MyBoostMultiSet> const pboostmultiset2 = ::boost::movelib::make_unique<MyBoostMultiSet>();
755 
756       MyBoostSet &boostset2 = *pboostset2;
757       MyBoostMultiSet &boostmultiset2 = *pboostmultiset2;
758 
759       boostset.clear();
760       boostset2.clear();
761       boostmultiset.clear();
762       boostmultiset2.clear();
763       stdset.clear();
764       stdmultiset.clear();
765 
766       {
767          IntType aux_vect[MaxElem];
768          for(int i = 0; i < MaxElem; ++i){
769             aux_vect[i] = i;
770          }
771 
772          IntType aux_vect2[MaxElem];
773          for(int i = 0; i < MaxElem; ++i){
774             aux_vect2[i] = MaxElem/2+i;
775          }
776          IntType aux_vect3[MaxElem];
777          for(int i = 0; i < MaxElem; ++i){
778             aux_vect3[i] = MaxElem*2/2+i;
779          }
780          boostset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + MaxElem));
781          boostset2.insert(boost::make_move_iterator(&aux_vect2[0]), boost::make_move_iterator(&aux_vect2[0] + MaxElem));
782          boostmultiset2.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0] + MaxElem));
783       }
784       for(int i = 0; i < MaxElem; ++i){
785          stdset.insert(i);
786       }
787       for(int i = 0; i < MaxElem; ++i){
788          stdset.insert(MaxElem/2+i);
789       }
790 
791       boostset.merge(boost::move(boostset2));
792       if(!CheckEqualContainers(boostset, stdset)) return 1;
793 
794       for(int i = 0; i < MaxElem; ++i){
795          stdset.insert(MaxElem*2/2+i);
796       }
797 
798       boostset.merge(boost::move(boostmultiset2));
799       if(!CheckEqualContainers(boostset, stdset)) return 1;
800 
801       boostset.clear();
802       boostset2.clear();
803       boostmultiset.clear();
804       boostmultiset2.clear();
805       stdset.clear();
806       stdmultiset.clear();
807       {
808          IntType aux_vect[MaxElem];
809          for(int i = 0; i < MaxElem; ++i){
810             aux_vect[i] = i;
811          }
812 
813          IntType aux_vect2[MaxElem];
814          for(int i = 0; i < MaxElem; ++i){
815             aux_vect2[i] = MaxElem/2+i;
816          }
817          IntType aux_vect3[MaxElem];
818          for(int i = 0; i < MaxElem; ++i){
819             aux_vect3[i] = MaxElem*2/2+i;
820          }
821          boostmultiset.insert(boost::make_move_iterator(&aux_vect[0]), boost::make_move_iterator(&aux_vect[0] + MaxElem));
822          boostmultiset2.insert(boost::make_move_iterator(&aux_vect2[0]), boost::make_move_iterator(&aux_vect2[0] + MaxElem));
823          boostset2.insert(boost::make_move_iterator(&aux_vect3[0]), boost::make_move_iterator(&aux_vect3[0] + MaxElem));
824       }
825       for(int i = 0; i < MaxElem; ++i){
826          stdmultiset.insert(i);
827       }
828       for(int i = 0; i < MaxElem; ++i){
829          stdmultiset.insert(MaxElem/2+i);
830       }
831       boostmultiset.merge(boost::move(boostmultiset2));
832       if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
833 
834       for(int i = 0; i < MaxElem; ++i){
835          stdmultiset.insert(MaxElem*2/2+i);
836       }
837 
838       boostmultiset.merge(boost::move(boostset2));
839       if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
840    }
841 
842    if(set_test_copyable<MyBoostSet, MyStdSet, MyBoostMultiSet, MyStdMultiSet>
843       (dtl::bool_<boost::container::test::is_copyable<IntType>::value>())){
844       return 1;
845    }
846 
847    return 0;
848 }
849 
850 template<typename SetType>
test_set_methods_with_initializer_list_as_argument_for()851 bool test_set_methods_with_initializer_list_as_argument_for()
852 {
853 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
854    std::initializer_list<int> il = { 1, 2, 3, 4, 5, 5 };
855    std::initializer_list<int> ilu = { 1, 2, 3, 4, 5 };
856    SetType expected(il.begin(), il.end());
857    SetType expectedu(ilu.begin(), ilu.end());
858    {
859       SetType sil((il));
860       if (sil != expected)
861          return false;
862 
863       SetType sila(il, typename SetType::allocator_type());
864       if (sila != expected)
865          return false;
866 
867       SetType silca(il, typename SetType::key_compare(), typename SetType::allocator_type());
868       if (silca != expected)
869          return false;
870 
871       SetType sil_ordered(ordered_unique_range, ilu);
872       if (sil_ordered != expectedu)
873          return false;
874 
875       SetType sil_assign = { 99, 100, 101, 102, 103, 104, 105 };
876       sil_assign = il;
877       if (sil_assign != expected)
878          return false;
879    }
880    {
881       SetType sil;
882       sil.insert(il);
883       if (sil != expected)
884          return false;
885    }
886    return true;
887 #endif
888    return true;
889 }
890 
891 template<typename SetType, typename MultisetType>
instantiate_constructors()892 bool instantiate_constructors()
893 {
894    {
895       typedef typename SetType::value_type value_type;
896       typename SetType::key_compare comp;
897       typename SetType::allocator_type a;
898       value_type value;
899       {
900          SetType s0;
901          SetType s1(comp);
902          SetType s2(a);
903          SetType s3(comp, a);
904       }
905       {
906          SetType s0(&value, &value);
907          SetType s1(&value, &value ,comp);
908          SetType s2(&value, &value ,a);
909          SetType s3(&value, &value ,comp, a);
910       }
911       #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
912       {
913          SetType s0({ 0 });
914          SetType s1({ 0 },comp);
915          SetType s2({ 0 },a);
916          SetType s3({ 0 },comp, a);
917       }
918       {
919          std::initializer_list<value_type> il{0};
920          SetType s0(ordered_unique_range, il);
921          SetType s1(ordered_unique_range, il,comp);
922          SetType s3(ordered_unique_range, il,comp, a);
923       }
924       #endif
925       {
926          SetType s0(ordered_unique_range, &value, &value);
927          SetType s1(ordered_unique_range, &value, &value ,comp);
928          SetType s2(ordered_unique_range, &value, &value ,comp, a);
929       }
930    }
931 
932    {
933       typedef typename MultisetType::value_type value_type;
934       typename MultisetType::key_compare comp;
935       typename MultisetType::allocator_type a;
936       value_type value;
937       {
938          MultisetType s0;
939          MultisetType s1(comp);
940          MultisetType s2(a);
941          MultisetType s3(comp, a);
942       }
943       {
944          MultisetType s0(&value, &value);
945          MultisetType s1(&value, &value ,comp);
946          MultisetType s2(&value, &value ,a);
947          MultisetType s3(&value, &value ,comp, a);
948       }
949       #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
950       {
951          MultisetType s0({ 0 });
952          MultisetType s1({ 0 },comp);
953          MultisetType s2({ 0 },a);
954          MultisetType s3({ 0 },comp, a);
955       }
956       {
957          std::initializer_list<value_type>il{0};
958          MultisetType s0(ordered_range, il);
959          MultisetType s1(ordered_range, il,comp);
960          MultisetType s3(ordered_range, il,comp, a);
961       }
962       #endif
963       {
964          MultisetType s0(ordered_range, &value, &value);
965          MultisetType s1(ordered_range, &value, &value ,comp);
966          MultisetType s2(ordered_range, &value, &value ,comp, a);
967       }
968    }
969    return true;
970 }
971 
972 }  //namespace test{
973 }  //namespace container {
974 }  //namespace boost{
975 
976 #include <boost/container/detail/config_end.hpp>
977 
978 #endif
979