1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
10 #ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
11 #define BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP
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 #include <boost/move/detail/force_ptr.hpp> //adl_move_swap
28 BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
31 EmplaceInt(int a = 0, int b = 0, int c = 0, int d = 0, int e = 0)
32 : a_(a), b_(b), c_(c), d_(d), e_(e)
35 EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
36 : a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
39 EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
49 friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
51 return l.a_ == r.a_ &&
58 friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
59 { return l.sum() < r.sum(); }
61 friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
62 { return l.sum() > r.sum(); }
64 friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
67 friend std::size_t hash_value(const EmplaceInt &v)
68 { return std::size_t(v.a_); }
70 friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
72 os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
77 { a_ = b_ = c_ = d_ = e_ = 0; }
81 { return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
83 int a_, b_, c_, d_, e_;
93 EMPLACE_BACK = 1 << 0,
94 EMPLACE_FRONT = 1 << 1,
95 EMPLACE_BEFORE = 1 << 2,
96 EMPLACE_AFTER = 1 << 3,
97 EMPLACE_ASSOC = 1 << 4,
98 EMPLACE_HINT = 1 << 5,
99 EMPLACE_ASSOC_PAIR = 1 << 6,
100 EMPLACE_HINT_PAIR = 1 << 7
103 template<class Container>
104 bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n, unsigned int cont_offset = 0)
106 typedef typename Container::const_iterator const_iterator;
107 const_iterator itb(ec.begin()), ite(ec.end());
108 unsigned int cur = 0;
109 if(cont_offset > ec.size()){
112 if(only_first_n > (ec.size() - cont_offset)){
115 while(cont_offset--){
118 for(; itb != ite && only_first_n--; ++itb, ++cur){
119 const EmplaceInt & cr = *itb;
120 if(cr != Expected[cur]){
127 template<class Container>
128 bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
130 typedef typename Container::const_iterator const_iterator;
131 const_iterator itb(ec.begin()), ite(ec.end());
132 unsigned int cur = 0;
133 if(only_first_n > ec.size()){
136 for(; itb != ite && only_first_n--; ++itb, ++cur){
137 if(itb->first != Expected[cur].first){
138 std::cout << "Error in first: " << itb->first << ' ' << Expected[cur].first << std::endl;
142 else if(itb->second != Expected[cur].second){
143 std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
150 typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
151 static boost::container::dtl::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
153 static EmplaceIntPair* initialize_emplace_int_pair()
155 EmplaceIntPair* ret = move_detail::force_ptr<EmplaceIntPair*>(&pair_storage);
156 for(unsigned int i = 0; i != 10; ++i){
157 new(&ret->first)EmplaceInt();
158 new(&ret->second)EmplaceInt();
163 static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
166 template<class Container>
167 bool test_emplace_back(dtl::true_)
169 std::cout << "Starting test_emplace_back." << std::endl << " Class: "
170 << typeid(Container).name() << std::endl;
171 static EmplaceInt expected [10];
174 new(&expected [0]) EmplaceInt();
175 new(&expected [1]) EmplaceInt(1);
176 new(&expected [2]) EmplaceInt(1, 2);
177 new(&expected [3]) EmplaceInt(1, 2, 3);
178 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
179 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
181 typedef typename Container::reference reference;
183 reference r = c.emplace_back();
184 if(&r != &c.back() && !test_expected_container(c, &expected[0], 1)){
189 reference r = c.emplace_back(1);
190 if(&r != &c.back() && !test_expected_container(c, &expected[0], 2)){
194 c.emplace_back(1, 2);
195 if(!test_expected_container(c, &expected[0], 3)){
198 c.emplace_back(1, 2, 3);
199 if(!test_expected_container(c, &expected[0], 4)){
202 c.emplace_back(1, 2, 3, 4);
203 if(!test_expected_container(c, &expected[0], 5)){
206 c.emplace_back(1, 2, 3, 4, 5);
207 if(!test_expected_container(c, &expected[0], 6)){
211 std::cout << "...OK" << std::endl;
215 template<class Container>
216 bool test_emplace_back(dtl::false_)
219 template<class Container>
220 bool test_emplace_front(dtl::true_)
222 std::cout << "Starting test_emplace_front." << std::endl << " Class: "
223 << typeid(Container).name() << std::endl;
224 static EmplaceInt expected [10];
226 new(&expected [0]) EmplaceInt(1, 2, 3, 4, 5);
227 new(&expected [1]) EmplaceInt(1, 2, 3, 4);
228 new(&expected [2]) EmplaceInt(1, 2, 3);
229 new(&expected [3]) EmplaceInt(1, 2);
230 new(&expected [4]) EmplaceInt(1);
231 new(&expected [5]) EmplaceInt();
233 typedef typename Container::reference reference;
235 reference r = c.emplace_front();
236 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 5, 1)){
241 reference r = c.emplace_front(1);
242 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 4, 2)){
246 c.emplace_front(1, 2);
247 if(!test_expected_container(c, &expected[0] + 3, 3)){
250 c.emplace_front(1, 2, 3);
251 if(!test_expected_container(c, &expected[0] + 2, 4)){
254 c.emplace_front(1, 2, 3, 4);
255 if(!test_expected_container(c, &expected[0] + 1, 5)){
258 c.emplace_front(1, 2, 3, 4, 5);
259 if(!test_expected_container(c, &expected[0] + 0, 6)){
263 std::cout << "...OK" << std::endl;
267 template<class Container>
268 bool test_emplace_front(dtl::false_)
271 template<class Container>
272 bool test_emplace_before(dtl::true_)
274 std::cout << "Starting test_emplace_before." << std::endl << " Class: "
275 << typeid(Container).name() << std::endl;
276 static EmplaceInt expected [10];
278 new(&expected [0]) EmplaceInt();
279 new(&expected [1]) EmplaceInt(1);
280 new(&expected [2]) EmplaceInt();
282 c.emplace(c.cend(), 1);
283 c.emplace(c.cbegin());
284 if(!test_expected_container(c, &expected[0], 2)){
288 if(!test_expected_container(c, &expected[0], 3)){
293 new(&expected [0]) EmplaceInt();
294 new(&expected [1]) EmplaceInt(1);
295 new(&expected [2]) EmplaceInt(1, 2);
296 new(&expected [3]) EmplaceInt(1, 2, 3);
297 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
298 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
301 c.emplace(c.cbegin(), 1, 2, 3, 4, 5);
302 c.emplace(c.cbegin(), 1, 2, 3, 4);
303 c.emplace(c.cbegin(), 1, 2, 3);
304 c.emplace(c.cbegin(), 1, 2);
305 c.emplace(c.cbegin(), 1);
306 c.emplace(c.cbegin());
307 if(!test_expected_container(c, &expected[0], 6)){
312 typename Container::const_iterator i = c.emplace(c.cend());
313 if(!test_expected_container(c, &expected[0], 1)){
316 i = c.emplace(++i, 1);
317 if(!test_expected_container(c, &expected[0], 2)){
320 i = c.emplace(++i, 1, 2);
321 if(!test_expected_container(c, &expected[0], 3)){
324 i = c.emplace(++i, 1, 2, 3);
325 if(!test_expected_container(c, &expected[0], 4)){
328 i = c.emplace(++i, 1, 2, 3, 4);
329 if(!test_expected_container(c, &expected[0], 5)){
332 i = c.emplace(++i, 1, 2, 3, 4, 5);
333 if(!test_expected_container(c, &expected[0], 6)){
337 //emplace in the middle
338 c.emplace(c.cbegin());
339 if(!test_expected_container(c, &expected[0], 1)){
342 i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
343 if(!test_expected_container(c, &expected[0], 1)){
346 if(!test_expected_container(c, &expected[5], 1, 1)){
349 i = c.emplace(i, 1, 2, 3, 4);
350 if(!test_expected_container(c, &expected[0], 1)){
353 if(!test_expected_container(c, &expected[4], 2, 1)){
356 i = c.emplace(i, 1, 2, 3);
357 if(!test_expected_container(c, &expected[0], 1)){
360 if(!test_expected_container(c, &expected[3], 3, 1)){
363 i = c.emplace(i, 1, 2);
364 if(!test_expected_container(c, &expected[0], 1)){
367 if(!test_expected_container(c, &expected[2], 4, 1)){
371 if(!test_expected_container(c, &expected[0], 6)){
374 std::cout << "...OK" << std::endl;
379 template<class Container>
380 bool test_emplace_before(dtl::false_)
383 template<class Container>
384 bool test_emplace_after(dtl::true_)
386 std::cout << "Starting test_emplace_after." << std::endl << " Class: "
387 << typeid(Container).name() << std::endl;
388 static EmplaceInt expected [10];
390 new(&expected [0]) EmplaceInt();
391 new(&expected [1]) EmplaceInt(1);
392 new(&expected [2]) EmplaceInt();
394 typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
395 c.emplace_after(c.cbefore_begin());
396 if(!test_expected_container(c, &expected[0], 2)){
400 if(!test_expected_container(c, &expected[0], 3)){
405 new(&expected [0]) EmplaceInt();
406 new(&expected [1]) EmplaceInt(1);
407 new(&expected [2]) EmplaceInt(1, 2);
408 new(&expected [3]) EmplaceInt(1, 2, 3);
409 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
410 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
413 c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4, 5);
414 c.emplace_after(c.cbefore_begin(), 1, 2, 3, 4);
415 c.emplace_after(c.cbefore_begin(), 1, 2, 3);
416 c.emplace_after(c.cbefore_begin(), 1, 2);
417 c.emplace_after(c.cbefore_begin(), 1);
418 c.emplace_after(c.cbefore_begin());
419 if(!test_expected_container(c, &expected[0], 6)){
424 typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
425 if(!test_expected_container(c, &expected[0], 1)){
428 i = c.emplace_after(i, 1);
429 if(!test_expected_container(c, &expected[0], 2)){
432 i = c.emplace_after(i, 1, 2);
433 if(!test_expected_container(c, &expected[0], 3)){
436 i = c.emplace_after(i, 1, 2, 3);
437 if(!test_expected_container(c, &expected[0], 4)){
440 i = c.emplace_after(i, 1, 2, 3, 4);
441 if(!test_expected_container(c, &expected[0], 5)){
444 i = c.emplace_after(i, 1, 2, 3, 4, 5);
445 if(!test_expected_container(c, &expected[0], 6)){
449 //emplace_after in the middle
450 i = c.emplace_after(c.cbefore_begin());
451 c.emplace_after(i, 1, 2, 3, 4, 5);
452 c.emplace_after(i, 1, 2, 3, 4);
453 c.emplace_after(i, 1, 2, 3);
454 c.emplace_after(i, 1, 2);
455 c.emplace_after(i, 1);
457 if(!test_expected_container(c, &expected[0], 6)){
460 std::cout << "...OK" << std::endl;
465 template<class Container>
466 bool test_emplace_after(dtl::false_)
469 template<class Container>
470 bool test_emplace_assoc(dtl::true_)
472 std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
473 << typeid(Container).name() << std::endl;
474 static EmplaceInt expected [10];
475 new(&expected [0]) EmplaceInt();
476 new(&expected [1]) EmplaceInt(1);
477 new(&expected [2]) EmplaceInt(1, 2);
478 new(&expected [3]) EmplaceInt(1, 2, 3);
479 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
480 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
484 if(!test_expected_container(c, &expected[0], 1)){
488 if(!test_expected_container(c, &expected[0], 2)){
492 if(!test_expected_container(c, &expected[0], 3)){
496 if(!test_expected_container(c, &expected[0], 4)){
499 c.emplace(1, 2, 3, 4);
500 if(!test_expected_container(c, &expected[0], 5)){
503 c.emplace(1, 2, 3, 4, 5);
504 if(!test_expected_container(c, &expected[0], 6)){
507 std::cout << "...OK" << std::endl;
512 template<class Container>
513 bool test_emplace_assoc(dtl::false_)
516 template<class Container>
517 bool test_emplace_hint(dtl::true_)
519 std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
520 << typeid(Container).name() << std::endl;
521 static EmplaceInt expected [10];
522 new(&expected [0]) EmplaceInt();
523 new(&expected [1]) EmplaceInt(1);
524 new(&expected [2]) EmplaceInt(1, 2);
525 new(&expected [3]) EmplaceInt(1, 2, 3);
526 new(&expected [4]) EmplaceInt(1, 2, 3, 4);
527 new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
531 typename Container::const_iterator it;
532 it = c.emplace_hint(c.begin());
533 if(!test_expected_container(c, &expected[0], 1)){
536 it = c.emplace_hint(it, 1);
537 if(!test_expected_container(c, &expected[0], 2)){
540 it = c.emplace_hint(it, 1, 2);
541 if(!test_expected_container(c, &expected[0], 3)){
544 it = c.emplace_hint(it, 1, 2, 3);
545 if(!test_expected_container(c, &expected[0], 4)){
548 it = c.emplace_hint(it, 1, 2, 3, 4);
549 if(!test_expected_container(c, &expected[0], 5)){
552 it = c.emplace_hint(it, 1, 2, 3, 4, 5);
553 if(!test_expected_container(c, &expected[0], 6)){
556 std::cout << "...OK" << std::endl;
562 template<class Container>
563 bool test_emplace_hint(dtl::false_)
566 template<class Container>
567 bool test_emplace_assoc_pair(dtl::true_)
569 std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
570 << typeid(Container).name() << std::endl;
572 new(&expected_pair[0].first) EmplaceInt();
573 new(&expected_pair[0].second) EmplaceInt();
574 new(&expected_pair[1].first) EmplaceInt(1);
575 new(&expected_pair[1].second) EmplaceInt(1);
576 new(&expected_pair[2].first) EmplaceInt(2);
577 new(&expected_pair[2].second) EmplaceInt(2);
581 if(!test_expected_container(c, &expected_pair[0], 1)){
582 std::cout << "Error after c.emplace();\n";
586 if(!test_expected_container(c, &expected_pair[0], 2)){
587 std::cout << "Error after c.emplace(1);\n";
591 if(!test_expected_container(c, &expected_pair[0], 3)){
592 std::cout << "Error after c.emplace(2, 2);\n";
595 std::cout << "...OK" << std::endl;
600 template<class Container>
601 bool test_emplace_assoc_pair(dtl::false_)
604 template<class Container>
605 bool test_emplace_hint_pair(dtl::true_)
607 std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
608 << typeid(Container).name() << std::endl;
610 new(&expected_pair[0].first) EmplaceInt();
611 new(&expected_pair[0].second) EmplaceInt();
612 new(&expected_pair[1].first) EmplaceInt(1);
613 new(&expected_pair[1].second) EmplaceInt(1);
614 new(&expected_pair[2].first) EmplaceInt(2);
615 new(&expected_pair[2].second) EmplaceInt(2);
618 typename Container::const_iterator it;
619 it = c.emplace_hint(c.begin());
620 if(!test_expected_container(c, &expected_pair[0], 1)){
621 std::cout << "Error after c.emplace(1);\n";
624 it = c.emplace_hint(it, 1, 1);
625 if(!test_expected_container(c, &expected_pair[0], 2)){
626 std::cout << "Error after c.emplace(it, 1);\n";
629 it = c.emplace_hint(it, 2, 2);
630 if(!test_expected_container(c, &expected_pair[0], 3)){
631 std::cout << "Error after c.emplace(it, 2, 2);\n";
634 std::cout << "...OK" << std::endl;
639 template<class Container>
640 bool test_emplace_hint_pair(dtl::false_)
643 template <EmplaceOptions O, EmplaceOptions Mask>
644 struct emplace_active
646 static const bool value = (0 != (O & Mask));
647 typedef dtl::bool_<value> type;
648 operator type() const{ return type(); }
651 template<class Container, EmplaceOptions O>
654 if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>())){
657 if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>())){
660 if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>())){
663 if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>())){
666 if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>())){
669 if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>())){
672 if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>())){
675 if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>())){
682 } //namespace container {
685 #include <boost/container/detail/config_end.hpp>
687 #endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP