]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/container/test/set_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / container / test / set_test.cpp
CommitLineData
7c673cae
FG
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#include <boost/container/detail/config_begin.hpp>
11#include <set>
12#include <boost/container/set.hpp>
13#include <boost/container/adaptive_pool.hpp>
14
15#include "print_container.hpp"
16#include "movable_int.hpp"
17#include "dummy_test_allocator.hpp"
18#include "set_test.hpp"
19#include "propagate_allocator_test.hpp"
20#include "emplace_test.hpp"
21#include "../../intrusive/test/iterator_test.hpp"
22
23using namespace boost::container;
24
7c673cae
FG
25//Test recursive structures
26class recursive_set
27{
28public:
29 recursive_set & operator=(const recursive_set &x)
30 { id_ = x.id_; set_ = x.set_; return *this; }
31
32 int id_;
33 set<recursive_set> set_;
34 set<recursive_set>::iterator it_;
35 set<recursive_set>::const_iterator cit_;
36 set<recursive_set>::reverse_iterator rit_;
37 set<recursive_set>::const_reverse_iterator crit_;
38
39 friend bool operator< (const recursive_set &a, const recursive_set &b)
40 { return a.id_ < b.id_; }
41};
42
43//Test recursive structures
44class recursive_multiset
45{
46 public:
47 recursive_multiset & operator=(const recursive_multiset &x)
48 { id_ = x.id_; multiset_ = x.multiset_; return *this; }
49
50 int id_;
51 multiset<recursive_multiset> multiset_;
52 multiset<recursive_multiset>::iterator it_;
53 multiset<recursive_multiset>::const_iterator cit_;
54 multiset<recursive_multiset>::reverse_iterator rit_;
55 multiset<recursive_multiset>::const_reverse_iterator crit_;
56
57 friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
58 { return a.id_ < b.id_; }
59};
60
61template<class C>
62void test_move()
63{
64 //Now test move semantics
65 C original;
66 original.emplace();
67 C move_ctor(boost::move(original));
68 C move_assign;
69 move_assign.emplace();
70 move_assign = boost::move(move_ctor);
71 move_assign.swap(original);
72}
73
74bool node_type_test()
75{
76 using namespace boost::container;
77 {
78 typedef set<test::movable_int> set_type;
79 set_type src;
80 {
81 test::movable_int mv_1(1), mv_2(2), mv_3(3);
82 src.emplace(boost::move(mv_1));
83 src.emplace(boost::move(mv_2));
84 src.emplace(boost::move(mv_3));
85 }
86 if(src.size() != 3)
87 return false;
88
89 set_type dst;
90 {
91 test::movable_int mv_3(3);
92 dst.emplace(boost::move(mv_3));
93 }
94
95 if(dst.size() != 1)
96 return false;
97
98 const test::movable_int mv_1(1);
99 const test::movable_int mv_2(2);
100 const test::movable_int mv_3(3);
101 const test::movable_int mv_33(33);
102 set_type::insert_return_type r;
103
104 r = dst.insert(src.extract(mv_33)); // Key version, try to insert empty node
105 if(! (r.position == dst.end() && r.inserted == false && r.node.empty()) )
106 return false;
107 r = dst.insert(src.extract(src.find(mv_1))); // Iterator version, successful
108 if(! (r.position == dst.find(mv_1) && r.inserted == true && r.node.empty()) )
109 return false;
110 r = dst.insert(dst.begin(), src.extract(mv_2)); // Key type version, successful
111 if(! (r.position == dst.find(mv_2) && r.inserted == true && r.node.empty()) )
112 return false;
113 r = dst.insert(src.extract(mv_3)); // Key type version, unsuccessful
114
115 if(!src.empty())
116 return false;
117 if(dst.size() != 3)
118 return false;
119 if(! (r.position == dst.find(mv_3) && r.inserted == false && r.node.value() == mv_3) )
120 return false;
121 }
122
123 {
124 typedef multiset<test::movable_int> multiset_type;
125 multiset_type src;
126 {
127 test::movable_int mv_1(1), mv_2(2), mv_3(3), mv_3bis(3);
128 src.emplace(boost::move(mv_1));
129 src.emplace(boost::move(mv_2));
130 src.emplace(boost::move(mv_3));
131 src.emplace_hint(src.begin(), boost::move(mv_3bis));
132 }
133 if(src.size() != 4)
134 return false;
135
136 multiset_type dst;
137 {
138 test::movable_int mv_3(3);
139 dst.emplace(boost::move(mv_3));
140 }
141
142 if(dst.size() != 1)
143 return false;
144
145 const test::movable_int mv_1(1);
146 const test::movable_int mv_2(2);
147 const test::movable_int mv_3(3);
148 const test::movable_int mv_4(4);
149 multiset_type::iterator r;
150
151 multiset_type::node_type nt(src.extract(mv_3));
152 r = dst.insert(dst.begin(), boost::move(nt));
153 if(! (*r == mv_3 && dst.find(mv_3) == r && nt.empty()) )
154 return false;
155
156 nt = src.extract(src.find(mv_1));
157 r = dst.insert(boost::move(nt)); // Iterator version, successful
158 if(! (*r == mv_1 && nt.empty()) )
159 return false;
160
161 nt = src.extract(mv_2);
162 r = dst.insert(boost::move(nt)); // Key type version, successful
163 if(! (*r == mv_2 && nt.empty()) )
164 return false;
165
166 r = dst.insert(src.extract(mv_3)); // Key type version, successful
167 if(! (*r == mv_3 && r == --multiset_type::iterator(dst.upper_bound(mv_3)) && nt.empty()) )
168 return false;
169
170 r = dst.insert(src.extract(mv_4)); // Key type version, unsuccessful
171 if(! (r == dst.end()) )
172 return false;
173
174 if(!src.empty())
175 return false;
176 if(dst.size() != 5)
177 return false;
178 }
179 return true;
180}
181
182struct boost_container_set;
183struct boost_container_multiset;
184
185namespace boost {
186namespace container {
187namespace test {
188
189template<>
190struct alloc_propagate_base<boost_container_set>
191{
192 template <class T, class Allocator>
193 struct apply
194 {
195 typedef boost::container::set<T, std::less<T>, Allocator> type;
196 };
197};
198
199template<>
200struct alloc_propagate_base<boost_container_multiset>
201{
202 template <class T, class Allocator>
203 struct apply
204 {
205 typedef boost::container::multiset<T, std::less<T>, Allocator> type;
206 };
207};
208
92f5a8d4
TL
209bool constructor_template_auto_deduction_test()
210{
211#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
212 using namespace boost::container;
213 const std::size_t NumElements = 100;
214 {
215 std::set<int> int_set;
216 for (std::size_t i = 0; i != NumElements; ++i) {
217 int_set.insert(static_cast<int>(i));
218 }
219 std::multiset<int> int_mset;
220 for (std::size_t i = 0; i != NumElements; ++i) {
221 int_mset.insert(static_cast<int>(i));
222 }
223
224 typedef std::less<int> comp_int_t;
225 typedef std::allocator<int> alloc_int_t;
226
227 //range
228 {
229 auto fset = set(int_set.begin(), int_set.end());
230 if (!CheckEqualContainers(int_set, fset))
231 return false;
232 auto fmset = multiset(int_mset.begin(), int_mset.end());
233 if (!CheckEqualContainers(int_mset, fmset))
234 return false;
235 }
236 //range+comp
237 {
238 auto fset = set(int_set.begin(), int_set.end(), comp_int_t());
239 if (!CheckEqualContainers(int_set, fset))
240 return false;
241 auto fmset = multiset(int_mset.begin(), int_mset.end(), comp_int_t());
242 if (!CheckEqualContainers(int_mset, fmset))
243 return false;
244 }
245 //range+comp+alloc
246 {
247 auto fset = set(int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t());
248 if (!CheckEqualContainers(int_set, fset))
249 return false;
250 auto fmset = multiset(int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t());
251 if (!CheckEqualContainers(int_mset, fmset))
252 return false;
253 }
254 //range+alloc
255 {
256 auto fset = set(int_set.begin(), int_set.end(), alloc_int_t());
257 if (!CheckEqualContainers(int_set, fset))
258 return false;
259 auto fmset = multiset(int_mset.begin(), int_mset.end(), alloc_int_t());
260 if (!CheckEqualContainers(int_mset, fmset))
261 return false;
262 }
263
264 //ordered_unique_range / ordered_range
265
266 //range
267 {
268 auto fset = set(ordered_unique_range, int_set.begin(), int_set.end());
269 if (!CheckEqualContainers(int_set, fset))
270 return false;
271 auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end());
272 if (!CheckEqualContainers(int_mset, fmset))
273 return false;
274 }
275 //range+comp
276 {
277 auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t());
278 if (!CheckEqualContainers(int_set, fset))
279 return false;
280 auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t());
281 if (!CheckEqualContainers(int_mset, fmset))
282 return false;
283 }
284 //range+comp+alloc
285 {
286 auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), comp_int_t(), alloc_int_t());
287 if (!CheckEqualContainers(int_set, fset))
288 return false;
289 auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), comp_int_t(), alloc_int_t());
290 if (!CheckEqualContainers(int_mset, fmset))
291 return false;
292 }
293 //range+alloc
294 {
295 auto fset = set(ordered_unique_range, int_set.begin(), int_set.end(), alloc_int_t());
296 if (!CheckEqualContainers(int_set, fset))
297 return false;
298 auto fmset = multiset(ordered_range, int_mset.begin(), int_mset.end(), alloc_int_t());
299 if (!CheckEqualContainers(int_mset, fmset))
300 return false;
301 }
302 }
303#endif
304 return true;
305}
306
7c673cae
FG
307}}} //boost::container::test
308
309template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
310struct GetAllocatorSet
311{
312 template<class ValueType>
313 struct apply
314 {
315 typedef set < ValueType
316 , std::less<ValueType>
317 , typename allocator_traits<VoidAllocator>
318 ::template portable_rebind_alloc<ValueType>::type
319 , typename boost::container::tree_assoc_options
320 < boost::container::tree_type<tree_type_value>
321 >::type
322 > set_type;
323
324 typedef multiset < ValueType
325 , std::less<ValueType>
326 , typename allocator_traits<VoidAllocator>
327 ::template portable_rebind_alloc<ValueType>::type
328 , typename boost::container::tree_assoc_options
329 < boost::container::tree_type<tree_type_value>
330 >::type
331 > multiset_type;
332 };
333};
334
7c673cae
FG
335void test_merge_from_different_comparison()
336{
337 set<int> set1;
338 set<int, std::greater<int> > set2;
339 set1.merge(set2);
340}
341
92f5a8d4
TL
342bool test_heterogeneous_lookups()
343{
344 typedef set<int, test::less_transparent> set_t;
345 typedef multiset<int, test::less_transparent> mset_t;
346
347 set_t set1;
348 mset_t mset1;
349
350 const set_t &cset1 = set1;
351 const mset_t &cmset1 = mset1;
352
353 set1.insert(1);
354 set1.insert(1);
355 set1.insert(2);
356 set1.insert(2);
357 set1.insert(3);
358
359 mset1.insert(1);
360 mset1.insert(1);
361 mset1.insert(2);
362 mset1.insert(2);
363 mset1.insert(3);
364
365 const test::non_copymovable_int find_me(2);
366
367 //find
368 if(*set1.find(find_me) != 2)
369 return false;
370 if(*cset1.find(find_me) != 2)
371 return false;
372 if(*mset1.find(find_me) != 2)
373 return false;
374 if(*cmset1.find(find_me) != 2)
375 return false;
376
377 //count
378 if(set1.count(find_me) != 1)
379 return false;
380 if(cset1.count(find_me) != 1)
381 return false;
382 if(mset1.count(find_me) != 2)
383 return false;
384 if(cmset1.count(find_me) != 2)
385 return false;
386
387 //contains
388 if(!set1.contains(find_me))
389 return false;
390 if(!cset1.contains(find_me))
391 return false;
392 if(!mset1.contains(find_me))
393 return false;
394 if(!cmset1.contains(find_me))
395 return false;
396
397 //lower_bound
398 if(*set1.lower_bound(find_me) != 2)
399 return false;
400 if(*cset1.lower_bound(find_me) != 2)
401 return false;
402 if(*mset1.lower_bound(find_me) != 2)
403 return false;
404 if(*cmset1.lower_bound(find_me) != 2)
405 return false;
406
407 //upper_bound
408 if(*set1.upper_bound(find_me) != 3)
409 return false;
410 if(*cset1.upper_bound(find_me) != 3)
411 return false;
412 if(*mset1.upper_bound(find_me) != 3)
413 return false;
414 if(*cmset1.upper_bound(find_me) != 3)
415 return false;
416
417 //equal_range
418 if(*set1.equal_range(find_me).first != 2)
419 return false;
420 if(*cset1.equal_range(find_me).second != 3)
421 return false;
422 if(*mset1.equal_range(find_me).first != 2)
423 return false;
424 if(*cmset1.equal_range(find_me).second != 3)
425 return false;
426
427 return true;
428}
429
7c673cae
FG
430int main ()
431{
432 //Recursive container instantiation
433 {
434 set<recursive_set> set_;
435 multiset<recursive_multiset> multiset_;
436 }
437 //Allocator argument container
438 {
439 set<int> set_((set<int>::allocator_type()));
440 multiset<int> multiset_((multiset<int>::allocator_type()));
441 }
442 //Now test move semantics
443 {
444 test_move<set<recursive_set> >();
445 test_move<multiset<recursive_multiset> >();
446 }
447 //Test std::pair value type as tree has workarounds to make old std::pair
448 //implementations movable that can break things
449 {
b32b8144
FG
450 boost::container::set<std::pair<int,int> > s;
451 std::pair<int,int> p(0, 0);
452 s.insert(p);
453 s.emplace(p);
7c673cae
FG
454 }
455
b32b8144
FG
456 if (!boost::container::test::instantiate_constructors<set<int>, multiset<int> >())
457 return 1;
458
7c673cae
FG
459 test_merge_from_different_comparison();
460
461 ////////////////////////////////////
92f5a8d4 462 // Constructor Template Auto Deduction test
7c673cae 463 ////////////////////////////////////
92f5a8d4 464 if (!test::constructor_template_auto_deduction_test()) {
7c673cae
FG
465 return 1;
466 }
92f5a8d4
TL
467
468 if(!test_heterogeneous_lookups())
7c673cae 469 return 1;
7c673cae
FG
470
471 ////////////////////////////////////
92f5a8d4 472 // Testing allocator implementations
7c673cae 473 ////////////////////////////////////
92f5a8d4
TL
474 {
475 typedef std::set<int> MyStdSet;
476 typedef std::multiset<int> MyStdMultiSet;
477
478 if (0 != test::set_test
479 < GetAllocatorSet<std::allocator<void>, red_black_tree>::apply<int>::set_type
480 , MyStdSet
481 , GetAllocatorSet<std::allocator<void>, red_black_tree>::apply<int>::multiset_type
482 , MyStdMultiSet>()) {
483 std::cout << "Error in set_test<std::allocator<void>, red_black_tree>" << std::endl;
484 return 1;
485 }
486
487 if (0 != test::set_test
488 < GetAllocatorSet<new_allocator<void>, avl_tree>::apply<int>::set_type
489 , MyStdSet
490 , GetAllocatorSet<new_allocator<void>, avl_tree>::apply<int>::multiset_type
491 , MyStdMultiSet>()) {
492 std::cout << "Error in set_test<new_allocator<void>, avl_tree>" << std::endl;
493 return 1;
494 }
495
496 if (0 != test::set_test
497 < GetAllocatorSet<adaptive_pool<void>, scapegoat_tree>::apply<int>::set_type
498 , MyStdSet
499 , GetAllocatorSet<adaptive_pool<void>, scapegoat_tree>::apply<int>::multiset_type
500 , MyStdMultiSet>()) {
501 std::cout << "Error in set_test<adaptive_pool<void>, scapegoat_tree>" << std::endl;
502 return 1;
503 }
504
505 ///////////
506
507 if (0 != test::set_test
508 < GetAllocatorSet<new_allocator<void>, splay_tree>::apply<test::movable_int>::set_type
509 , MyStdSet
510 , GetAllocatorSet<new_allocator<void>, splay_tree>::apply<test::movable_int>::multiset_type
511 , MyStdMultiSet>()) {
512 std::cout << "Error in set_test<new_allocator<void>, splay_tree>" << std::endl;
513 return 1;
514 }
515
516 if (0 != test::set_test
517 < GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::copyable_int>::set_type
518 , MyStdSet
519 , GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::copyable_int>::multiset_type
520 , MyStdMultiSet>()) {
521 std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
522 return 1;
523 }
524
525 if (0 != test::set_test
526 < GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::movable_and_copyable_int>::set_type
527 , MyStdSet
528 , GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::movable_and_copyable_int>::multiset_type
529 , MyStdMultiSet>()) {
530 std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
531 return 1;
532 }
7c673cae
FG
533 }
534
535 ////////////////////////////////////
536 // Emplace testing
537 ////////////////////////////////////
538 const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
539 if(!boost::container::test::test_emplace<set<test::EmplaceInt>, SetOptions>())
540 return 1;
541 if(!boost::container::test::test_emplace<multiset<test::EmplaceInt>, SetOptions>())
542 return 1;
543
544 ////////////////////////////////////
545 // Allocator propagation testing
546 ////////////////////////////////////
547 if(!boost::container::test::test_propagate_allocator<boost_container_set>())
548 return 1;
549
550 if(!boost::container::test::test_propagate_allocator<boost_container_multiset>())
551 return 1;
552
553 if (!boost::container::test::test_set_methods_with_initializer_list_as_argument_for<set<int> >())
554 return 1;
555
556 if (!boost::container::test::test_set_methods_with_initializer_list_as_argument_for<multiset<int> >())
557 return 1;
558
559 ////////////////////////////////////
560 // Test optimize_size option
561 ////////////////////////////////////
562 //
563 // set
564 //
565 typedef set< int*, std::less<int*>, std::allocator<int*>
566 , tree_assoc_options< optimize_size<false>, tree_type<red_black_tree> >::type > rbset_size_optimized_no;
7c673cae 567
7c673cae
FG
568 typedef set< int*, std::less<int*>, std::allocator<int*>
569 , tree_assoc_options< optimize_size<true>, tree_type<avl_tree> >::type > avlset_size_optimized_yes;
7c673cae
FG
570 //
571 // multiset
572 //
7c673cae
FG
573 typedef multiset< int*, std::less<int*>, std::allocator<int*>
574 , tree_assoc_options< optimize_size<true>, tree_type<red_black_tree> >::type > rbmset_size_optimized_yes;
7c673cae
FG
575
576 typedef multiset< int*, std::less<int*>, std::allocator<int*>
577 , tree_assoc_options< optimize_size<false>, tree_type<avl_tree> >::type > avlmset_size_optimized_no;
b32b8144
FG
578
579 BOOST_STATIC_ASSERT(sizeof(rbmset_size_optimized_yes) < sizeof(rbset_size_optimized_no));
580 BOOST_STATIC_ASSERT(sizeof(avlset_size_optimized_yes) < sizeof(avlmset_size_optimized_no));
7c673cae
FG
581
582 ////////////////////////////////////
583 // Iterator testing
584 ////////////////////////////////////
585 {
586 typedef boost::container::set<int> cont_int;
587 cont_int a; a.insert(0); a.insert(1); a.insert(2);
588 boost::intrusive::test::test_iterator_bidirectional< cont_int >(a);
589 if(boost::report_errors() != 0) {
590 return 1;
591 }
592 }
593 {
594 typedef boost::container::multiset<int> cont_int;
595 cont_int a; a.insert(0); a.insert(1); a.insert(2);
596 boost::intrusive::test::test_iterator_bidirectional< cont_int >(a);
597 if(boost::report_errors() != 0) {
598 return 1;
599 }
600 }
601
602 ////////////////////////////////////
603 // Node extraction/insertion testing functions
604 ////////////////////////////////////
605 if(!node_type_test())
606 return 1;
607
92f5a8d4
TL
608 ////////////////////////////////////
609 // has_trivial_destructor_after_move testing
610 ////////////////////////////////////
611 // set, default allocator
612 {
613 typedef boost::container::set<int> cont;
614 typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
615 if (boost::has_trivial_destructor_after_move<cont>::value !=
616 boost::has_trivial_destructor_after_move<tree>::value) {
617 std::cerr << "has_trivial_destructor_after_move(set, default allocator) test failed" << std::endl;
618 return 1;
619 }
620 }
621 // set, std::allocator
622 {
623 typedef boost::container::set<int, std::less<int>, std::allocator<int> > cont;
624 typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
625 if (boost::has_trivial_destructor_after_move<cont>::value !=
626 boost::has_trivial_destructor_after_move<tree>::value) {
627 std::cerr << "has_trivial_destructor_after_move(set, std::allocator) test failed" << std::endl;
628 return 1;
629 }
630 }
631 // multiset, default allocator
632 {
633 typedef boost::container::multiset<int> cont;
634 typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
635 if (boost::has_trivial_destructor_after_move<cont>::value !=
636 boost::has_trivial_destructor_after_move<tree>::value) {
637 std::cerr << "has_trivial_destructor_after_move(multiset, default allocator) test failed" << std::endl;
638 return 1;
639 }
640 }
641 // multiset, std::allocator
642 {
643 typedef boost::container::multiset<int, std::less<int>, std::allocator<int> > cont;
644 typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
645 if (boost::has_trivial_destructor_after_move<cont>::value !=
646 boost::has_trivial_destructor_after_move<tree>::value) {
647 std::cerr << "has_trivial_destructor_after_move(multiset, std::allocator) test failed" << std::endl;
648 return 1;
649 }
650 }
651
7c673cae
FG
652 return 0;
653}
654
655#include <boost/container/detail/config_end.hpp>