Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / container / test / set_test.hpp
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 <memory>
17 #include <set>
18 #include <functional>
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>
23 #include <string>
24
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()
31
32
33 namespace boost{
34 namespace container {
35 namespace test{
36
37 template<class C>
38 void set_test_rebalanceable(C &, boost::container::container_detail::false_type)
39 {}
40
41 template<class C>
42 void set_test_rebalanceable(C &c, boost::container::container_detail::true_type)
43 {
44    c.rebalance();
45 }
46
47 template<class MyBoostSet
48         ,class MyStdSet
49         ,class MyBoostMultiSet
50         ,class MyStdMultiSet>
51 int set_test_copyable(boost::container::container_detail::false_type)
52 {  return 0; }
53
54 template<class MyBoostSet
55         ,class MyStdSet
56         ,class MyBoostMultiSet
57         ,class MyStdMultiSet>
58 int set_test_copyable(boost::container::container_detail::true_type)
59 {
60    typedef typename MyBoostSet::value_type IntType;
61    const int max = 50;
62
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>();
67
68    MyBoostSet &boostset = *pboostset;
69    MyStdSet   &stdset   = *pstdset;
70    MyBoostMultiSet &boostmultiset = *pboostmultiset;
71    MyStdMultiSet   &stdmultiset   = *pstdmultiset;
72
73    for(int i = 0; i < max; ++i){
74       IntType move_me(i);
75       boostset.insert(boost::move(move_me));
76       stdset.insert(i);
77       IntType move_me2(i);
78       boostmultiset.insert(boost::move(move_me2));
79       stdmultiset.insert(i);
80    }
81    if(!CheckEqualContainers(boostset, stdset)) return 1;
82    if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1;
83
84    {
85       //Now, test copy constructor
86       MyBoostSet boostsetcopy(boostset);
87       MyStdSet stdsetcopy(stdset);
88
89       if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
90          return 1;
91
92       MyBoostMultiSet boostmsetcopy(boostmultiset);
93       MyStdMultiSet stdmsetcopy(stdmultiset);
94
95       if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
96          return 1;
97
98       //And now assignment
99       boostsetcopy  =boostset;
100       stdsetcopy  = stdset;
101
102       if(!CheckEqualContainers(boostsetcopy, stdsetcopy))
103          return 1;
104
105       boostmsetcopy = boostmultiset;
106       stdmsetcopy = stdmultiset;
107
108       if(!CheckEqualContainers(boostmsetcopy, stdmsetcopy))
109          return 1;
110    }
111    return 0;
112 }
113
114
115 template<class MyBoostSet
116         ,class MyStdSet
117         ,class MyBoostMultiSet
118         ,class MyStdMultiSet>
119 int set_test ()
120 {
121    typedef typename MyBoostSet::value_type IntType;
122    const int max = 50;
123
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>();
128
129    MyBoostSet &boostset = *pboostset;
130    MyStdSet   &stdset   = *pstdset;
131    MyBoostMultiSet &boostmultiset = *pboostmultiset;
132    MyStdMultiSet   &stdmultiset   = *pstdmultiset;
133
134    //Test construction from a range
135    {
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);
140       }
141       int aux_vect2[50];
142       for(int i = 0; i < 50; ++i){
143          aux_vect2[i] = i/2;
144       }
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);
149       }
150
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);
161
162       MyBoostSet &boostset2 = *pboostset2;
163       MyStdSet   &stdset2   = *pstdset2;
164       MyBoostMultiSet &boostmultiset2 = *pboostmultiset2;
165       MyStdMultiSet   &stdmultiset2   = *pstdmultiset2;
166
167       if(!CheckEqualContainers(boostset2, stdset2)){
168          std::cout << "Error in construct<MyBoostSet>(MyBoostSet2)" << std::endl;
169          return 1;
170       }
171       if(!CheckEqualContainers(boostmultiset2, stdmultiset2)){
172          std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet2)" << std::endl;
173          return 1;
174       }
175
176       //ordered range insertion
177       for(int i = 0; i < 50; ++i){
178          IntType move_me(i);
179          aux_vect[i] = boost::move(move_me);
180       }
181
182       for(int i = 0; i < 50; ++i){
183          aux_vect2[i] = i;
184       }
185
186       for(int i = 0; i < 50; ++i){
187          IntType move_me(i);
188          aux_vect3[i] = boost::move(move_me);
189       }
190
191
192
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>
200             ( ordered_range
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);
205
206       MyBoostSet &boostset3 = *pboostset3;
207       MyStdSet   &stdset3   = *pstdset3;
208       MyBoostMultiSet &boostmultiset3 = *pboostmultiset3;
209       MyStdMultiSet   &stdmultiset3   = *pstdmultiset3;
210
211       if(!CheckEqualContainers(boostset3, stdset3)){
212          std::cout << "Error in construct<MyBoostSet>(MyBoostSet3)" << std::endl;
213          return 1;
214       }
215       if(!CheckEqualContainers(boostmultiset3, stdmultiset3)){
216          std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
217          return 1;
218       }
219    }
220
221    for(int i = 0; i < max; ++i){
222       IntType move_me(i);
223       boostset.insert(boost::move(move_me));
224       stdset.insert(i);
225       boostset.insert(IntType(i));
226       stdset.insert(i);
227       IntType move_me2(i);
228       boostmultiset.insert(boost::move(move_me2));
229       stdmultiset.insert(i);
230       boostmultiset.insert(IntType(i));
231       stdmultiset.insert(i);
232    }
233
234    if(!CheckEqualContainers(boostset, stdset)){
235       std::cout << "Error in boostset.insert(boost::move(move_me)" << std::endl;
236       return 1;
237    }
238
239    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
240       std::cout << "Error in boostmultiset.insert(boost::move(move_me)" << std::endl;
241       return 1;
242    }
243
244    typename MyBoostSet::iterator it = boostset.begin();
245    typename MyBoostSet::const_iterator cit = it;
246    (void)cit;
247
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;
254       return 1;
255    }
256    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
257       std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
258       return 1;
259    }
260
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;
267       return 1;
268    }
269    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
270       std::cout << "Error in boostmultiset.erase(boostmultiset.begin())" << std::endl;
271       return 1;
272    }
273
274    //Swapping test
275    MyBoostSet tmpboosteset2;
276    MyStdSet tmpstdset2;
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;
289       return 1;
290    }
291    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
292       std::cout << "Error in boostmultiset.swap(tmpboostemultiset2)" << std::endl;
293       return 1;
294    }
295
296    //Insertion from other container
297    //Initialize values
298    {
299       IntType aux_vect[50];
300       for(int i = 0; i < 50; ++i){
301          IntType move_me(-1);
302          aux_vect[i] = boost::move(move_me);
303       }
304       int aux_vect2[50];
305       for(int i = 0; i < 50; ++i){
306          aux_vect2[i] = -1;
307       }
308       IntType aux_vect3[50];
309       for(int i = 0; i < 50; ++i){
310          IntType move_me(-1);
311          aux_vect3[i] = boost::move(move_me);
312       }
313
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;
320          return 1;
321       }
322       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
323          std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect3[0]), ..." << std::endl;
324          return 1;
325       }
326
327       for(int i = 0, j = static_cast<int>(boostset.size()); i < j; ++i){
328          IntType erase_me(i);
329          boostset.erase(erase_me);
330          stdset.erase(i);
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;
335             return 1;
336          }
337          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
338             std::cout << "Error in boostmultiset.erase(erase_me)" << std::endl;
339             return 1;
340          }
341       }
342    }
343    {
344       IntType aux_vect[50];
345       for(int i = 0; i < 50; ++i){
346          IntType move_me(-1);
347          aux_vect[i] = boost::move(move_me);
348       }
349       int aux_vect2[50];
350       for(int i = 0; i < 50; ++i){
351          aux_vect2[i] = -1;
352       }
353       IntType aux_vect3[50];
354       for(int i = 0; i < 50; ++i){
355          IntType move_me(-1);
356          aux_vect3[i] = boost::move(move_me);
357       }
358
359       IntType aux_vect4[50];
360       for(int i = 0; i < 50; ++i){
361          IntType move_me(-1);
362          aux_vect4[i] = boost::move(move_me);
363       }
364
365       IntType aux_vect5[50];
366       for(int i = 0; i < 50; ++i){
367          IntType move_me(-1);
368          aux_vect5[i] = boost::move(move_me);
369       }
370
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;
381          return 1;
382       }
383       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
384          std::cout << "Error in boostmultiset.insert(boost::make_move_iterator(&aux_vect5[0])..." << std::endl;
385          return 1;
386       }
387
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;
394          return 1;
395       }
396       if(!CheckEqualContainers(boostmultiset, stdmultiset)){
397          std::cout << "Error in boostmultiset.erase(*boostmultiset.begin())" << std::endl;
398          return 1;
399       }
400    }
401
402    for(int i = 0; i < max; ++i){
403       IntType move_me(i);
404       boostset.insert(boost::move(move_me));
405       stdset.insert(i);
406       IntType move_me2(i);
407       boostmultiset.insert(boost::move(move_me2));
408       stdmultiset.insert(i);
409    }
410
411    if(!CheckEqualContainers(boostset, stdset)){
412       std::cout << "Error in boostset.insert(boost::move(move_me)) try 2" << std::endl;
413       return 1;
414    }
415    if(!CheckEqualContainers(boostmultiset, stdmultiset)){
416       std::cout << "Error in boostmultiset.insert(boost::move(move_me2)) try 2" << std::endl;
417       return 1;
418    }
419
420    for(int i = 0; i < max; ++i){
421       {
422          IntType move_me(i);
423          boostset.insert(boostset.begin(), boost::move(move_me));
424          stdset.insert(stdset.begin(), i);
425          //PrintContainers(boostset, stdset);
426          IntType move_me2(i);
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;
432             return 1;
433          }
434          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
435             std::cout << "Error in boostmultiset.insert(boostmultiset.begin(), boost::move(move_me2))" << std::endl;
436             return 1;
437          }
438
439          IntType move_me3(i);
440          boostset.insert(boostset.end(), boost::move(move_me3));
441          stdset.insert(stdset.end(), i);
442          IntType move_me4(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;
447             return 1;
448          }
449          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
450             std::cout << "Error in boostmultiset.insert(boostmultiset.end(), boost::move(move_me4))" << std::endl;
451             return 1;
452          }
453       }
454       {
455          IntType move_me(i);
456          boostset.insert(boostset.upper_bound(move_me), boost::move(move_me));
457          stdset.insert(stdset.upper_bound(i), i);
458          //PrintContainers(boostset, stdset);
459          IntType move_me2(i);
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;
465             return 1;
466          }
467          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
468             std::cout << "Error in boostmultiset.insert(boostmultiset.upper_bound(move_me2), boost::move(move_me2))" << std::endl;
469             return 1;
470          }
471
472       }
473       {
474          IntType move_me(i);
475          IntType move_me2(i);
476          boostset.insert(boostset.lower_bound(move_me), boost::move(move_me2));
477          stdset.insert(stdset.lower_bound(i), i);
478          //PrintContainers(boostset, stdset);
479          move_me2 = i;
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;
485             return 1;
486          }
487          if(!CheckEqualContainers(boostmultiset, stdmultiset)){
488             std::cout << "Error in boostmultiset.insert(boostmultiset.lower_bound(move_me2), boost::move(move_me2))" << std::endl;
489             return 1;
490          }
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;
495             return 1;
496          }
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;
501             return 1;
502          }
503       }
504    }
505
506    //Compare count with std containers
507    for(int i = 0; i < max; ++i){
508       IntType count_me(i);
509       if(boostset.count(count_me) != stdset.count(i)){
510          return -1;
511       }
512       if(boostmultiset.count(count_me) != stdmultiset.count(i)){
513          return -1;
514       }
515    }
516
517    //Compare find/lower_bound/upper_bound in set
518    {
519       typename MyBoostSet::iterator bs_b = boostset.begin();
520       typename MyBoostSet::iterator bs_e = boostset.end();
521       typename MyStdSet::iterator ss_b   = stdset.begin();
522
523       std::size_t i = 0;
524       while(bs_b != bs_e){
525          ++i;
526          typename MyBoostSet::iterator bs_i;
527          typename MyStdSet::iterator ss_i;
528          //find
529          bs_i = boostset.find(*bs_b);
530          ss_i = stdset.find(*ss_b);
531          if(!CheckEqualIt(bs_i, ss_i, boostset, stdset)){
532             return -1;
533          }
534          //lower bound
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)){
538             return -1;
539          }
540          //upper bound
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)){
544             return -1;
545          }
546          //equal range
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)){
554             return -1;
555          }
556          if(!CheckEqualIt(bs_ip.second, ss_ip.second, boostset, stdset)){
557             return -1;
558          }
559          ++bs_b;
560          ++ss_b;
561       }
562    }
563    //Compare find/lower_bound/upper_bound in multiset
564    {
565       typename MyBoostMultiSet::iterator bm_b = boostmultiset.begin();
566       typename MyBoostMultiSet::iterator bm_e = boostmultiset.end();
567       typename MyStdMultiSet::iterator sm_b   = stdmultiset.begin();
568
569       while(bm_b != bm_e){
570          typename MyBoostMultiSet::iterator bm_i;
571          typename MyStdMultiSet::iterator sm_i;
572          //find
573          bm_i = boostmultiset.find(*bm_b);
574          sm_i = stdmultiset.find(*sm_b);
575          if(!CheckEqualIt(bm_i, sm_i, boostmultiset, stdmultiset)){
576             return -1;
577          }
578          //lower bound
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)){
582             return -1;
583          }
584          //upper bound
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)){
588             return -1;
589          }
590          //equal range
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)){
598             return -1;
599          }
600          if(!CheckEqualIt(bm_ip.second, sm_ip.second, boostmultiset, stdmultiset)){
601             return -1;
602          }
603          ++bm_b;
604          ++sm_b;
605       }
606    }
607
608    //Now do count exercise
609    boostset.erase(boostset.begin(), boostset.end());
610    boostmultiset.erase(boostmultiset.begin(), boostmultiset.end());
611    boostset.clear();
612    boostmultiset.clear();
613
614    for(int j = 0; j < 3; ++j)
615    for(int i = 0; i < 100; ++i){
616       IntType move_me(i);
617       boostset.insert(boost::move(move_me));
618       IntType move_me2(i);
619       boostmultiset.insert(boost::move(move_me2));
620       IntType count_me(i);
621       if(boostset.count(count_me) != typename MyBoostMultiSet::size_type(1)){
622          std::cout << "Error in boostset.count(count_me)" << std::endl;
623          return 1;
624       }
625       if(boostmultiset.count(count_me) != typename MyBoostMultiSet::size_type(j+1)){
626          std::cout << "Error in boostmultiset.count(count_me)" << std::endl;
627          return 1;
628       }
629    }
630
631    if(set_test_copyable<MyBoostSet, MyStdSet, MyBoostMultiSet, MyStdMultiSet>
632       (container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
633       return 1;
634    }
635
636    return 0;
637 }
638
639 }  //namespace test{
640 }  //namespace container {
641 }  //namespace boost{
642
643 #include <boost/container/detail/config_end.hpp>
644
645 #endif