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>
27 BOOST_MOVABLE_BUT_NOT_COPYABLE(EmplaceInt)
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)
34 EmplaceInt(BOOST_RV_REF(EmplaceInt) o)
35 : a_(o.a_), b_(o.b_), c_(o.c_), d_(o.d_), e_(o.e_)
38 EmplaceInt& operator=(BOOST_RV_REF(EmplaceInt) o)
48 friend bool operator==(const EmplaceInt &l, const EmplaceInt &r)
50 return l.a_ == r.a_ &&
57 friend bool operator<(const EmplaceInt &l, const EmplaceInt &r)
58 { return l.sum() < r.sum(); }
60 friend bool operator>(const EmplaceInt &l, const EmplaceInt &r)
61 { return l.sum() > r.sum(); }
63 friend bool operator!=(const EmplaceInt &l, const EmplaceInt &r)
66 friend std::ostream &operator <<(std::ostream &os, const EmplaceInt &v)
68 os << "EmplaceInt: " << v.a_ << ' ' << v.b_ << ' ' << v.c_ << ' ' << v.d_ << ' ' << v.e_;
73 { a_ = b_ = c_ = d_ = e_ = 0; }
77 { return this->a_ + this->b_ + this->c_ + this->d_ + this->e_; }
79 int a_, b_, c_, d_, e_;
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
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)
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()){
108 if(only_first_n > (ec.size() - cont_offset)){
111 while(cont_offset--){
114 for(; itb != ite && only_first_n--; ++itb, ++cur){
115 const EmplaceInt & cr = *itb;
116 if(cr != Expected[cur]){
123 template<class Container>
124 bool test_expected_container(const Container &ec, const std::pair<EmplaceInt, EmplaceInt> *Expected, unsigned int only_first_n)
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()){
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;
138 else if(itb->second != Expected[cur].second){
139 std::cout << "Error in second: " << itb->second << ' ' << Expected[cur].second << std::endl;
146 typedef std::pair<EmplaceInt, EmplaceInt> EmplaceIntPair;
147 static boost::container::container_detail::aligned_storage<sizeof(EmplaceIntPair)*10>::type pair_storage;
149 static EmplaceIntPair* initialize_emplace_int_pair()
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();
159 static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
162 template<class Container>
163 bool test_emplace_back(container_detail::true_)
165 std::cout << "Starting test_emplace_back." << std::endl << " Class: "
166 << typeid(Container).name() << std::endl;
167 static EmplaceInt expected [10];
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);
177 typedef typename Container::reference reference;
179 reference r = c.emplace_back();
180 if(&r != &c.back() && !test_expected_container(c, &expected[0], 1)){
185 reference r = c.emplace_back(1);
186 if(&r != &c.back() && !test_expected_container(c, &expected[0], 2)){
190 c.emplace_back(1, 2);
191 if(!test_expected_container(c, &expected[0], 3)){
194 c.emplace_back(1, 2, 3);
195 if(!test_expected_container(c, &expected[0], 4)){
198 c.emplace_back(1, 2, 3, 4);
199 if(!test_expected_container(c, &expected[0], 5)){
202 c.emplace_back(1, 2, 3, 4, 5);
203 if(!test_expected_container(c, &expected[0], 6)){
207 std::cout << "...OK" << std::endl;
211 template<class Container>
212 bool test_emplace_back(container_detail::false_)
215 template<class Container>
216 bool test_emplace_front(container_detail::true_)
218 std::cout << "Starting test_emplace_front." << std::endl << " Class: "
219 << typeid(Container).name() << std::endl;
220 static EmplaceInt expected [10];
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();
229 typedef typename Container::reference reference;
231 reference r = c.emplace_front();
232 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 5, 1)){
237 reference r = c.emplace_front(1);
238 if(&r != &c.front() && !test_expected_container(c, &expected[0] + 4, 2)){
242 c.emplace_front(1, 2);
243 if(!test_expected_container(c, &expected[0] + 3, 3)){
246 c.emplace_front(1, 2, 3);
247 if(!test_expected_container(c, &expected[0] + 2, 4)){
250 c.emplace_front(1, 2, 3, 4);
251 if(!test_expected_container(c, &expected[0] + 1, 5)){
254 c.emplace_front(1, 2, 3, 4, 5);
255 if(!test_expected_container(c, &expected[0] + 0, 6)){
259 std::cout << "...OK" << std::endl;
263 template<class Container>
264 bool test_emplace_front(container_detail::false_)
267 template<class Container>
268 bool test_emplace_before(container_detail::true_)
270 std::cout << "Starting test_emplace_before." << std::endl << " Class: "
271 << typeid(Container).name() << std::endl;
272 static EmplaceInt expected [10];
274 new(&expected [0]) EmplaceInt();
275 new(&expected [1]) EmplaceInt(1);
276 new(&expected [2]) EmplaceInt();
278 c.emplace(c.cend(), 1);
279 c.emplace(c.cbegin());
280 if(!test_expected_container(c, &expected[0], 2)){
284 if(!test_expected_container(c, &expected[0], 3)){
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);
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)){
308 typename Container::const_iterator i = c.emplace(c.cend());
309 if(!test_expected_container(c, &expected[0], 1)){
312 i = c.emplace(++i, 1);
313 if(!test_expected_container(c, &expected[0], 2)){
316 i = c.emplace(++i, 1, 2);
317 if(!test_expected_container(c, &expected[0], 3)){
320 i = c.emplace(++i, 1, 2, 3);
321 if(!test_expected_container(c, &expected[0], 4)){
324 i = c.emplace(++i, 1, 2, 3, 4);
325 if(!test_expected_container(c, &expected[0], 5)){
328 i = c.emplace(++i, 1, 2, 3, 4, 5);
329 if(!test_expected_container(c, &expected[0], 6)){
333 //emplace in the middle
334 c.emplace(c.cbegin());
335 if(!test_expected_container(c, &expected[0], 1)){
338 i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
339 if(!test_expected_container(c, &expected[0], 1)){
342 if(!test_expected_container(c, &expected[5], 1, 1)){
345 i = c.emplace(i, 1, 2, 3, 4);
346 if(!test_expected_container(c, &expected[0], 1)){
349 if(!test_expected_container(c, &expected[4], 2, 1)){
352 i = c.emplace(i, 1, 2, 3);
353 if(!test_expected_container(c, &expected[0], 1)){
356 if(!test_expected_container(c, &expected[3], 3, 1)){
359 i = c.emplace(i, 1, 2);
360 if(!test_expected_container(c, &expected[0], 1)){
363 if(!test_expected_container(c, &expected[2], 4, 1)){
367 if(!test_expected_container(c, &expected[0], 6)){
370 std::cout << "...OK" << std::endl;
375 template<class Container>
376 bool test_emplace_before(container_detail::false_)
379 template<class Container>
380 bool test_emplace_after(container_detail::true_)
382 std::cout << "Starting test_emplace_after." << std::endl << " Class: "
383 << typeid(Container).name() << std::endl;
384 static EmplaceInt expected [10];
386 new(&expected [0]) EmplaceInt();
387 new(&expected [1]) EmplaceInt(1);
388 new(&expected [2]) EmplaceInt();
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)){
396 if(!test_expected_container(c, &expected[0], 3)){
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);
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)){
420 typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
421 if(!test_expected_container(c, &expected[0], 1)){
424 i = c.emplace_after(i, 1);
425 if(!test_expected_container(c, &expected[0], 2)){
428 i = c.emplace_after(i, 1, 2);
429 if(!test_expected_container(c, &expected[0], 3)){
432 i = c.emplace_after(i, 1, 2, 3);
433 if(!test_expected_container(c, &expected[0], 4)){
436 i = c.emplace_after(i, 1, 2, 3, 4);
437 if(!test_expected_container(c, &expected[0], 5)){
440 i = c.emplace_after(i, 1, 2, 3, 4, 5);
441 if(!test_expected_container(c, &expected[0], 6)){
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);
453 if(!test_expected_container(c, &expected[0], 6)){
456 std::cout << "...OK" << std::endl;
461 template<class Container>
462 bool test_emplace_after(container_detail::false_)
465 template<class Container>
466 bool test_emplace_assoc(container_detail::true_)
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);
480 if(!test_expected_container(c, &expected[0], 1)){
484 if(!test_expected_container(c, &expected[0], 2)){
488 if(!test_expected_container(c, &expected[0], 3)){
492 if(!test_expected_container(c, &expected[0], 4)){
495 c.emplace(1, 2, 3, 4);
496 if(!test_expected_container(c, &expected[0], 5)){
499 c.emplace(1, 2, 3, 4, 5);
500 if(!test_expected_container(c, &expected[0], 6)){
503 std::cout << "...OK" << std::endl;
508 template<class Container>
509 bool test_emplace_assoc(container_detail::false_)
512 template<class Container>
513 bool test_emplace_hint(container_detail::true_)
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);
527 typename Container::const_iterator it;
528 it = c.emplace_hint(c.begin());
529 if(!test_expected_container(c, &expected[0], 1)){
532 it = c.emplace_hint(it, 1);
533 if(!test_expected_container(c, &expected[0], 2)){
536 it = c.emplace_hint(it, 1, 2);
537 if(!test_expected_container(c, &expected[0], 3)){
540 it = c.emplace_hint(it, 1, 2, 3);
541 if(!test_expected_container(c, &expected[0], 4)){
544 it = c.emplace_hint(it, 1, 2, 3, 4);
545 if(!test_expected_container(c, &expected[0], 5)){
548 it = c.emplace_hint(it, 1, 2, 3, 4, 5);
549 if(!test_expected_container(c, &expected[0], 6)){
552 std::cout << "...OK" << std::endl;
558 template<class Container>
559 bool test_emplace_hint(container_detail::false_)
562 template<class Container>
563 bool test_emplace_assoc_pair(container_detail::true_)
565 std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
566 << typeid(Container).name() << std::endl;
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);
577 if(!test_expected_container(c, &expected_pair[0], 1)){
578 std::cout << "Error after c.emplace();\n";
582 if(!test_expected_container(c, &expected_pair[0], 2)){
583 std::cout << "Error after c.emplace(1);\n";
587 if(!test_expected_container(c, &expected_pair[0], 3)){
588 std::cout << "Error after c.emplace(2, 2);\n";
591 std::cout << "...OK" << std::endl;
596 template<class Container>
597 bool test_emplace_assoc_pair(container_detail::false_)
600 template<class Container>
601 bool test_emplace_hint_pair(container_detail::true_)
603 std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
604 << typeid(Container).name() << std::endl;
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);
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";
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";
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";
630 std::cout << "...OK" << std::endl;
635 template<class Container>
636 bool test_emplace_hint_pair(container_detail::false_)
639 template <EmplaceOptions O, EmplaceOptions Mask>
640 struct emplace_active
642 static const bool value = (0 != (O & Mask));
643 typedef container_detail::bool_<value> type;
644 operator type() const{ return type(); }
647 template<class Container, EmplaceOptions O>
650 if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>())){
653 if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>())){
656 if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>())){
659 if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>())){
662 if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>())){
665 if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>())){
668 if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>())){
671 if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>())){
678 } //namespace container {
681 #include <boost/container/detail/config_end.hpp>
683 #endif //#ifndef BOOST_CONTAINER_TEST_EMPLACE_TEST_HPP