]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/test/emplace_test.hpp
add subtree-ish sources for 12.0.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 static EmplaceInt expected [10];
147
148 typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
149 static boost::container::container_detail::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
150
151 static EmplaceIntPair* initialize_emplace_int_pair()
152 {
153 EmplaceIntPair* ret = reinterpret_cast<EmplaceIntPair*>(&pair_storage);
154 for(unsigned int i = 0; i != 10; ++i){
155 new(&ret->first)EmplaceInt();
156 new(&ret->second)EmplaceInt();
157 }
158 return ret;
159 }
160
161 static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
162
163
164 template<class Container>
165 bool test_emplace_back(container_detail::true_)
166 {
167 std::cout << "Starting test_emplace_back." << std::endl << " Class: "
168 << typeid(Container).name() << std::endl;
169
170 {
171 new(&expected [0]) EmplaceInt();
172 new(&expected [1]) EmplaceInt(1);
173 new(&expected [2]) EmplaceInt(1, 2);
174 new(&expected [3]) EmplaceInt(1, 2, 3);
175 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
176 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
177 Container c;
178 typedef typename Container::reference reference;
179 {
180 reference r = c.emplace_back();
181 if(&r != &c.back() && !test_expected_container(c, &expected[0], 1)){
182 return false;
183 }
184 }
185 {
186 reference r = c.emplace_back(1);
187 if(&r != &c.back() && !test_expected_container(c, &expected[0], 2)){
188 return false;
189 }
190 }
191 c.emplace_back(1, 2);
192 if(!test_expected_container(c, &expected[0], 3)){
193 return false;
194 }
195 c.emplace_back(1, 2, 3);
196 if(!test_expected_container(c, &expected[0], 4)){
197 return false;
198 }
199 c.emplace_back(1, 2, 3, 4);
200 if(!test_expected_container(c, &expected[0], 5)){
201 return false;
202 }
203 c.emplace_back(1, 2, 3, 4, 5);
204 if(!test_expected_container(c, &expected[0], 6)){
205 return false;
206 }
207 }
208 std::cout << "...OK" << std::endl;
209 return true;
210 }
211
212 template<class Container>
213 bool test_emplace_back(container_detail::false_)
214 { return true; }
215
216 template<class Container>
217 bool test_emplace_front(container_detail::true_)
218 {
219 std::cout << "Starting test_emplace_front." << std::endl << " Class: "
220 << typeid(Container).name() << std::endl;
221
222 {
223 new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
224 new(&expected [1]) EmplaceInt(1, 2, 3, 4);
225 new(&expected [2]) EmplaceInt(1, 2, 3);
226 new(&expected [3]) EmplaceInt(1, 2);
227 new(&expected [4]) EmplaceInt(1);
228 new(&expected [5]) EmplaceInt();
229 Container c;
230 typedef typename Container::reference reference;
231 {
232 reference r = c.emplace_front();
233 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 5, 1)){
234 return false;
235 }
236 }
237 {
238 reference r = c.emplace_front(1);
239 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 4, 2)){
240 return false;
241 }
242 }
243 c.emplace_front(1, 2);
244 if(!test_expected_container(c, &expected[0] + 3, 3)){
245 return false;
246 }
247 c.emplace_front(1, 2, 3);
248 if(!test_expected_container(c, &expected[0] + 2, 4)){
249 return false;
250 }
251 c.emplace_front(1, 2, 3, 4);
252 if(!test_expected_container(c, &expected[0] + 1, 5)){
253 return false;
254 }
255 c.emplace_front(1, 2, 3, 4, 5);
256 if(!test_expected_container(c, &expected[0] + 0, 6)){
257 return false;
258 }
259 }
260 std::cout << "...OK" << std::endl;
261 return true;
262 }
263
264 template<class Container>
265 bool test_emplace_front(container_detail::false_)
266 { return true; }
267
268 template<class Container>
269 bool test_emplace_before(container_detail::true_)
270 {
271 std::cout << "Starting test_emplace_before." << std::endl << " Class: "
272 << typeid(Container).name() << std::endl;
273
274 {
275 new(&expected [0]) EmplaceInt();
276 new(&expected [1]) EmplaceInt(1);
277 new(&expected [2]) EmplaceInt();
278 Container c;
279 c.emplace(c.cend(), 1);
280 c.emplace(c.cbegin());
281 if(!test_expected_container(c, &expected[0], 2)){
282 return false;
283 }
284 c.emplace(c.cend());
285 if(!test_expected_container(c, &expected[0], 3)){
286 return false;
287 }
288 }
289 {
290 new(&expected [0]) EmplaceInt();
291 new(&expected [1]) EmplaceInt(1);
292 new(&expected [2]) EmplaceInt(1, 2);
293 new(&expected [3]) EmplaceInt(1, 2, 3);
294 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
295 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
296 //emplace_front-like
297 Container c;
298 c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
299 c.emplace(c.cbegin(), 1, 2, 3, 4);
300 c.emplace(c.cbegin(), 1, 2, 3);
301 c.emplace(c.cbegin(), 1, 2);
302 c.emplace(c.cbegin(), 1);
303 c.emplace(c.cbegin());
304 if(!test_expected_container(c, &expected[0], 6)){
305 return false;
306 }
307 c.clear();
308 //emplace_back-like
309 typename Container::const_iterator i = c.emplace(c.cend());
310 if(!test_expected_container(c, &expected[0], 1)){
311 return false;
312 }
313 i = c.emplace(++i, 1);
314 if(!test_expected_container(c, &expected[0], 2)){
315 return false;
316 }
317 i = c.emplace(++i, 1, 2);
318 if(!test_expected_container(c, &expected[0], 3)){
319 return false;
320 }
321 i = c.emplace(++i, 1, 2, 3);
322 if(!test_expected_container(c, &expected[0], 4)){
323 return false;
324 }
325 i = c.emplace(++i, 1, 2, 3, 4);
326 if(!test_expected_container(c, &expected[0], 5)){
327 return false;
328 }
329 i = c.emplace(++i, 1, 2, 3, 4, 5);
330 if(!test_expected_container(c, &expected[0], 6)){
331 return false;
332 }
333 c.clear();
334 //emplace in the middle
335 c.emplace(c.cbegin());
336 if(!test_expected_container(c, &expected[0], 1)){
337 return false;
338 }
339 i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
340 if(!test_expected_container(c, &expected[0], 1)){
341 return false;
342 }
343 if(!test_expected_container(c, &expected[5], 1, 1)){
344 return false;
345 }
346 i = c.emplace(i, 1, 2, 3, 4);
347 if(!test_expected_container(c, &expected[0], 1)){
348 return false;
349 }
350 if(!test_expected_container(c, &expected[4], 2, 1)){
351 return false;
352 }
353 i = c.emplace(i, 1, 2, 3);
354 if(!test_expected_container(c, &expected[0], 1)){
355 return false;
356 }
357 if(!test_expected_container(c, &expected[3], 3, 1)){
358 return false;
359 }
360 i = c.emplace(i, 1, 2);
361 if(!test_expected_container(c, &expected[0], 1)){
362 return false;
363 }
364 if(!test_expected_container(c, &expected[2], 4, 1)){
365 return false;
366 }
367 i = c.emplace(i, 1);
368 if(!test_expected_container(c, &expected[0], 6)){
369 return false;
370 }
371 std::cout << "...OK" << std::endl;
372 }
373 return true;
374 }
375
376 template<class Container>
377 bool test_emplace_before(container_detail::false_)
378 { return true; }
379
380 template<class Container>
381 bool test_emplace_after(container_detail::true_)
382 {
383 std::cout << "Starting test_emplace_after." << std::endl << " Class: "
384 << typeid(Container).name() << std::endl;
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
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
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