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