]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/test/emplace_test.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / container / test / emplace_test.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2008. 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 #ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
11 #define BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
12
13 #include <iostream>
14 #include <typeinfo>
15 #include <boost/container/detail/config_begin.hpp>
16 #include <boost/container/detail/workaround.hpp>
17 #include <boost/container/detail/mpl.hpp>
18 #include <boost/move/utility_core.hpp>
19 #include <boost/container/detail/type_traits.hpp>
20
21 namespace boost{
22 namespace container {
23 namespace test{
24
25 class EmplaceInt
26 {
27 BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
28
29 public:
30 EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
31 : a_(a), b_(b), c_(c), d_(d), e_(e)
32 {}
33
34 EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
35 : a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
36 {}
37
38 EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
39 {
40 this->a_ = o.a_;
41 this->b_ = o.b_;
42 this->c_ = o.c_;
43 this->d_ = o.d_;
44 this->e_ = o.e_;
45 return *this;
46 }
47
48 friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
49 {
50 return l.a_ == r.a_ &&
51 l.b_ == r.b_ &&
52 l.c_ == r.c_ &&
53 l.d_ == r.d_ &&
54 l.e_ == r.e_;
55 }
56
57 friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
58 { return l.sum() < r.sum(); }
59
60 friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
61 { return l.sum() > r.sum(); }
62
63 friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
64 { return !(l == r); }
65
66 friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
67 {
68 os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
69 return os;
70 }
71
72 ~EmplaceInt()
73 { a_ = b_ = c_ = d_ = e_ = 0; }
74
75 //private:
76 int sum() const
77 { return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
78
79 int a_, b_, c_, d_, e_;
80 int padding[6];
81 };
82
83
84 } //namespace test {
85
86 namespace test {
87
88 enum EmplaceOptions{
89 EMPLACE_BACK = 1 << 0,
90 EMPLACE_FRONT = 1 << 1,
91 EMPLACE_BEFORE = 1 << 2,
92 EMPLACE_AFTER = 1 << 3,
93 EMPLACE_ASSOC = 1 << 4,
94 EMPLACE_HINT = 1 << 5,
95 EMPLACE_ASSOC_PAIR = 1 << 6,
96 EMPLACE_HINT_PAIR = 1 << 7
97 };
98
99 template<class Container>
100 bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n, unsigned int cont_offset = 0)
101 {
102 typedef typename Container::const_iterator const_iterator;
103 const_iterator itb(ec.begin()), ite(ec.end());
104 unsigned int cur = 0;
105 if(cont_offset > ec.size()){
106 return false;
107 }
108 if(only_first_n > (ec.size() - cont_offset)){
109 return false;
110 }
111 while(cont_offset--){
112 ++itb;
113 }
114 for(; itb != ite && only_first_n--; ++itb, ++cur){
115 const EmplaceInt & cr = *itb;
116 if(cr != Expected[cur]){
117 return false;
118 }
119 }
120 return true;
121 }
122
123 template<class Container>
124 bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
125 {
126 typedef typename Container::const_iterator const_iterator;
127 const_iterator itb(ec.begin()), ite(ec.end());
128 unsigned int cur = 0;
129 if(only_first_n > ec.size()){
130 return false;
131 }
132 for(; itb != ite && only_first_n--; ++itb, ++cur){
133 if(itb->first != Expected[cur].first){
134 std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
135 return false;
136
137 }
138 else if(itb->second != Expected[cur].second){
139 std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
140 return false;
141 }
142 }
143 return true;
144 }
145
146 typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
147 static boost::container::container_detail::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
148
149 static EmplaceIntPair* initialize_emplace_int_pair()
150 {
151 EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
152 for(unsigned int i = 0; i != 10; ++i){
153 new(&ret->first)EmplaceInt();
154 new(&ret->second)EmplaceInt();
155 }
156 return ret;
157 }
158
159 static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
160
161
162 template<class Container>
163 bool test_emplace_back(container_detail::true_)
164 {
165 std::cout << "Starting test_emplace_back." << std::endl << " Class: "
166 << typeid(Container).name() << std::endl;
167 static EmplaceInt expected [10];
168
169 {
170 new(&expected [0]) EmplaceInt();
171 new(&expected [1]) EmplaceInt(1);
172 new(&expected [2]) EmplaceInt(1, 2);
173 new(&expected [3]) EmplaceInt(1, 2, 3);
174 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
175 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
176 Container c;
177 typedef typename Container::reference reference;
178 {
179 reference r = c.emplace_back();
180 if(&r != &c.back() && !test_expected_container(c, &expected[0], 1)){
181 return false;
182 }
183 }
184 {
185 reference r = c.emplace_back(1);
186 if(&r != &c.back() && !test_expected_container(c, &expected[0], 2)){
187 return false;
188 }
189 }
190 c.emplace_back(1, 2);
191 if(!test_expected_container(c, &expected[0], 3)){
192 return false;
193 }
194 c.emplace_back(1, 2, 3);
195 if(!test_expected_container(c, &expected[0], 4)){
196 return false;
197 }
198 c.emplace_back(1, 2, 3, 4);
199 if(!test_expected_container(c, &expected[0], 5)){
200 return false;
201 }
202 c.emplace_back(1, 2, 3, 4, 5);
203 if(!test_expected_container(c, &expected[0], 6)){
204 return false;
205 }
206 }
207 std::cout << "...OK" << std::endl;
208 return true;
209 }
210
211 template<class Container>
212 bool test_emplace_back(container_detail::false_)
213 { return true; }
214
215 template<class Container>
216 bool test_emplace_front(container_detail::true_)
217 {
218 std::cout << "Starting test_emplace_front." << std::endl << " Class: "
219 << typeid(Container).name() << std::endl;
220 static EmplaceInt expected [10];
221 {
222 new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
223 new(&expected [1]) EmplaceInt(1, 2, 3, 4);
224 new(&expected [2]) EmplaceInt(1, 2, 3);
225 new(&expected [3]) EmplaceInt(1, 2);
226 new(&expected [4]) EmplaceInt(1);
227 new(&expected [5]) EmplaceInt();
228 Container c;
229 typedef typename Container::reference reference;
230 {
231 reference r = c.emplace_front();
232 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 5, 1)){
233 return false;
234 }
235 }
236 {
237 reference r = c.emplace_front(1);
238 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 4, 2)){
239 return false;
240 }
241 }
242 c.emplace_front(1, 2);
243 if(!test_expected_container(c, &expected[0] + 3, 3)){
244 return false;
245 }
246 c.emplace_front(1, 2, 3);
247 if(!test_expected_container(c, &expected[0] + 2, 4)){
248 return false;
249 }
250 c.emplace_front(1, 2, 3, 4);
251 if(!test_expected_container(c, &expected[0] + 1, 5)){
252 return false;
253 }
254 c.emplace_front(1, 2, 3, 4, 5);
255 if(!test_expected_container(c, &expected[0] + 0, 6)){
256 return false;
257 }
258 }
259 std::cout << "...OK" << std::endl;
260 return true;
261 }
262
263 template<class Container>
264 bool test_emplace_front(container_detail::false_)
265 { return true; }
266
267 template<class Container>
268 bool test_emplace_before(container_detail::true_)
269 {
270 std::cout << "Starting test_emplace_before." << std::endl << " Class: "
271 << typeid(Container).name() << std::endl;
272 static EmplaceInt expected [10];
273 {
274 new(&expected [0]) EmplaceInt();
275 new(&expected [1]) EmplaceInt(1);
276 new(&expected [2]) EmplaceInt();
277 Container c;
278 c.emplace(c.cend(), 1);
279 c.emplace(c.cbegin());
280 if(!test_expected_container(c, &expected[0], 2)){
281 return false;
282 }
283 c.emplace(c.cend());
284 if(!test_expected_container(c, &expected[0], 3)){
285 return false;
286 }
287 }
288 {
289 new(&expected [0]) EmplaceInt();
290 new(&expected [1]) EmplaceInt(1);
291 new(&expected [2]) EmplaceInt(1, 2);
292 new(&expected [3]) EmplaceInt(1, 2, 3);
293 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
294 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
295 //emplace_front-like
296 Container c;
297 c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
298 c.emplace(c.cbegin(), 1, 2, 3, 4);
299 c.emplace(c.cbegin(), 1, 2, 3);
300 c.emplace(c.cbegin(), 1, 2);
301 c.emplace(c.cbegin(), 1);
302 c.emplace(c.cbegin());
303 if(!test_expected_container(c, &expected[0], 6)){
304 return false;
305 }
306 c.clear();
307 //emplace_back-like
308 typename Container::const_iterator i = c.emplace(c.cend());
309 if(!test_expected_container(c, &expected[0], 1)){
310 return false;
311 }
312 i = c.emplace(++i, 1);
313 if(!test_expected_container(c, &expected[0], 2)){
314 return false;
315 }
316 i = c.emplace(++i, 1, 2);
317 if(!test_expected_container(c, &expected[0], 3)){
318 return false;
319 }
320 i = c.emplace(++i, 1, 2, 3);
321 if(!test_expected_container(c, &expected[0], 4)){
322 return false;
323 }
324 i = c.emplace(++i, 1, 2, 3, 4);
325 if(!test_expected_container(c, &expected[0], 5)){
326 return false;
327 }
328 i = c.emplace(++i, 1, 2, 3, 4, 5);
329 if(!test_expected_container(c, &expected[0], 6)){
330 return false;
331 }
332 c.clear();
333 //emplace in the middle
334 c.emplace(c.cbegin());
335 if(!test_expected_container(c, &expected[0], 1)){
336 return false;
337 }
338 i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
339 if(!test_expected_container(c, &expected[0], 1)){
340 return false;
341 }
342 if(!test_expected_container(c, &expected[5], 1, 1)){
343 return false;
344 }
345 i = c.emplace(i, 1, 2, 3, 4);
346 if(!test_expected_container(c, &expected[0], 1)){
347 return false;
348 }
349 if(!test_expected_container(c, &expected[4], 2, 1)){
350 return false;
351 }
352 i = c.emplace(i, 1, 2, 3);
353 if(!test_expected_container(c, &expected[0], 1)){
354 return false;
355 }
356 if(!test_expected_container(c, &expected[3], 3, 1)){
357 return false;
358 }
359 i = c.emplace(i, 1, 2);
360 if(!test_expected_container(c, &expected[0], 1)){
361 return false;
362 }
363 if(!test_expected_container(c, &expected[2], 4, 1)){
364 return false;
365 }
366 i = c.emplace(i, 1);
367 if(!test_expected_container(c, &expected[0], 6)){
368 return false;
369 }
370 std::cout << "...OK" << std::endl;
371 }
372 return true;
373 }
374
375 template<class Container>
376 bool test_emplace_before(container_detail::false_)
377 { return true; }
378
379 template<class Container>
380 bool test_emplace_after(container_detail::true_)
381 {
382 std::cout << "Starting test_emplace_after." << std::endl << " Class: "
383 << typeid(Container).name() << std::endl;
384 static EmplaceInt expected [10];
385 {
386 new(&expected [0]) EmplaceInt();
387 new(&expected [1]) EmplaceInt(1);
388 new(&expected [2]) EmplaceInt();
389 Container c;
390 typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
391 c.emplace_after(c.cbefore_begin());
392 if(!test_expected_container(c, &expected[0], 2)){
393 return false;
394 }
395 c.emplace_after(i);
396 if(!test_expected_container(c, &expected[0], 3)){
397 return false;
398 }
399 }
400 {
401 new(&expected [0]) EmplaceInt();
402 new(&expected [1]) EmplaceInt(1);
403 new(&expected [2]) EmplaceInt(1, 2);
404 new(&expected [3]) EmplaceInt(1, 2, 3);
405 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
406 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
407 //emplace_front-like
408 Container c;
409 c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
410 c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
411 c.emplace_after(c.cbefore_begin(), 1, 2, 3);
412 c.emplace_after(c.cbefore_begin(), 1, 2);
413 c.emplace_after(c.cbefore_begin(), 1);
414 c.emplace_after(c.cbefore_begin());
415 if(!test_expected_container(c, &expected[0], 6)){
416 return false;
417 }
418 c.clear();
419 //emplace_back-like
420 typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
421 if(!test_expected_container(c, &expected[0], 1)){
422 return false;
423 }
424 i = c.emplace_after(i, 1);
425 if(!test_expected_container(c, &expected[0], 2)){
426 return false;
427 }
428 i = c.emplace_after(i, 1, 2);
429 if(!test_expected_container(c, &expected[0], 3)){
430 return false;
431 }
432 i = c.emplace_after(i, 1, 2, 3);
433 if(!test_expected_container(c, &expected[0], 4)){
434 return false;
435 }
436 i = c.emplace_after(i, 1, 2, 3, 4);
437 if(!test_expected_container(c, &expected[0], 5)){
438 return false;
439 }
440 i = c.emplace_after(i, 1, 2, 3, 4, 5);
441 if(!test_expected_container(c, &expected[0], 6)){
442 return false;
443 }
444 c.clear();
445 //emplace_after in the middle
446 i = c.emplace_after(c.cbefore_begin());
447 c.emplace_after(i, 1, 2, 3, 4, 5);
448 c.emplace_after(i, 1, 2, 3, 4);
449 c.emplace_after(i, 1, 2, 3);
450 c.emplace_after(i, 1, 2);
451 c.emplace_after(i, 1);
452
453 if(!test_expected_container(c, &expected[0], 6)){
454 return false;
455 }
456 std::cout << "...OK" << std::endl;
457 }
458 return true;
459 }
460
461 template<class Container>
462 bool test_emplace_after(container_detail::false_)
463 { return true; }
464
465 template<class Container>
466 bool test_emplace_assoc(container_detail::true_)
467 {
468 std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
469 << typeid(Container).name() << std::endl;
470 static EmplaceInt expected [10];
471 new(&expected [0]) EmplaceInt();
472 new(&expected [1]) EmplaceInt(1);
473 new(&expected [2]) EmplaceInt(1, 2);
474 new(&expected [3]) EmplaceInt(1, 2, 3);
475 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
476 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
477 {
478 Container c;
479 c.emplace();
480 if(!test_expected_container(c, &expected[0], 1)){
481 return false;
482 }
483 c.emplace(1);
484 if(!test_expected_container(c, &expected[0], 2)){
485 return false;
486 }
487 c.emplace(1, 2);
488 if(!test_expected_container(c, &expected[0], 3)){
489 return false;
490 }
491 c.emplace(1, 2, 3);
492 if(!test_expected_container(c, &expected[0], 4)){
493 return false;
494 }
495 c.emplace(1, 2, 3, 4);
496 if(!test_expected_container(c, &expected[0], 5)){
497 return false;
498 }
499 c.emplace(1, 2, 3, 4, 5);
500 if(!test_expected_container(c, &expected[0], 6)){
501 return false;
502 }
503 std::cout << "...OK" << std::endl;
504 }
505 return true;
506 }
507
508 template<class Container>
509 bool test_emplace_assoc(container_detail::false_)
510 { return true; }
511
512 template<class Container>
513 bool test_emplace_hint(container_detail::true_)
514 {
515 std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
516 << typeid(Container).name() << std::endl;
517 static EmplaceInt expected [10];
518 new(&expected [0]) EmplaceInt();
519 new(&expected [1]) EmplaceInt(1);
520 new(&expected [2]) EmplaceInt(1, 2);
521 new(&expected [3]) EmplaceInt(1, 2, 3);
522 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
523 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
524
525 {
526 Container c;
527 typename Container::const_iterator it;
528 it = c.emplace_hint(c.begin());
529 if(!test_expected_container(c, &expected[0], 1)){
530 return false;
531 }
532 it = c.emplace_hint(it, 1);
533 if(!test_expected_container(c, &expected[0], 2)){
534 return false;
535 }
536 it = c.emplace_hint(it, 1, 2);
537 if(!test_expected_container(c, &expected[0], 3)){
538 return false;
539 }
540 it = c.emplace_hint(it, 1, 2, 3);
541 if(!test_expected_container(c, &expected[0], 4)){
542 return false;
543 }
544 it = c.emplace_hint(it, 1, 2, 3, 4);
545 if(!test_expected_container(c, &expected[0], 5)){
546 return false;
547 }
548 it = c.emplace_hint(it, 1, 2, 3, 4, 5);
549 if(!test_expected_container(c, &expected[0], 6)){
550 return false;
551 }
552 std::cout << "...OK" << std::endl;
553 }
554
555 return true;
556 }
557
558 template<class Container>
559 bool test_emplace_hint(container_detail::false_)
560 { return true; }
561
562 template<class Container>
563 bool test_emplace_assoc_pair(container_detail::true_)
564 {
565 std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
566 << typeid(Container).name() << std::endl;
567
568 new(&expected_pair[0].first) EmplaceInt();
569 new(&expected_pair[0].second) EmplaceInt();
570 new(&expected_pair[1].first) EmplaceInt(1);
571 new(&expected_pair[1].second) EmplaceInt(1);
572 new(&expected_pair[2].first) EmplaceInt(2);
573 new(&expected_pair[2].second) EmplaceInt(2);
574 {
575 Container c;
576 c.emplace();
577 if(!test_expected_container(c, &expected_pair[0], 1)){
578 std::cout << "Error after c.emplace();\n";
579 return false;
580 }
581 c.emplace(1, 1);
582 if(!test_expected_container(c, &expected_pair[0], 2)){
583 std::cout << "Error after c.emplace(1);\n";
584 return false;
585 }
586 c.emplace(2, 2);
587 if(!test_expected_container(c, &expected_pair[0], 3)){
588 std::cout << "Error after c.emplace(2, 2);\n";
589 return false;
590 }
591 std::cout << "...OK" << std::endl;
592 }
593 return true;
594 }
595
596 template<class Container>
597 bool test_emplace_assoc_pair(container_detail::false_)
598 { return true; }
599
600 template<class Container>
601 bool test_emplace_hint_pair(container_detail::true_)
602 {
603 std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
604 << typeid(Container).name() << std::endl;
605
606 new(&expected_pair[0].first) EmplaceInt();
607 new(&expected_pair[0].second) EmplaceInt();
608 new(&expected_pair[1].first) EmplaceInt(1);
609 new(&expected_pair[1].second) EmplaceInt(1);
610 new(&expected_pair[2].first) EmplaceInt(2);
611 new(&expected_pair[2].second) EmplaceInt(2);
612 {
613 Container c;
614 typename Container::const_iterator it;
615 it = c.emplace_hint(c.begin());
616 if(!test_expected_container(c, &expected_pair[0], 1)){
617 std::cout << "Error after c.emplace(1);\n";
618 return false;
619 }
620 it = c.emplace_hint(it, 1, 1);
621 if(!test_expected_container(c, &expected_pair[0], 2)){
622 std::cout << "Error after c.emplace(it, 1);\n";
623 return false;
624 }
625 it = c.emplace_hint(it, 2, 2);
626 if(!test_expected_container(c, &expected_pair[0], 3)){
627 std::cout << "Error after c.emplace(it, 2, 2);\n";
628 return false;
629 }
630 std::cout << "...OK" << std::endl;
631 }
632 return true;
633 }
634
635 template<class Container>
636 bool test_emplace_hint_pair(container_detail::false_)
637 { return true; }
638
639 template <EmplaceOptions O, EmplaceOptions Mask>
640 struct emplace_active
641 {
642 static const bool value = (0 != (O & Mask));
643 typedef container_detail::bool_<value> type;
644 operator type() const{ return type(); }
645 };
646
647 template<class Container, EmplaceOptions O>
648 bool test_emplace()
649 {
650 if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>())){
651 return false;
652 }
653 if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>())){
654 return false;
655 }
656 if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>())){
657 return false;
658 }
659 if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>())){
660 return false;
661 }
662 if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>())){
663 return false;
664 }
665 if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>())){
666 return false;
667 }
668 if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>())){
669 return false;
670 }
671 if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>())){
672 return false;
673 }
674 return true;
675 }
676
677 } //namespace test{
678 } //namespace container {
679 } //namespace boost{
680
681 #include <boost/container/detail/config_end.hpp>
682
683 #endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP