]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/test/flat_set_test.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / container / test / flat_set_test.cpp
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 #include <boost/container/detail/config_begin.hpp>
12
13 #include <set>
14
15 #include <boost/container/flat_set.hpp>
16 #include <boost/container/stable_vector.hpp>
17 #include <boost/container/small_vector.hpp>
18 #include <boost/container/deque.hpp>
19 #include <boost/container/static_vector.hpp>
20 #include <boost/container/allocator.hpp>
21 #include <boost/container/detail/container_or_allocator_rebind.hpp>
22
23 #include "print_container.hpp"
24 #include "dummy_test_allocator.hpp"
25 #include "movable_int.hpp"
26 #include "set_test.hpp"
27 #include "propagate_allocator_test.hpp"
28 #include "emplace_test.hpp"
29 #include "container_common_tests.hpp"
30 #include "../../intrusive/test/iterator_test.hpp"
31
32 using namespace boost::container;
33
34 namespace boost {
35 namespace container {
36
37 //Explicit instantiation to detect compilation errors
38
39 //flat_set
40 template class flat_set
41 < test::movable_and_copyable_int
42 , std::less<test::movable_and_copyable_int>
43 , test::simple_allocator<test::movable_and_copyable_int>
44 >;
45
46 template class flat_set
47 < test::movable_and_copyable_int
48 , std::less<test::movable_and_copyable_int>
49 , small_vector<test::movable_and_copyable_int, 10, allocator<test::movable_and_copyable_int> >
50 >;
51
52 //flat_multiset
53 template class flat_multiset
54 < test::movable_and_copyable_int
55 , std::less<test::movable_and_copyable_int>
56 , stable_vector<test::movable_and_copyable_int, test::simple_allocator<test::movable_and_copyable_int> >
57 >;
58
59 template class flat_multiset
60 < test::movable_and_copyable_int
61 , std::less<test::movable_and_copyable_int>
62 , deque<test::movable_and_copyable_int, test::simple_allocator< test::movable_and_copyable_int > >
63 >;
64
65 template class flat_multiset
66 < test::movable_and_copyable_int
67 , std::less<test::movable_and_copyable_int>
68 , static_vector<test::movable_and_copyable_int, 10 >
69 >;
70
71 //As flat container iterators are typedefs for vector::[const_]iterator,
72 //no need to explicit instantiate them
73
74 }} //boost::container
75
76
77 #if (__cplusplus > 201103L)
78 #include <vector>
79
80 namespace boost{
81 namespace container{
82
83 template class flat_set
84 < test::movable_and_copyable_int
85 , std::less<test::movable_and_copyable_int>
86 , std::vector<test::movable_and_copyable_int>
87 >;
88
89 }} //boost::container
90
91 #endif
92
93 //Test recursive structures
94 class recursive_flat_set
95 {
96 public:
97 recursive_flat_set(const recursive_flat_set &c)
98 : id_(c.id_), flat_set_(c.flat_set_)
99 {}
100
101 recursive_flat_set & operator =(const recursive_flat_set &c)
102 {
103 id_ = c.id_;
104 flat_set_= c.flat_set_;
105 return *this;
106 }
107 int id_;
108 flat_set<recursive_flat_set> flat_set_;
109 flat_set<recursive_flat_set>::iterator it_;
110 flat_set<recursive_flat_set>::const_iterator cit_;
111 flat_set<recursive_flat_set>::reverse_iterator rit_;
112 flat_set<recursive_flat_set>::const_reverse_iterator crit_;
113
114 friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b)
115 { return a.id_ < b.id_; }
116 };
117
118
119 //Test recursive structures
120 class recursive_flat_multiset
121 {
122 public:
123 recursive_flat_multiset(const recursive_flat_multiset &c)
124 : id_(c.id_), flat_multiset_(c.flat_multiset_)
125 {}
126
127 recursive_flat_multiset & operator =(const recursive_flat_multiset &c)
128 {
129 id_ = c.id_;
130 flat_multiset_= c.flat_multiset_;
131 return *this;
132 }
133 int id_;
134 flat_multiset<recursive_flat_multiset> flat_multiset_;
135 flat_multiset<recursive_flat_multiset>::iterator it_;
136 flat_multiset<recursive_flat_multiset>::const_iterator cit_;
137 flat_multiset<recursive_flat_multiset>::reverse_iterator rit_;
138 flat_multiset<recursive_flat_multiset>::const_reverse_iterator crit_;
139
140 friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b)
141 { return a.id_ < b.id_; }
142 };
143
144
145 template<class C>
146 void test_move()
147 {
148 //Now test move semantics
149 C original;
150 C move_ctor(boost::move(original));
151 C move_assign;
152 move_assign = boost::move(move_ctor);
153 move_assign.swap(original);
154 }
155
156 namespace boost{
157 namespace container {
158 namespace test{
159
160 bool flat_tree_ordered_insertion_test()
161 {
162 using namespace boost::container;
163 const std::size_t NumElements = 100;
164
165 //Ordered insertion multiset
166 {
167 std::multiset<int> int_mset;
168 for(std::size_t i = 0; i != NumElements; ++i){
169 int_mset.insert(static_cast<int>(i));
170 }
171 //Construction insertion
172 flat_multiset<int> fmset(ordered_range, int_mset.begin(), int_mset.end());
173 if(!CheckEqualContainers(int_mset, fmset))
174 return false;
175 //Insertion when empty
176 fmset.clear();
177 fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
178 if(!CheckEqualContainers(int_mset, fmset))
179 return false;
180 //Re-insertion
181 fmset.insert(ordered_range, int_mset.begin(), int_mset.end());
182 std::multiset<int> int_mset2(int_mset);
183 int_mset2.insert(int_mset.begin(), int_mset.end());
184 if(!CheckEqualContainers(int_mset2, fmset))
185 return false;
186 //Re-re-insertion
187 fmset.insert(ordered_range, int_mset2.begin(), int_mset2.end());
188 std::multiset<int> int_mset4(int_mset2);
189 int_mset4.insert(int_mset2.begin(), int_mset2.end());
190 if(!CheckEqualContainers(int_mset4, fmset))
191 return false;
192 //Re-re-insertion of even
193 std::multiset<int> int_even_mset;
194 for(std::size_t i = 0; i < NumElements; i+=2){
195 int_mset.insert(static_cast<int>(i));
196 }
197 fmset.insert(ordered_range, int_even_mset.begin(), int_even_mset.end());
198 int_mset4.insert(int_even_mset.begin(), int_even_mset.end());
199 if(!CheckEqualContainers(int_mset4, fmset))
200 return false;
201
202 //Re-re-insertion using in-place merge
203 fmset.reserve(fmset.size() + int_mset2.size());
204 fmset.insert(ordered_range, int_mset2.begin(), int_mset2.end());
205 std::multiset<int> int_mset5(int_mset2);
206 int_mset4.insert(int_mset5.begin(), int_mset5.end());
207 if(!CheckEqualContainers(int_mset4, fmset))
208 return false;
209 //Re-re-insertion of even
210 std::multiset<int> int_even_mset2;
211 for(std::size_t i = 0; i < NumElements; i+=2){
212 int_even_mset2.insert(static_cast<int>(i));
213 }
214 fmset.reserve(fmset.size() + int_even_mset2.size());
215 fmset.insert(ordered_range, int_even_mset2.begin(), int_even_mset2.end());
216 int_mset4.insert(int_even_mset2.begin(), int_even_mset2.end());
217 if(!CheckEqualContainers(int_mset4, fmset))
218 return false;
219 }
220
221 //Ordered insertion set
222 {
223 std::set<int> int_set;
224 for(std::size_t i = 0; i != NumElements; ++i){
225 int_set.insert(static_cast<int>(i));
226 }
227 //Construction insertion
228 flat_set<int> fset(ordered_unique_range, int_set.begin(), int_set.end());
229 if(!CheckEqualContainers(int_set, fset))
230 return false;
231 //Insertion when empty
232 fset.clear();
233 fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
234 if(!CheckEqualContainers(int_set, fset))
235 return false;
236 //Re-insertion
237 fset.insert(ordered_unique_range, int_set.begin(), int_set.end());
238 std::set<int> int_set2(int_set);
239 int_set2.insert(int_set.begin(), int_set.end());
240 if(!CheckEqualContainers(int_set2, fset))
241 return false;
242 //Re-re-insertion
243 fset.insert(ordered_unique_range, int_set2.begin(), int_set2.end());
244 std::set<int> int_set4(int_set2);
245 int_set4.insert(int_set2.begin(), int_set2.end());
246 if(!CheckEqualContainers(int_set4, fset))
247 return false;
248 //Re-re-insertion of even
249 std::set<int> int_even_set;
250 for(std::size_t i = 0; i < NumElements; i+=2){
251 int_even_set.insert(static_cast<int>(i));
252 }
253 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
254 int_set4.insert(int_even_set.begin(), int_even_set.end());
255 if(!CheckEqualContainers(int_set4, fset))
256 return false;
257 //Partial Re-re-insertion of even
258 int_even_set.clear();
259 for(std::size_t i = 0; i < NumElements; i+=4){
260 int_even_set.insert(static_cast<int>(i));
261 }
262 fset.clear();
263 int_set4.clear();
264 //insert 0,4,8,12...
265 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
266 int_set4.insert(int_even_set.begin(), int_even_set.end());
267 if(!CheckEqualContainers(int_set4, fset))
268 return false;
269 for(std::size_t i = 2; i < NumElements; i+=4){
270 int_even_set.insert(static_cast<int>(i));
271 }
272 //insert 0,2,4,6,8,10,12...
273 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
274 int_set4.insert(int_even_set.begin(), int_even_set.end());
275 if(!CheckEqualContainers(int_set4, fset))
276 return false;
277 int_even_set.clear();
278 for(std::size_t i = 0; i < NumElements; i+=8){
279 int_even_set.insert(static_cast<int>(i));
280 }
281 fset.clear();
282 int_set4.clear();
283 //insert 0,8,16...
284 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
285 int_set4.insert(int_even_set.begin(), int_even_set.end());
286 if(!CheckEqualContainers(int_set4, fset))
287 return false;
288 for(std::size_t i = 0; i < NumElements; i+=2){
289 int_even_set.insert(static_cast<int>(i));
290 }
291 //insert 0,2,4,6,8,10,12...
292 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
293 int_set4.insert(int_even_set.begin(), int_even_set.end());
294 if(!CheckEqualContainers(int_set4, fset))
295 return false;
296
297
298 int_even_set.clear();
299 for(std::size_t i = 0; i < NumElements; i+=8){
300 int_even_set.insert(static_cast<int>(i));
301 int_even_set.insert(static_cast<int>(i+2));
302 }
303 int_even_set.insert(static_cast<int>(NumElements-2));
304 fset.clear();
305 int_set4.clear();
306 //insert 0,2,8,10...
307 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
308 int_set4.insert(int_even_set.begin(), int_even_set.end());
309 if(!CheckEqualContainers(int_set4, fset))
310 return false;
311 for(std::size_t i = 0; i < NumElements; i+=2){
312 int_even_set.insert(static_cast<int>(i));
313 }
314 //insert 0,2,4,6,8,10,12...
315 fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end());
316 int_set4.insert(int_even_set.begin(), int_even_set.end());
317 if(!CheckEqualContainers(int_set4, fset))
318 return false;
319 }
320
321 return true;
322 }
323
324 template< class RandomIt >
325 void random_shuffle( RandomIt first, RandomIt last )
326 {
327 typedef typename boost::container::iterator_traits<RandomIt>::difference_type difference_type;
328 difference_type n = last - first;
329 for (difference_type i = n-1; i > 0; --i) {
330 difference_type j = std::rand() % (i+1);
331 if(j != i) {
332 boost::adl_move_swap(first[i], first[j]);
333 }
334 }
335 }
336
337 bool flat_tree_extract_adopt_test()
338 {
339 using namespace boost::container;
340 const std::size_t NumElements = 100;
341
342 //extract/adopt set
343 {
344 //Construction insertion
345 flat_set<int> fset;
346
347 for(std::size_t i = 0; i != NumElements; ++i){
348 fset.insert(static_cast<int>(i));
349 }
350
351 flat_set<int> fset_copy(fset);
352 flat_set<int>::sequence_type seq(fset.extract_sequence());
353 if(!fset.empty())
354 return false;
355 if(!CheckEqualContainers(seq, fset_copy))
356 return false;
357
358 seq.insert(seq.end(), fset_copy.begin(), fset_copy.end());
359 boost::container::test::random_shuffle(seq.begin(), seq.end());
360 fset.adopt_sequence(boost::move(seq));
361 if(!CheckEqualContainers(fset, fset_copy))
362 return false;
363 }
364
365 //extract/adopt set, ordered_unique_range
366 {
367 //Construction insertion
368 flat_set<int> fset;
369
370 for(std::size_t i = 0; i != NumElements; ++i){
371 fset.insert(static_cast<int>(i));
372 }
373
374 flat_set<int> fset_copy(fset);
375 flat_set<int>::sequence_type seq(fset.extract_sequence());
376 if(!fset.empty())
377 return false;
378 if(!CheckEqualContainers(seq, fset_copy))
379 return false;
380
381 fset.adopt_sequence(ordered_unique_range, boost::move(seq));
382 if(!CheckEqualContainers(fset, fset_copy))
383 return false;
384 }
385
386 //extract/adopt multiset
387 {
388 //Construction insertion
389 flat_multiset<int> fmset;
390
391 for(std::size_t i = 0; i != NumElements; ++i){
392 fmset.insert(static_cast<int>(i));
393 fmset.insert(static_cast<int>(i));
394 }
395
396 flat_multiset<int> fmset_copy(fmset);
397 flat_multiset<int>::sequence_type seq(fmset.extract_sequence());
398 if(!fmset.empty())
399 return false;
400 if(!CheckEqualContainers(seq, fmset_copy))
401 return false;
402
403 boost::container::test::random_shuffle(seq.begin(), seq.end());
404 fmset.adopt_sequence(boost::move(seq));
405 if(!CheckEqualContainers(fmset, fmset_copy))
406 return false;
407 }
408
409 //extract/adopt multiset, ordered_range
410 {
411 //Construction insertion
412 flat_multiset<int> fmset;
413
414 for(std::size_t i = 0; i != NumElements; ++i){
415 fmset.insert(static_cast<int>(i));
416 fmset.insert(static_cast<int>(i));
417 }
418
419 flat_multiset<int> fmset_copy(fmset);
420 flat_multiset<int>::sequence_type seq(fmset.extract_sequence());
421 if(!fmset.empty())
422 return false;
423 if(!CheckEqualContainers(seq, fmset_copy))
424 return false;
425
426 fmset.adopt_sequence(ordered_range, boost::move(seq));
427 if(!CheckEqualContainers(fmset, fmset_copy))
428 return false;
429 }
430
431 return true;
432 }
433
434 }}}
435
436 template<class VoidAllocatorOrContainer>
437 struct GetSetContainer
438 {
439 template<class ValueType>
440 struct apply
441 {
442 typedef flat_set < ValueType
443 , std::less<ValueType>
444 , typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
445 > set_type;
446
447 typedef flat_multiset < ValueType
448 , std::less<ValueType>
449 , typename boost::container::container_detail::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
450 > multiset_type;
451 };
452 };
453
454 template<class VoidAllocator>
455 int test_set_variants()
456 {
457 typedef typename GetSetContainer<VoidAllocator>::template apply<int>::set_type MySet;
458 typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::set_type MyMoveSet;
459 typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::set_type MyCopyMoveSet;
460 typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::set_type MyCopySet;
461
462 typedef typename GetSetContainer<VoidAllocator>::template apply<int>::multiset_type MyMultiSet;
463 typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_int>::multiset_type MyMoveMultiSet;
464 typedef typename GetSetContainer<VoidAllocator>::template apply<test::movable_and_copyable_int>::multiset_type MyCopyMoveMultiSet;
465 typedef typename GetSetContainer<VoidAllocator>::template apply<test::copyable_int>::multiset_type MyCopyMultiSet;
466
467 typedef std::set<int> MyStdSet;
468 typedef std::multiset<int> MyStdMultiSet;
469
470 if (0 != test::set_test<
471 MySet
472 ,MyStdSet
473 ,MyMultiSet
474 ,MyStdMultiSet>()){
475 std::cout << "Error in set_test<MyBoostSet>" << std::endl;
476 return 1;
477 }
478
479 if (0 != test::set_test<
480 MyMoveSet
481 ,MyStdSet
482 ,MyMoveMultiSet
483 ,MyStdMultiSet>()){
484 std::cout << "Error in set_test<MyBoostSet>" << std::endl;
485 return 1;
486 }
487
488 if (0 != test::set_test<
489 MyCopyMoveSet
490 ,MyStdSet
491 ,MyCopyMoveMultiSet
492 ,MyStdMultiSet>()){
493 std::cout << "Error in set_test<MyBoostSet>" << std::endl;
494 return 1;
495 }
496
497 if (0 != test::set_test<
498 MyCopySet
499 ,MyStdSet
500 ,MyCopyMultiSet
501 ,MyStdMultiSet>()){
502 std::cout << "Error in set_test<MyBoostSet>" << std::endl;
503 return 1;
504 }
505
506 return 0;
507 }
508
509
510 template<typename FlatSetType>
511 bool test_support_for_initialization_list_for()
512 {
513 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
514 const std::initializer_list<int> il
515 = {1, 2};
516
517 const FlatSetType expected(il.begin(), il.end());
518 {
519 const FlatSetType sil = il;
520 if (sil != expected)
521 return false;
522
523 const FlatSetType sil_ordered(ordered_unique_range, il);
524 if(sil_ordered != expected)
525 return false;
526
527 FlatSetType sil_assign = {99};
528 sil_assign = il;
529 if(sil_assign != expected)
530 return false;
531 }
532 {
533 FlatSetType sil;
534 sil.insert(il);
535 if(sil != expected)
536 return false;
537 }
538 return true;
539 #endif
540 return true;
541 }
542
543 struct boost_container_flat_set;
544 struct boost_container_flat_multiset;
545
546 namespace boost {
547 namespace container {
548 namespace test {
549
550 template<>
551 struct alloc_propagate_base<boost_container_flat_set>
552 {
553 template <class T, class Allocator>
554 struct apply
555 {
556 typedef boost::container::flat_set<T, std::less<T>, Allocator> type;
557 };
558 };
559
560 template<>
561 struct alloc_propagate_base<boost_container_flat_multiset>
562 {
563 template <class T, class Allocator>
564 struct apply
565 {
566 typedef boost::container::flat_multiset<T, std::less<T>, Allocator> type;
567 };
568 };
569
570 }}} //boost::container::test
571
572 int main()
573 {
574 using namespace boost::container::test;
575
576 //Allocator argument container
577 {
578 flat_set<int> set_((flat_set<int>::allocator_type()));
579 flat_multiset<int> multiset_((flat_multiset<int>::allocator_type()));
580 }
581 //Now test move semantics
582 {
583 test_move<flat_set<recursive_flat_set> >();
584 test_move<flat_multiset<recursive_flat_multiset> >();
585 }
586 //Now test nth/index_of
587 {
588 flat_set<int> set;
589 flat_multiset<int> mset;
590
591 set.insert(0);
592 set.insert(1);
593 set.insert(2);
594 mset.insert(0);
595 mset.insert(1);
596 mset.insert(2);
597 if(!boost::container::test::test_nth_index_of(set))
598 return 1;
599 if(!boost::container::test::test_nth_index_of(mset))
600 return 1;
601 }
602
603 ////////////////////////////////////
604 // Ordered insertion test
605 ////////////////////////////////////
606 if(!flat_tree_ordered_insertion_test()){
607 return 1;
608 }
609
610 ////////////////////////////////////
611 // Extract/Adopt test
612 ////////////////////////////////////
613 if(!flat_tree_extract_adopt_test()){
614 return 1;
615 }
616
617 if (!boost::container::test::instantiate_constructors<flat_set<int>, flat_multiset<int> >())
618 return 1;
619
620 ////////////////////////////////////
621 // Testing allocator implementations
622 ////////////////////////////////////
623 // std::allocator
624 if(test_set_variants< std::allocator<void> >()){
625 std::cerr << "test_set_variants< std::allocator<void> > failed" << std::endl;
626 return 1;
627 }
628 // boost::container::allocator
629 if(test_set_variants< allocator<void> >()){
630 std::cerr << "test_set_variants< allocator<void> > failed" << std::endl;
631 return 1;
632 }
633
634 ////////////////////////////////////
635 // Emplace testing
636 ////////////////////////////////////
637 const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
638
639 if(!boost::container::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
640 return 1;
641 if(!boost::container::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
642 return 1;
643
644 if (!boost::container::test::test_set_methods_with_initializer_list_as_argument_for<flat_set<int> >())
645 return 1;
646
647 if (!boost::container::test::test_set_methods_with_initializer_list_as_argument_for<flat_multiset<int> >())
648 return 1;
649
650 ////////////////////////////////////
651 // Allocator propagation testing
652 ////////////////////////////////////
653 if(!boost::container::test::test_propagate_allocator<boost_container_flat_set>())
654 return 1;
655
656 if(!boost::container::test::test_propagate_allocator<boost_container_flat_multiset>())
657 return 1;
658
659 ////////////////////////////////////
660 // Iterator testing
661 ////////////////////////////////////
662 {
663 typedef boost::container::flat_set<int> cont_int;
664 cont_int a; a.insert(0); a.insert(1); a.insert(2);
665 boost::intrusive::test::test_iterator_random< cont_int >(a);
666 if(boost::report_errors() != 0) {
667 return 1;
668 }
669 }
670 {
671 typedef boost::container::flat_multiset<int> cont_int;
672 cont_int a; a.insert(0); a.insert(1); a.insert(2);
673 boost::intrusive::test::test_iterator_random< cont_int >(a);
674 if(boost::report_errors() != 0) {
675 return 1;
676 }
677 }
678
679 return 0;
680 }
681
682 #include <boost/container/detail/config_end.hpp>
683