• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // \(C\) Copyright Benedek Thaler 2015-2016
4 // \(C\) Copyright Ion Gaztanaga 2019-2020. Distributed under the Boost
5 // Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // See http://www.boost.org/libs/container for documentation.
9 //
10 //////////////////////////////////////////////////////////////////////////////
11 
12 #include <boost/core/lightweight_test.hpp>
13 #include <cstring> // memcmp
14 #include <iostream>
15 #include <algorithm>
16 #include <limits>
17 #include <boost/container/list.hpp>
18 #include <boost/container/vector.hpp>
19 #include <boost/core/no_exceptions_support.hpp>
20 #include <boost/type_traits/is_default_constructible.hpp>
21 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
22 #include "dummy_test_allocator.hpp"
23 #include "propagate_allocator_test.hpp"
24 #include "check_equal_containers.hpp"
25 #include "movable_int.hpp"
26 
27 #include <boost/algorithm/cxx14/equal.hpp>
28 
29 #define BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
30 #include <boost/container/devector.hpp>
31 #undef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
32 
33 #include "test_util.hpp"
34 #include "test_elem.hpp"
35 #include "input_iterator.hpp"
36 
37 using namespace boost::container;
38 
39 struct boost_container_devector;
40 
41 #ifdef _MSC_VER
42    #pragma warning (push)
43    #pragma warning (disable : 4127) // conditional expression is constant
44 #endif
45 
46 namespace boost {
47 namespace container {
48 namespace test {
49 
50 template<>
51 struct alloc_propagate_base<boost_container_devector>
52 {
53    template <class T, class Allocator>
54    struct apply
55    {
56       typedef devector<T, Allocator> type;
57    };
58 };
59 
60 }}}   //namespace boost::container::test {
61 
62 struct different_growth_policy
63 {
64   template <typename SizeType>
new_capacitydifferent_growth_policy65   static SizeType new_capacity(SizeType capacity)
66   {
67     return (capacity) ? capacity * 4u : 32u;
68   }
69 };
70 
71 // END HELPERS
72 
test_constructor_default()73 template <class Devector> void test_constructor_default()
74 {
75   Devector a;
76 
77   BOOST_TEST(a.empty());
78   BOOST_TEST(a.get_alloc_count() == 0u);
79   BOOST_TEST(a.capacity() == 0u);
80 }
81 
test_constructor_allocator()82 template <class Devector> void test_constructor_allocator()
83 {
84   typename Devector::allocator_type alloc_template;
85 
86   Devector a(alloc_template);
87 
88   BOOST_TEST(a.empty());
89   BOOST_TEST(a.get_alloc_count() == 0u);
90   BOOST_TEST(a.capacity() == 0u);
91 }
92 
test_constructor_reserve_only()93 template <class Devector> void test_constructor_reserve_only()
94 {
95   {
96     Devector a(16, reserve_only_tag_t());
97     BOOST_TEST(a.size() == 0u);
98     BOOST_TEST(a.capacity() >= 16u);
99   }
100 
101   {
102     Devector b(0, reserve_only_tag_t());
103     BOOST_TEST(b.get_alloc_count() == 0u);
104   }
105 }
106 
test_constructor_reserve_only_front_back()107 template <class Devector> void test_constructor_reserve_only_front_back()
108 {
109   {
110     Devector a(8, 8, reserve_only_tag_t());
111     BOOST_TEST(a.size() == 0u);
112     BOOST_TEST(a.capacity() >= 16u);
113 
114     for (int i = 8; i; --i)
115     {
116       a.emplace_front(i);
117     }
118 
119     for (int i = 9; i < 17; ++i)
120     {
121       a.emplace_back(i);
122     }
123 
124     const int expected [] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
125     test_equal_range(a, expected);
126     BOOST_TEST(a.get_alloc_count() <= 1u);
127   }
128 
129   {
130     Devector b(0, 0, reserve_only_tag_t());
131     BOOST_TEST(b.get_alloc_count() == 0u);
132   }
133 }
134 
test_constructor_n()135 template <class Devector> void test_constructor_n()
136 {
137    {
138       Devector a(8);
139       const int expected [] = {0, 0, 0, 0, 0, 0, 0, 0};
140       test_equal_range(a, expected);
141    }
142 
143    {
144       Devector b(0);
145 
146       test_equal_range(b);
147       BOOST_TEST(b.get_alloc_count() == 0u);
148    }
149 
150    #ifndef BOOST_NO_EXCEPTIONS
151    typedef typename Devector::value_type T;
152 
153    BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_default_constructible<T>::value)
154    {
155       test_elem_throw::on_ctor_after(4);
156       BOOST_TEST_THROWS(Devector(8), test_exception);
157       BOOST_TEST(test_elem_base::no_living_elem());
158       test_elem_throw::do_not_throw();
159    }
160    #endif   //#ifndef BOOST_NO_EXCEPTIONS
161 }
162 
test_constructor_n_copy_throwing(dtl::true_)163 template <class Devector> void test_constructor_n_copy_throwing(dtl::true_)
164 {
165    #ifndef BOOST_NO_EXCEPTIONS
166    typedef typename Devector::value_type T;
167    test_elem_throw::on_copy_after(4);
168    const T x(404);
169    BOOST_TEST_THROWS(Devector(8, x), test_exception);
170    test_elem_throw::do_not_throw();
171    #endif   //#ifndef BOOST_NO_EXCEPTIONS
172 }
173 
174 
test_constructor_n_copy_throwing(dtl::false_)175 template <class Devector> void test_constructor_n_copy_throwing(dtl::false_)
176 {}
177 
test_constructor_n_copy()178 template <class Devector> void test_constructor_n_copy()
179 {
180    typedef typename Devector::value_type T;
181    {
182       const T x(9);
183       Devector a(8, x);
184       const int expected [] = {9, 9, 9, 9, 9, 9, 9, 9};
185       test_equal_range(a, expected);
186    }
187 
188    {
189       const T x(9);
190       Devector b(0, x);
191 
192       test_equal_range(b);
193       BOOST_TEST(b.get_alloc_count() == 0u);
194    }
195 
196    test_constructor_n_copy_throwing<Devector>
197       (dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
198 
199    BOOST_TEST(test_elem_base::no_living_elem());
200 }
201 
test_constructor_input_range()202 template <class Devector> void test_constructor_input_range()
203 {
204    typedef typename Devector::value_type T;
205    {
206       devector<T> expected; get_range<devector<T> >(16, expected);
207       devector<T> input = expected;
208 
209       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
210       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
211 
212       Devector a(input_begin, input_end);
213       BOOST_TEST(a == expected);
214    }
215 
216    { // empty range
217       devector<T> input;
218       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
219 
220       Devector b(input_begin, input_begin);
221 
222       test_equal_range(b);
223       BOOST_TEST(b.get_alloc_count() == 0u);
224    }
225 
226    BOOST_TEST(test_elem_base::no_living_elem());
227 /* //if move_if_noexcept is implemented
228    #ifndef BOOST_NO_EXCEPTIONS
229    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
230    {
231       devector<T> input; get_range<devector<T> >(16, input);
232 
233       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
234       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
235 
236       test_elem_throw::on_copy_after(4);
237 
238       BOOST_TEST_THROWS(Devector c(input_begin, input_end), test_exception);
239    }
240 
241    BOOST_TEST(test_elem_base::no_living_elem());
242    #endif   //#ifndef BOOST_NO_EXCEPTIONS
243 */
244 }
245 
246 
test_constructor_forward_range_throwing(dtl::true_)247 void test_constructor_forward_range_throwing(dtl::true_)
248 {}
249 
test_constructor_forward_range_throwing(dtl::false_)250 void test_constructor_forward_range_throwing(dtl::false_)
251 {}
252 
test_constructor_forward_range()253 template <class Devector> void test_constructor_forward_range()
254 {
255    typedef typename Devector::value_type T;
256    boost::container::list<T> ncx;
257    ncx.emplace_back(1);
258    ncx.emplace_back(2);
259    ncx.emplace_back(3);
260    ncx.emplace_back(4);
261    ncx.emplace_back(5);
262    ncx.emplace_back(6);
263    ncx.emplace_back(7);
264    ncx.emplace_back(8);
265    const boost::container::list<T> &x = ncx;
266 
267    {
268       Devector a(x.begin(), x.end());
269       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
270       test_equal_range(a, expected);
271       BOOST_TEST(a.get_alloc_count() <= 1u);
272       a.reset_alloc_stats();
273    }
274 
275    {
276       Devector b(x.begin(), x.begin());
277 
278       test_equal_range(b);
279       BOOST_TEST(b.get_alloc_count() == 0u);
280    }
281 
282    #ifndef BOOST_NO_EXCEPTIONS
283    BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
284    {
285       test_elem_throw::on_copy_after(4);
286       BOOST_TEST_THROWS(Devector c(x.begin(), x.end()), test_exception);
287       test_elem_throw::do_not_throw();
288    }
289    #endif   //#ifndef BOOST_NO_EXCEPTIONS
290 }
291 
test_constructor_pointer_range()292 template <class Devector> void test_constructor_pointer_range()
293 {
294    typedef typename Devector::value_type T;
295 
296    boost::container::vector<T> x; get_range<boost::container::vector<T> >(8, x);
297    const T* xbeg = x.data();
298    const T* xend = x.data() + x.size();
299 
300    {
301       Devector a(xbeg, xend);
302 
303       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
304       test_equal_range(a, expected);
305       BOOST_TEST(a.get_alloc_count() <= 1u);
306    }
307 
308    {
309       Devector b(xbeg, xbeg);
310 
311       test_equal_range(b);
312       BOOST_TEST(b.get_alloc_count() == 0u);
313    }
314 
315    #ifndef BOOST_NO_EXCEPTIONS
316    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
317    {
318       test_elem_throw::on_copy_after(4);
319       BOOST_TEST_THROWS(Devector c(xbeg, xend), test_exception);
320       test_elem_throw::do_not_throw();
321    }
322    #endif   //#ifndef BOOST_NO_EXCEPTIONS
323 }
324 
test_copy_constructor()325 template <class Devector> void test_copy_constructor()
326 {
327    {
328       Devector a;
329       Devector b(a);
330 
331       test_equal_range(b);
332       BOOST_TEST(b.get_alloc_count() == 0u);
333    }
334 
335    {
336       Devector a; get_range<Devector>(8, a);
337       Devector b(a);
338       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
339       test_equal_range(b, expected);
340       BOOST_TEST(b.get_alloc_count() <= 1u);
341    }
342 
343    #ifndef BOOST_NO_EXCEPTIONS
344    typedef typename Devector::value_type T;
345 
346    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
347    {
348       Devector a; get_range<Devector>(8, a);
349 
350       test_elem_throw::on_copy_after(4);
351       BOOST_TEST_THROWS(Devector b(a), test_exception);
352       test_elem_throw::do_not_throw();
353    }
354    #endif   //#ifndef BOOST_NO_EXCEPTIONS
355 }
356 
test_move_constructor()357 template <class Devector> void test_move_constructor()
358 {
359   { // empty
360     Devector a;
361     Devector b(boost::move(a));
362 
363     BOOST_TEST(a.empty());
364     BOOST_TEST(b.empty());
365   }
366 
367   { // maybe small
368     Devector a; get_range<Devector>(1, 5, 5, 9, a);
369     Devector b(boost::move(a));
370 
371     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
372     test_equal_range(b, expected);
373 
374     // a is unspecified but valid state
375     a.clear();
376     BOOST_TEST(a.empty());
377   }
378 
379   { // big
380     Devector a; get_range<Devector>(32, a);
381     Devector b(boost::move(a));
382 
383     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(32, expected);
384     test_equal_range(b, expected);
385 
386     // a is unspecified but valid state
387     a.clear();
388     BOOST_TEST(a.empty());
389   }
390 }
391 
test_destructor()392 template <class Devector> void test_destructor()
393 {
394   Devector a;
395 
396   Devector b; get_range<Devector>(3, b);
397 }
398 
test_assignment()399 template <class Devector> void test_assignment()
400 {
401    const typename Devector::size_type alloc_count =
402       boost::container::allocator_traits
403       < typename Devector::allocator_type >::propagate_on_container_copy_assignment::value;
404 
405    { // assign to empty (maybe small)
406       Devector a;
407       Devector c; get_range<Devector>(6, c);
408       Devector &b = c;
409 
410       a = b;
411       const int expected[] = {1, 2, 3, 4, 5, 6};
412       test_equal_range(a, expected);
413    }
414 
415    { // assign from empty
416       Devector a; get_range<Devector>(6, a);
417       const Devector b;
418 
419       a = b;
420 
421       test_equal_range(a);
422    }
423 
424    { // assign to non-empty
425       Devector a; get_range<Devector>(11, 15, 15, 19, a);
426       Devector c; get_range<Devector>(6, c);
427       const Devector &b = c;
428 
429       a = b;
430       const int expected[] = {1, 2, 3, 4, 5, 6};
431       test_equal_range(a, expected);
432    }
433 
434    { // assign to free front
435       Devector a; get_range<Devector>(11, 15, 15, 19, a);
436       a.reserve_front(8);
437       a.reset_alloc_stats();
438 
439       Devector c; get_range<Devector>(6, c);
440       const Devector &b = c;
441 
442       a = b;
443       const int expected [] = {1, 2, 3, 4, 5, 6};
444       test_equal_range(a, expected);
445       BOOST_TEST(a.get_alloc_count() == alloc_count);
446    }
447 
448    { // assignment overlaps contents
449       Devector a; get_range<Devector>(11, 15, 15, 19, a);
450       a.reserve_front(12);
451       a.reset_alloc_stats();
452 
453       Devector c; get_range<Devector>(6, c);
454       const Devector &b = c;
455 
456       a = b;
457       const int expected [] = {1, 2, 3, 4, 5, 6};
458       test_equal_range(a, expected);
459       BOOST_TEST(a.get_alloc_count() == alloc_count);
460    }
461 
462    { // assignment exceeds contents
463       Devector a; get_range<Devector>(11, 13, 13, 15, a);
464       a.reserve_front(8);
465       a.reserve_back(8);
466       a.reset_alloc_stats();
467 
468       Devector c; get_range<Devector>(12, c);
469       const Devector &b = c;
470 
471       a = b;
472       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
473       test_equal_range(a, expected);
474       BOOST_TEST(a.get_alloc_count() == alloc_count);
475    }
476 
477    #ifndef BOOST_NO_EXCEPTIONS
478    typedef typename Devector::value_type T;
479    BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
480    {
481       // strong guarantee if reallocation is needed (no guarantee otherwise)
482       Devector a; get_range<Devector>(6, a);
483       Devector c; get_range<Devector>(12, c);
484       const Devector &b = c;
485 
486       test_elem_throw::on_copy_after(3);
487       BOOST_TEST_THROWS(a = b, test_exception);
488       test_elem_throw::do_not_throw();
489 
490       const int expected[] = {1, 2, 3, 4, 5, 6};
491       test_equal_range(a, expected);
492    }
493    #endif   //#ifndef BOOST_NO_EXCEPTIONS
494 }
495 
test_move_assignment_throwing(dtl::true_)496 template <class Devector> void test_move_assignment_throwing(dtl::true_)
497 // move should be used on the slow path
498 {
499    Devector a; get_range<Devector>(11, 15, 15, 19, a);
500    Devector b; get_range<Devector>(6, b);
501 
502    test_elem_throw::on_copy_after(3);
503    a = boost::move(b);
504    test_elem_throw::do_not_throw();
505 
506    const int expected [] = {1, 2, 3, 4, 5, 6};
507    test_equal_range(a, expected);
508 
509    b.clear();
510    test_equal_range(b);
511 }
512 
test_move_assignment_throwing(dtl::false_)513 template <class Devector> void test_move_assignment_throwing(dtl::false_)
514 {}
515 
test_move_assignment()516 template <class Devector> void test_move_assignment()
517 {
518   { // assign to empty (maybe small)
519     Devector a;
520     Devector b; get_range<Devector>(6, b);
521 
522     a = boost::move(b);
523 
524     const int expected [] = {1, 2, 3, 4, 5, 6};
525     test_equal_range(a, expected);
526 
527     // b is in unspecified but valid state
528     b.clear();
529     test_equal_range(b);
530   }
531 
532   { // assign from empty
533     Devector a; get_range<Devector>(6, a);
534     Devector b;
535 
536     a = boost::move(b);
537 
538     test_equal_range(a);
539     test_equal_range(b);
540   }
541 
542   { // assign to non-empty
543     Devector a; get_range<Devector>(11, 15, 15, 19, a);
544     Devector b; get_range<Devector>(6, b);
545 
546     a = boost::move(b);
547     const int expected [] = {1, 2, 3, 4, 5, 6};
548     test_equal_range(a, expected);
549 
550     b.clear();
551     test_equal_range(b);
552   }
553 
554   typedef typename Devector::value_type T;
555    test_move_assignment_throwing<Devector>
556       (boost::move_detail::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
557 }
558 
test_il_assignment()559 template <class Devector> void test_il_assignment()
560 {
561    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
562 
563    { // assign to empty (maybe small)
564       Devector a;
565       a = {1, 2, 3, 4, 5, 6 };
566       test_equal_range(a, {1, 2, 3, 4, 5, 6});
567    }
568 
569    { // assign from empty
570       Devector a; get_range<Devector>(6, a);
571       a = {};
572 
573       test_equal_range(a);
574    }
575 
576    { // assign to non-empty
577       Devector a; get_range<Devector>(11, 15, 15, 19, a);
578 
579       a = {1, 2, 3, 4, 5, 6};
580 
581       test_equal_range(a, {1, 2, 3, 4, 5, 6});
582    }
583 
584    { // assign to free front
585       Devector a; get_range<Devector>(11, 15, 15, 19, a);
586       a.reserve_front(8);
587       a.reset_alloc_stats();
588 
589       a = {1, 2, 3, 4, 5, 6};
590 
591       test_equal_range(a, {1, 2, 3, 4, 5, 6});
592       BOOST_TEST(a.get_alloc_count() == 0u);
593    }
594 
595    { // assignment overlaps contents
596       Devector a; get_range<Devector>(11, 15, 15, 19, a);
597       a.reserve_front(12);
598       a.reset_alloc_stats();
599 
600       a = {1, 2, 3, 4, 5, 6};
601 
602       test_equal_range(a, {1, 2, 3, 4, 5, 6});
603       BOOST_TEST(a.get_alloc_count() == 0u);
604    }
605 
606    { // assignment exceeds contents
607       Devector a; get_range<Devector>(11, 13, 13, 15, a);
608       a.reserve_front(8);
609       a.reserve_back(8);
610       a.reset_alloc_stats();
611 
612       a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
613 
614       test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
615       BOOST_TEST(a.get_alloc_count() == 0u);
616    }
617 
618    #ifndef BOOST_NO_EXCEPTIONS
619    typedef typename Devector::value_type T;
620    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
621    {
622       // strong guarantee if reallocation is needed (no guarantee otherwise)
623       Devector a; get_range<Devector>(6, a);
624 
625       test_elem_throw::on_copy_after(3);
626 
627       BOOST_TRY
628       {
629          a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
630          BOOST_TEST(false);
631       }
632       BOOST_CATCH(const test_exception&) {}
633       BOOST_CATCH_END
634       test_elem_throw::do_not_throw();
635 
636       test_equal_range(a, {1, 2, 3, 4, 5, 6});
637    }
638    #endif   //BOOST_NO_EXCEPTIONS
639    #endif   //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
640 }
641 
test_assign_input_range()642 template <class Devector> void test_assign_input_range()
643 {
644    typedef typename Devector::value_type T;
645 
646    { // assign to empty, keep it small
647       devector<T> expected; get_range<Devector>(1, 13, 13, 25, expected);
648       devector<T> input = expected;
649 
650       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
651       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
652 
653       Devector a;
654       a.reset_alloc_stats();
655       a.assign(input_begin, input_end);
656 
657       BOOST_TEST(a == expected);
658    }
659 
660    { // assign to empty (maybe small)
661       devector<T> input; get_range<devector<T> >(6, input);
662 
663       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
664       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
665 
666       Devector a;
667 
668       a.assign(input_begin, input_end);
669       const int expected [] = {1, 2, 3, 4, 5, 6};
670       test_equal_range(a, expected);
671    }
672 
673    { // assign from empty
674       devector<T> input; get_range<devector<T> >(6, input);
675       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
676 
677       Devector a; get_range<Devector>(6, a);
678       a.assign(input_begin, input_begin);
679 
680       test_equal_range(a);
681    }
682 
683    { // assign to non-empty
684       devector<T> input; get_range<devector<T> >(6, input);
685       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
686       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
687 
688       Devector a; get_range<Devector>(11, 15, 15, 19, a);
689       a.assign(input_begin, input_end);
690       const int expected [] = {1, 2, 3, 4, 5, 6};
691       test_equal_range(a, expected);
692    }
693 
694    { // assign to free front
695       devector<T> input; get_range<devector<T> >(6, input);
696       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
697       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
698 
699       Devector a; get_range<Devector>(11, 15, 15, 19, a);
700       a.reserve_front(8);
701       a.reset_alloc_stats();
702 
703       a.assign(input_begin, input_end);
704       const int expected[] = {1, 2, 3, 4, 5, 6};
705       test_equal_range(a, expected);
706    }
707 
708    { // assignment overlaps contents
709       devector<T> input; get_range<devector<T> >(6, input);
710       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
711       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
712 
713       Devector a; get_range<Devector>(11, 15, 15, 19, a);
714       a.reserve_front(12);
715       a.reset_alloc_stats();
716 
717       a.assign(input_begin, input_end);
718       const int expected[] = {1, 2, 3, 4, 5, 6};
719       test_equal_range(a, expected);
720    }
721 
722    { // assignment exceeds contents
723       devector<T> input; get_range<devector<T> >(12, input);
724       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
725       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
726 
727       Devector a; get_range<Devector>(11, 13, 13, 15, a);
728       a.reserve_front(8);
729       a.reserve_back(8);
730       a.reset_alloc_stats();
731 
732       a.assign(input_begin, input_end);
733       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
734       test_equal_range(a, expected);
735    }
736 
737    #ifndef BOOST_NO_EXCEPTIONS
738    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
739    {
740       // strong guarantee if reallocation is needed (no guarantee otherwise)
741 
742       devector<T> input; get_range<devector<T> >(12, input);
743       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
744       input_iterator<Devector> input_end   = make_input_iterator(input, input.end());
745 
746       Devector a; get_range<Devector>(6, a);
747 
748       test_elem_throw::on_copy_after(3);
749       BOOST_TEST_THROWS(a.assign(input_begin, input_end), test_exception);
750       test_elem_throw::do_not_throw();
751 
752       const int expected[] = {1, 2, 3, 4, 5, 6};
753       test_equal_range(a, expected);
754    }
755    #endif   //#ifndef BOOST_NO_EXCEPTIONS
756 }
757 
test_assign_forward_range_throwing(dtl::false_)758 template <class Devector> void test_assign_forward_range_throwing(dtl::false_)
759 {}
760 
test_assign_forward_range()761 template <class Devector> void test_assign_forward_range()
762 {
763   typedef typename Devector::value_type T;
764   typedef boost::container::list<T> List;
765 
766   boost::container::list<T> x;
767   typedef typename List::iterator list_iterator;
768   x.emplace_back(1);
769   x.emplace_back(2);
770   x.emplace_back(3);
771   x.emplace_back(4);
772   x.emplace_back(5);
773   x.emplace_back(6);
774   x.emplace_back(7);
775   x.emplace_back(8);
776   x.emplace_back(9);
777   x.emplace_back(10);
778   x.emplace_back(11);
779   x.emplace_back(12);
780 
781   list_iterator one = x.begin();
782   list_iterator six = one;
783   list_iterator twelve = one;
784 
785   iterator_advance(six, 6);
786   iterator_advance(twelve, 12);
787 
788   { // assign to empty (maybe small)
789     Devector a;
790 
791     a.assign(one, six);
792 
793     const int expected [] = {1, 2, 3, 4, 5, 6};
794     test_equal_range(a, expected);
795   }
796 
797   { // assign from empty
798     Devector a; get_range<Devector>(6, a);
799 
800     a.assign(one, one);
801 
802     test_equal_range(a);
803   }
804 
805   { // assign to non-empty
806     Devector a; get_range<Devector>(11, 15, 15, 19, a);
807 
808     a.assign(one, six);
809 
810     const int expected [] = {1, 2, 3, 4, 5, 6};
811     test_equal_range(a, expected);
812   }
813 
814   { // assign to free front
815     Devector a; get_range<Devector>(11, 15, 15, 19, a);
816     a.reserve_front(8);
817     a.reset_alloc_stats();
818 
819     a.assign(one, six);
820 
821     const int expected [] = {1, 2, 3, 4, 5, 6};
822     test_equal_range(a, expected);
823     BOOST_TEST(a.get_alloc_count() == 0u);
824   }
825 
826   { // assignment overlaps contents
827     Devector a; get_range<Devector>(11, 15, 15, 19, a);
828     a.reserve_front(12);
829     a.reset_alloc_stats();
830 
831     a.assign(one, six);
832 
833     const int expected [] = {1, 2, 3, 4, 5, 6};
834     test_equal_range(a, expected);
835     BOOST_TEST(a.get_alloc_count() == 0u);
836   }
837 
838   { // assignment exceeds contents
839     Devector a; get_range<Devector>(11, 13, 13, 15, a);
840     a.reserve_front(8);
841     a.reserve_back(8);
842     a.reset_alloc_stats();
843 
844     a.assign(one, twelve);
845 
846     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
847     test_equal_range(a, expected);
848     BOOST_TEST(a.get_alloc_count() == 0u);
849   }
850 
851    #ifndef BOOST_NO_EXCEPTIONS
852    BOOST_IF_CONSTEXPR(! boost::move_detail::is_nothrow_copy_constructible<T>::value)
853    {
854       // strong guarantee if reallocation is needed (no guarantee otherwise)
855       Devector a; get_range<Devector>(6, a);
856 
857       test_elem_throw::on_copy_after(3);
858       BOOST_TEST_THROWS(a.assign(one, twelve), test_exception);
859       test_elem_throw::do_not_throw();
860 
861       const int expected [] = {1, 2, 3, 4, 5, 6};
862       test_equal_range(a, expected);
863    }
864    #endif   //#ifndef BOOST_NO_EXCEPTIONS
865 }
866 
test_assign_pointer_range()867 template <class Devector> void test_assign_pointer_range()
868 {
869    typedef typename Devector::value_type T;
870 
871    boost::container::vector<T> x; get_range<boost::container::vector<T> >(12, x);
872    const T* one = x.data();
873    const T* six = one + 6;
874    const T* twelve = one + 12;
875 
876    { // assign to empty (maybe small)
877       Devector a;
878 
879       a.assign(one, six);
880 
881       const int expected[] = {1, 2, 3, 4, 5, 6};
882       test_equal_range(a, expected);
883    }
884 
885    { // assign from empty
886       Devector a; get_range<Devector>(6, a);
887 
888       a.assign(one, one);
889 
890       test_equal_range(a);
891    }
892 
893    { // assign to non-empty
894       Devector a; get_range<Devector>(11, 15, 15, 19, a);
895 
896       a.assign(one, six);
897 
898       const int expected[] = {1, 2, 3, 4, 5, 6};
899       test_equal_range(a, expected);
900    }
901 
902    { // assign to free front
903       Devector a; get_range<Devector>(11, 15, 15, 19, a);
904       a.reserve_front(8);
905       a.reset_alloc_stats();
906 
907       a.assign(one, six);
908 
909       const int expected[] = {1, 2, 3, 4, 5, 6};
910       test_equal_range(a, expected);
911       BOOST_TEST(a.get_alloc_count() == 0u);
912    }
913 
914    { // assignment overlaps contents
915       Devector a; get_range<Devector>(11, 15, 15, 19, a);
916       a.reserve_front(12);
917       a.reset_alloc_stats();
918 
919       a.assign(one, six);
920 
921       const int expected[] = {1, 2, 3, 4, 5, 6};
922       test_equal_range(a, expected);
923       BOOST_TEST(a.get_alloc_count() == 0u);
924    }
925 
926    { // assignment exceeds contents
927       Devector a; get_range<Devector>(11, 13, 13, 15, a);
928       a.reserve_front(8);
929       a.reserve_back(8);
930       a.reset_alloc_stats();
931 
932       a.assign(one, twelve);
933 
934       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
935       test_equal_range(a, expected);
936       BOOST_TEST(a.get_alloc_count() == 0u);
937    }
938 
939    #ifndef BOOST_NO_EXCEPTIONS
940    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
941    {
942       // strong guarantee if reallocation is needed (no guarantee otherwise)
943       Devector a; get_range<Devector>(6, a);
944 
945       test_elem_throw::on_copy_after(3);
946       BOOST_TEST_THROWS(a.assign(one, twelve), test_exception);
947       test_elem_throw::do_not_throw();
948 
949       const int expected[] = {1, 2, 3, 4, 5, 6};
950       test_equal_range(a, expected);
951    }
952    #endif   //#ifndef BOOST_NO_EXCEPTIONS
953 }
954 
test_assign_n()955 template <class Devector> void test_assign_n()
956 {
957    typedef typename Devector::value_type T;
958 
959    { // assign to empty (maybe small)
960       Devector a;
961 
962       a.assign(6, T(9));
963 
964       const int expected[] = {9, 9, 9, 9, 9, 9};
965       test_equal_range(a, expected);
966    }
967 
968    { // assign from empty
969       Devector a; get_range<Devector>(6, a);
970 
971       a.assign(0, T(404));
972 
973       test_equal_range(a);
974    }
975 
976    { // assign to non-empty
977       Devector a; get_range<Devector>(11, 15, 15, 19, a);
978 
979       a.assign(6, T(9));
980 
981       const int expected[] = {9, 9, 9, 9, 9, 9};
982       test_equal_range(a, expected);
983    }
984 
985    { // assign to free front
986       Devector a; get_range<Devector>(11, 15, 15, 19, a);
987       a.reserve_front(8);
988       a.reset_alloc_stats();
989 
990       a.assign(6, T(9));
991 
992       const int expected[] = {9, 9, 9, 9, 9, 9};
993       test_equal_range(a, expected);
994       BOOST_TEST(a.get_alloc_count() == 0u);
995    }
996 
997    { // assignment overlaps contents
998       Devector a; get_range<Devector>(11, 15, 15, 19, a);
999       a.reserve_front(12);
1000       a.reset_alloc_stats();
1001 
1002       a.assign(6, T(9));
1003 
1004       const int expected[] = {9, 9, 9, 9, 9, 9};
1005       test_equal_range(a, expected);
1006       BOOST_TEST(a.get_alloc_count() == 0u);
1007    }
1008 
1009    { // assignment exceeds contents
1010       Devector a; get_range<Devector>(11, 13, 13, 15, a);
1011       a.reserve_front(8);
1012       a.reserve_back(8);
1013       a.reset_alloc_stats();
1014 
1015       a.assign(12, T(9));
1016 
1017       const int expected[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
1018       test_equal_range(a, expected);
1019       BOOST_TEST(a.get_alloc_count() == 0u);
1020    }
1021 
1022    #ifndef BOOST_NO_EXCEPTIONS
1023    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
1024    {
1025       // strong guarantee if reallocation is needed (no guarantee otherwise)
1026       Devector a; get_range<Devector>(6, a);
1027 
1028       test_elem_throw::on_copy_after(3);
1029       BOOST_TEST_THROWS(a.assign(32, T(9)), test_exception);
1030       test_elem_throw::do_not_throw();
1031 
1032       const int expected[] = {1, 2, 3, 4, 5, 6};
1033       test_equal_range(a, expected);
1034    }
1035    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1036 }
1037 
test_assign_il()1038 template <class Devector> void test_assign_il()
1039 {
1040    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1041 
1042    { // assign to empty (maybe small)
1043       Devector a;
1044 
1045       a.assign({1, 2, 3, 4, 5, 6});
1046 
1047       test_equal_range(a, {1, 2, 3, 4, 5, 6});
1048    }
1049 
1050    { // assign from empty
1051       Devector a; get_range<Devector>(6, a);
1052 
1053       a.assign({});
1054 
1055       test_equal_range(a);
1056    }
1057 
1058    { // assign to non-empty
1059       Devector a; get_range<Devector>(11, 15, 15, 19, a);
1060 
1061       a.assign({1, 2, 3, 4, 5, 6});
1062 
1063       test_equal_range(a, {1, 2, 3, 4, 5, 6});
1064    }
1065 
1066    { // assign to free front
1067       Devector a; get_range<Devector>(11, 15, 15, 19, a);
1068       a.reserve_front(8);
1069       a.reset_alloc_stats();
1070 
1071       a.assign({1, 2, 3, 4, 5, 6});
1072 
1073       test_equal_range(a, {1, 2, 3, 4, 5, 6});
1074       BOOST_TEST(a.get_alloc_count() == 0u);
1075    }
1076 
1077    { // assignment overlaps contents
1078       Devector a; get_range<Devector>(11, 15, 15, 19, a);
1079       a.reserve_front(12);
1080       a.reset_alloc_stats();
1081 
1082       a.assign({1, 2, 3, 4, 5, 6});
1083 
1084       test_equal_range(a, {1, 2, 3, 4, 5, 6});
1085       BOOST_TEST(a.get_alloc_count() == 0u);
1086    }
1087 
1088    { // assignment exceeds contents
1089       Devector a; get_range<Devector>(11, 13, 13, 15, a);
1090       a.reserve_front(8);
1091       a.reserve_back(8);
1092       a.reset_alloc_stats();
1093 
1094       a.assign({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
1095 
1096       test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
1097       BOOST_TEST(a.get_alloc_count() == 0u);
1098    }
1099 
1100    #ifndef BOOST_NO_EXCEPTIONS
1101    typedef typename Devector::value_type T;
1102    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
1103    {
1104       // strong guarantee if reallocation is needed (no guarantee otherwise)
1105       Devector a; get_range<Devector>(6, a);
1106 
1107       test_elem_throw::on_copy_after(3);
1108       BOOST_TEST_THROWS(a.assign({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}), test_exception);
1109       test_elem_throw::do_not_throw();
1110 
1111       test_equal_range(a, {1, 2, 3, 4, 5, 6});
1112    }
1113    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1114    #endif   //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1115 }
1116 
test_get_allocator()1117 template <class Devector> void test_get_allocator()
1118 {
1119   Devector a;
1120   (void) a.get_allocator();
1121 }
1122 
test_begin_end()1123 template <class Devector> void test_begin_end()
1124 {
1125    boost::container::vector<int> expected; get_range<boost::container::vector<int> >(10, expected);
1126    {
1127       Devector actual; get_range<Devector>(10, actual);
1128 
1129       BOOST_TEST(boost::algorithm::equal(expected.begin(), expected.end(), actual.begin(), actual.end()));
1130       BOOST_TEST(boost::algorithm::equal(expected.rbegin(), expected.rend(), actual.rbegin(), actual.rend()));
1131       BOOST_TEST(boost::algorithm::equal(expected.cbegin(), expected.cend(), actual.cbegin(), actual.cend()));
1132       BOOST_TEST(boost::algorithm::equal(expected.crbegin(), expected.crend(), actual.crbegin(), actual.crend()));
1133    }
1134 
1135    {
1136       Devector cactual; get_range<Devector>(10, cactual);
1137 
1138       BOOST_TEST(boost::algorithm::equal(expected.begin(), expected.end(), cactual.begin(), cactual.end()));
1139       BOOST_TEST(boost::algorithm::equal(expected.rbegin(), expected.rend(), cactual.rbegin(), cactual.rend()));
1140    }
1141 }
1142 
test_empty()1143 template <class Devector> void test_empty()
1144 {
1145   typedef typename Devector::value_type T;
1146 
1147   Devector a;
1148   BOOST_TEST(a.empty());
1149 
1150   a.push_front(T(1));
1151   BOOST_TEST(! a.empty());
1152 
1153   a.pop_back();
1154   BOOST_TEST(a.empty());
1155 
1156   Devector b(16, reserve_only_tag_t());
1157   BOOST_TEST(b.empty());
1158 
1159   Devector c; get_range<Devector>(3, c);
1160   BOOST_TEST(! c.empty());
1161 }
1162 
1163 //template <typename ST>
1164 //using gp_devector = devector<unsigned, different_growth_policy>;
1165 
test_max_size()1166 void test_max_size()
1167 {/*
1168   gp_devector<unsigned char> a;
1169   BOOST_TEST(a.max_size() == (std::numeric_limits<unsigned char>::max)());
1170 
1171   gp_devector<unsigned short> b;
1172   BOOST_TEST(b.max_size() == (std::numeric_limits<unsigned short>::max)());
1173 
1174   gp_devector<unsigned int> c;
1175   BOOST_TEST(c.max_size() >= b.max_size());
1176 
1177   gp_devector<std::size_t> d;
1178   BOOST_TEST(d.max_size() >= c.max_size());
1179 */
1180 }
1181 
test_exceeding_max_size()1182 void test_exceeding_max_size()
1183 {/*
1184    #ifndef BOOST_NO_EXCEPTIONS
1185    using Devector = gp_devector<unsigned char>;
1186 
1187    Devector a((std::numeric_limits<typename Devector::size_type>::max)());
1188    BOOST_TEST_THROWS(a.emplace_back(404), std::length_error);
1189    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1190 */
1191 }
1192 
test_size()1193 template <class Devector> void test_size()
1194 {
1195   typedef typename Devector::value_type T;
1196 
1197   Devector a;
1198   BOOST_TEST(a.size() == 0u);
1199 
1200   a.push_front(T(1));
1201   BOOST_TEST(a.size() == 1u);
1202 
1203   a.pop_back();
1204   BOOST_TEST(a.size() == 0u);
1205 
1206   Devector b(16, reserve_only_tag_t());
1207   BOOST_TEST(b.size() == 0u);
1208 
1209   Devector c; get_range<Devector>(3, c);
1210   BOOST_TEST(c.size() == 3u);
1211 }
1212 
test_capacity()1213 template <class Devector> void test_capacity()
1214 {
1215   Devector a;
1216   BOOST_TEST(a.capacity() == 0u);
1217 
1218   Devector b(128, reserve_only_tag_t());
1219   BOOST_TEST(b.capacity() >= 128u);
1220 
1221   Devector c; get_range<Devector>(10, c);
1222   BOOST_TEST(c.capacity() >= 10u);
1223 }
1224 
test_resize_front_throwing(dtl::true_)1225 template <class Devector> void test_resize_front_throwing(dtl::true_)
1226 {
1227    #ifndef BOOST_NO_EXCEPTIONS
1228    typedef typename Devector::iterator iterator;
1229 
1230    Devector d; get_range<Devector>(5, d);
1231    boost::container::vector<int> d_origi; get_range<boost::container::vector<int> >(5, d_origi);
1232    iterator origi_begin = d.begin();
1233 
1234    test_elem_throw::on_ctor_after(3);
1235    BOOST_TEST_THROWS(d.resize_front(256), test_exception);
1236    test_elem_throw::do_not_throw();
1237 
1238    test_equal_range(d, d_origi);
1239    BOOST_TEST(origi_begin == d.begin());
1240    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1241 }
1242 
test_resize_front_throwing(dtl::false_)1243 template <class Devector> void test_resize_front_throwing(dtl::false_)
1244 {}
1245 
1246 
test_resize_front()1247 template <class Devector> void test_resize_front()
1248 {
1249    typedef typename Devector::value_type T;
1250 
1251    // size < required, alloc needed
1252    {
1253       Devector a; get_range<Devector>(5, a);
1254       a.resize_front(8);
1255       const int expected [] = {0, 0, 0, 1, 2, 3, 4, 5};
1256       test_equal_range(a, expected);
1257    }
1258 
1259    // size < required, but capacity provided
1260    {
1261       Devector b; get_range<Devector>(5, b);
1262       b.reserve_front(16);
1263       b.resize_front(8);
1264       const int expected [] = {0, 0, 0, 1, 2, 3, 4, 5};
1265       test_equal_range(b, expected);
1266    }
1267    /*
1268    // size < required, move would throw
1269    if (! boost::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value)
1270    {
1271       Devector c; get_range<Devector>(5, c);
1272 
1273       test_elem_throw::on_move_after(3);
1274       c.resize_front(8); // shouldn't use the throwing move
1275       test_elem_throw::do_not_throw();
1276 
1277       test_equal_range(c, {0, 0, 0, 1, 2, 3, 4, 5});
1278    }
1279    */
1280 
1281    test_resize_front_throwing<Devector>
1282       (dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
1283 
1284    // size >= required
1285    {
1286       Devector e; get_range<Devector>(6, e);
1287       e.resize_front(4);
1288       const int expected [] = {3, 4, 5, 6};
1289       test_equal_range(e, expected);
1290    }
1291 
1292    // size < required, does not fit front small buffer
1293    {
1294       boost::container::vector<int> expected(128);
1295       Devector g;
1296       g.resize_front(128);
1297       test_equal_range(g, expected);
1298    }
1299 
1300    // size = required
1301    {
1302       Devector e; get_range<Devector>(6, e);
1303       e.resize_front(6);
1304       const int expected [] = {1, 2, 3, 4, 5, 6};
1305       test_equal_range(e, expected);
1306    }
1307 }
1308 
test_resize_front_copy_throwing(dtl::true_)1309 template <class Devector> void test_resize_front_copy_throwing(dtl::true_)
1310 {
1311    #ifndef BOOST_NO_EXCEPTIONS
1312    typedef typename Devector::value_type T;
1313    typedef typename Devector::iterator iterator;
1314 
1315    // size < required, copy throws
1316    {
1317       Devector c; get_range<Devector>(5, c);
1318       boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
1319 
1320       test_elem_throw::on_copy_after(3);
1321       BOOST_TEST_THROWS(c.resize_front(256, T(404)), test_exception);
1322       test_elem_throw::do_not_throw();
1323 
1324       test_equal_range(c, c_origi);
1325    }
1326 
1327    // size < required, copy throws, but later
1328    {
1329       Devector c; get_range<Devector>(5, c);
1330       boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
1331       iterator origi_begin = c.begin();
1332 
1333       test_elem_throw::on_copy_after(7);
1334       BOOST_TEST_THROWS(c.resize_front(256, T(404)), test_exception);
1335       test_elem_throw::do_not_throw();
1336 
1337       test_equal_range(c, c_origi);
1338       BOOST_TEST(origi_begin == c.begin());
1339    }
1340    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1341 }
1342 
test_resize_front_copy_throwing(dtl::false_)1343 template <class Devector> void test_resize_front_copy_throwing(dtl::false_)
1344 {}
1345 
test_resize_front_copy()1346 template <class Devector> void test_resize_front_copy()
1347 {
1348    typedef typename Devector::value_type T;
1349 
1350    // size < required, alloc needed
1351    {
1352       Devector a; get_range<Devector>(5, a);
1353       a.resize_front(8, T(9));
1354       const int expected [] = {9, 9, 9, 1, 2, 3, 4, 5};
1355       test_equal_range(a, expected);
1356    }
1357 
1358    // size < required, but capacity provided
1359    {
1360       Devector b; get_range<Devector>(5, b);
1361       b.reserve_front(16);
1362       b.resize_front(8, T(9));
1363       const int expected [] = {9, 9, 9, 1, 2, 3, 4, 5};
1364       test_equal_range(b, expected);
1365    }
1366 
1367    test_resize_front_copy_throwing<Devector>
1368       (dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
1369 
1370    // size >= required
1371    {
1372       Devector e; get_range<Devector>(6, e);
1373       e.resize_front(4, T(404));
1374       const int expected[] = {3, 4, 5, 6};
1375       test_equal_range(e, expected);
1376    }
1377 
1378    // size < required, does not fit front small buffer
1379    {
1380       boost::container::vector<int> expected(128, 9);
1381       Devector g;
1382       g.resize_front(128, T(9));
1383       test_equal_range(g, expected);
1384    }
1385 
1386    // size = required
1387    {
1388       Devector e; get_range<Devector>(6, e);
1389       e.resize_front(6, T(9));
1390       const int expected[] = {1, 2, 3, 4, 5, 6};
1391       test_equal_range(e, expected);
1392    }
1393 
1394    // size < required, tmp is already inserted
1395    {
1396       Devector f; get_range<Devector>(8, f);
1397       const T& tmp = *(f.begin() + 1);
1398       f.resize_front(16, tmp);
1399       const int expected[] = {2,2,2,2,2,2,2,2,1,2,3,4,5,6,7,8};
1400       test_equal_range(f, expected);
1401    }
1402 }
1403 
test_resize_back_throwing(dtl::true_)1404 template <class Devector> void test_resize_back_throwing(dtl::true_)
1405 // size < required, constructor throws
1406 {
1407    #ifndef BOOST_NO_EXCEPTIONS
1408    typedef typename Devector::iterator iterator;
1409 
1410    Devector d; get_range<Devector>(5, d);
1411    boost::container::vector<int> d_origi; get_range<boost::container::vector<int> >(5, d_origi);
1412    iterator origi_begin = d.begin();
1413 
1414    test_elem_throw::on_ctor_after(3);
1415    BOOST_TEST_THROWS(d.resize_back(256), test_exception);
1416    test_elem_throw::do_not_throw();
1417 
1418    test_equal_range(d, d_origi);
1419    BOOST_TEST(origi_begin == d.begin());
1420    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1421 }
1422 
test_resize_back_throwing(dtl::false_)1423 template <class Devector> void test_resize_back_throwing(dtl::false_)
1424 {}
1425 
test_resize_back()1426 template <class Devector> void test_resize_back()
1427 {
1428    typedef typename Devector::value_type T;
1429 
1430    // size < required, alloc needed
1431    {
1432       Devector a; get_range<Devector>(5, a);
1433       a.resize_back(8);
1434       const int expected [] = {1, 2, 3, 4, 5, 0, 0, 0};
1435       test_equal_range(a, expected);
1436    }
1437 
1438    // size < required, but capacity provided
1439    {
1440       Devector b; get_range<Devector>(5, b);
1441       b.reserve_back(16);
1442       b.resize_back(8);
1443       const int expected [] = {1, 2, 3, 4, 5, 0, 0, 0};
1444       test_equal_range(b, expected);
1445    }
1446    /*
1447    // size < required, move would throw
1448    if (! boost::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value)
1449    {
1450       Devector c; get_range<Devector>(5, c);
1451 
1452       test_elem_throw::on_move_after(3);
1453       c.resize_back(8); // shouldn't use the throwing move
1454       test_elem_throw::do_not_throw();
1455 
1456       test_equal_range(c, {1, 2, 3, 4, 5, 0, 0, 0});
1457    }
1458    */
1459 
1460    test_resize_back_throwing<Devector>
1461       (dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
1462 
1463    // size >= required
1464    {
1465       Devector e; get_range<Devector>(6, e);
1466       e.resize_back(4);
1467       const int expected [] = {1, 2, 3, 4};
1468       test_equal_range(e, expected);
1469    }
1470 
1471    // size < required, does not fit front small buffer
1472    {
1473       boost::container::vector<int> expected(128);
1474       Devector g;
1475       g.resize_back(128);
1476       test_equal_range(g, expected);
1477    }
1478 
1479    // size = required
1480    {
1481       Devector e; get_range<Devector>(6, e);
1482       e.resize_back(6);
1483       const int expected [] = {1, 2, 3, 4, 5, 6};
1484       test_equal_range(e, expected);
1485    }
1486 }
1487 
test_resize_back_copy_throwing(dtl::true_)1488 template <class Devector> void test_resize_back_copy_throwing(dtl::true_)
1489 {
1490    #ifndef BOOST_NO_EXCEPTIONS
1491    typedef typename Devector::value_type T;
1492    typedef typename Devector::iterator iterator;
1493 
1494    // size < required, copy throws
1495    {
1496       Devector c; get_range<Devector>(5, c);
1497       boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
1498 
1499       test_elem_throw::on_copy_after(3);
1500       BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
1501       test_elem_throw::do_not_throw();
1502 
1503       test_equal_range(c, c_origi);
1504    }
1505 
1506    // size < required, copy throws, but later
1507    {
1508       Devector c; get_range<Devector>(5, c);
1509       boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
1510       iterator origi_begin = c.begin();
1511 
1512       test_elem_throw::on_copy_after(7);
1513       BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
1514       test_elem_throw::do_not_throw();
1515 
1516       test_equal_range(c, c_origi);
1517       BOOST_TEST(origi_begin == c.begin());
1518    }
1519 
1520    // size < required, copy throws
1521    {
1522       Devector c; get_range<Devector>(5, c);
1523       boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
1524       iterator origi_begin = c.begin();
1525 
1526       test_elem_throw::on_copy_after(3);
1527       BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
1528       test_elem_throw::do_not_throw();
1529 
1530       test_equal_range(c, c_origi);
1531       BOOST_TEST(origi_begin == c.begin());
1532    }
1533    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1534 }
1535 
test_resize_back_copy_throwing(dtl::false_)1536 template <class Devector> void test_resize_back_copy_throwing(dtl::false_)
1537 {}
1538 
test_resize_back_copy()1539 template <class Devector> void test_resize_back_copy()
1540 {
1541   typedef typename Devector::value_type T;
1542 
1543    // size < required, alloc needed
1544    {
1545       Devector a; get_range<Devector>(5, a);
1546       a.resize_back(8, T(9));
1547       const int expected [] = {1, 2, 3, 4, 5, 9, 9, 9};
1548       test_equal_range(a, expected);
1549    }
1550 
1551    // size < required, but capacity provided
1552    {
1553       Devector b; get_range<Devector>(5, b);
1554       b.reserve_back(16);
1555       b.resize_back(8, T(9));
1556       const int expected [] = {1, 2, 3, 4, 5, 9, 9, 9};
1557       test_equal_range(b, expected);
1558    }
1559 
1560    test_resize_back_copy_throwing<Devector>
1561       (dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
1562 
1563    // size >= required
1564    {
1565       Devector e; get_range<Devector>(6, e);
1566       e.resize_back(4, T(404));
1567       const int expected [] = {1, 2, 3, 4};
1568       test_equal_range(e, expected);
1569    }
1570 
1571    // size < required, does not fit front small buffer
1572    {
1573       boost::container::vector<int> expected(128, 9);
1574       Devector g;
1575       g.resize_back(128, T(9));
1576       test_equal_range(g, expected);
1577    }
1578 
1579    // size = required
1580    {
1581       Devector e; get_range<Devector>(6, e);
1582       e.resize_back(6, T(9));
1583       const int expected [] = {1, 2, 3, 4, 5, 6};
1584       test_equal_range(e, expected);
1585    }
1586 
1587    // size < required, tmp is already inserted
1588    {
1589       Devector f; get_range<Devector>(8, f);
1590       const T& tmp = *(f.begin() + 1);
1591       f.resize_back(16, tmp);
1592       const int expected [] = {1,2,3,4,5,6,7,8,2,2,2,2,2,2,2,2};
1593       test_equal_range(f, expected);
1594    }
1595 }
1596 
1597 /*
1598 template <class Devector> void test_constructor_unsafe_uninitialized()
1599 {
1600   {
1601     Devector a(8, unsafe_uninitialized_tag_t());
1602     BOOST_TEST(a.size() == 8u);
1603 
1604     for (int i = 0; i < 8; ++i)
1605     {
1606       new (a.data() + i) T(i+1);
1607     }
1608 
1609     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
1610     test_equal_range(a, expected);
1611   }
1612 
1613   {
1614     Devector b(0, unsafe_uninitialized_tag_t());
1615     BOOST_TEST(b.get_alloc_count() == 0u);
1616   }
1617 }
1618 */
1619 
1620 /*
1621 template <class Devector> void test_unsafe_uninitialized_resize_front()
1622 {
1623   typedef typename Devector::value_type T;
1624 
1625   { // noop
1626     Devector a; get_range<Devector>(8, a);
1627     a.reset_alloc_stats();
1628 
1629     a.unsafe_uninitialized_resize_front(a.size());
1630 
1631     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
1632     test_equal_range(a, expected);
1633     BOOST_TEST(a.get_alloc_count() == 0u);
1634   }
1635 
1636   { // grow (maybe has enough capacity)
1637     Devector b; get_range<Devector>(0, 0, 5, 9, b);
1638 
1639     b.unsafe_uninitialized_resize_front(8);
1640 
1641     for (int i = 0; i < 4; ++i)
1642     {
1643       new (b.data() + i) T(i+1);
1644     }
1645 
1646    const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
1647     test_equal_range(b, expected);
1648   }
1649 
1650   { // shrink uninitialized
1651     Devector c; get_range<Devector>(8, c);
1652 
1653     c.unsafe_uninitialized_resize_front(16);
1654     c.unsafe_uninitialized_resize_front(8);
1655 
1656       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
1657     test_equal_range(c, expected );
1658   }
1659 
1660   if (std::is_trivially_destructible<T>::value)
1661   {
1662     // shrink
1663     Devector d; get_range<Devector>(8, d);
1664 
1665     d.unsafe_uninitialized_resize_front(4);
1666 
1667     test_equal_range(d, {5, 6, 7, 8});
1668   }
1669 }
1670 
1671 template <class Devector> void test_unsafe_uninitialized_resize_back()
1672 {
1673   typedef typename Devector::value_type T;
1674 
1675   { // noop
1676     Devector a; get_range<Devector>(8, a);
1677     a.reset_alloc_stats();
1678 
1679     a.unsafe_uninitialized_resize_back(a.size());
1680 
1681     test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8});
1682     BOOST_TEST(a.get_alloc_count() == 0u);
1683   }
1684 
1685   { // grow (maybe has enough capacity)
1686     Devector b; get_range<Devector>(1, 5, 0, 0, b);
1687 
1688     b.unsafe_uninitialized_resize_back(8);
1689 
1690     for (int i = 0; i < 4; ++i)
1691     {
1692       new (b.data() + 4 + i) T(i+5);
1693     }
1694 
1695     test_equal_range(b, {1, 2, 3, 4, 5, 6, 7, 8});
1696   }
1697 
1698   { // shrink uninitialized
1699     Devector c; get_range<Devector>(8, c);
1700 
1701     c.unsafe_uninitialized_resize_back(16);
1702     c.unsafe_uninitialized_resize_back(8);
1703 
1704     test_equal_range(c, {1, 2, 3, 4, 5, 6, 7, 8});
1705   }
1706 
1707   if (std::is_trivially_destructible<T>::value)
1708   {
1709     // shrink
1710     Devector d; get_range<Devector>(8, d);
1711 
1712     d.unsafe_uninitialized_resize_back(4);
1713 
1714     test_equal_range(d, {1, 2, 3, 4});
1715   }
1716 }
1717 */
1718 
test_reserve_front()1719 template <class Devector> void test_reserve_front()
1720 {
1721   typedef typename Devector::value_type value_type;
1722   Devector a;
1723 
1724   a.reserve_front(100);
1725   for (unsigned i = 0; i < 100u; ++i)
1726   {
1727     a.push_front(value_type(i));
1728   }
1729 
1730   BOOST_TEST(a.get_alloc_count() == 1u);
1731 
1732   Devector b;
1733   b.reserve_front(4);
1734   b.reserve_front(6);
1735   b.reserve_front(4);
1736   b.reserve_front(8);
1737   b.reserve_front(16);
1738 }
1739 
test_reserve_back()1740 template <class Devector> void test_reserve_back()
1741 {
1742   Devector a;
1743   typedef typename Devector::value_type value_type;
1744   a.reserve_back(100);
1745   for (unsigned i = 0; i < 100; ++i)
1746   {
1747     a.push_back(value_type(i));
1748   }
1749 
1750   BOOST_TEST(a.get_alloc_count() == 1u);
1751 
1752   Devector b;
1753   b.reserve_back(4);
1754   b.reserve_back(6);
1755   b.reserve_back(4);
1756   b.reserve_back(8);
1757   b.reserve_back(16);
1758 }
1759 
1760 template <typename Devector>
test_shrink_to_fit_always()1761 void test_shrink_to_fit_always()
1762 {
1763    Devector a;
1764    a.reserve(100);
1765 
1766    a.push_back(1);
1767    a.push_back(2);
1768    a.push_back(3);
1769 
1770    a.shrink_to_fit();
1771 
1772    boost::container::vector<unsigned> expected;
1773    expected.push_back(1);
1774    expected.push_back(2);
1775    expected.push_back(3);
1776    test_equal_range(a, expected);
1777 
1778    std::size_t exp_capacity = 3u;
1779    BOOST_TEST(a.capacity() == exp_capacity);
1780 }
1781 
1782 template <typename Devector>
test_shrink_to_fit_never()1783 void test_shrink_to_fit_never()
1784 {
1785    Devector a;
1786    a.reserve(100);
1787 
1788    a.push_back(1);
1789    a.push_back(2);
1790    a.push_back(3);
1791 
1792    a.shrink_to_fit();
1793 
1794    boost::container::vector<unsigned> expected;
1795    expected.emplace_back(1);
1796    expected.emplace_back(2);
1797    expected.emplace_back(3);
1798    test_equal_range(a, expected);
1799    BOOST_TEST(a.capacity() == 100u);
1800 }
1801 
shrink_to_fit()1802 void shrink_to_fit()
1803 {
1804    typedef devector<unsigned> devector_u_shr;
1805    typedef devector<unsigned> small_devector_u_shr;
1806    test_shrink_to_fit_always<devector_u_shr>();
1807    test_shrink_to_fit_always<small_devector_u_shr>();
1808 }
1809 
test_index_operator()1810 template <class Devector> void test_index_operator()
1811 {
1812   typedef typename Devector::value_type T;
1813 
1814   { // non-const []
1815     Devector a; get_range<Devector>(5, a);
1816 
1817     BOOST_TEST(a[0] == 1);
1818     BOOST_TEST(a[4] == 5);
1819     BOOST_TEST(&a[3] == &a[0] + 3);
1820 
1821     a[0] = T(100);
1822     BOOST_TEST(a[0] == 100);
1823   }
1824 
1825   { // const []
1826     Devector b; get_range<Devector>(5, b);
1827     const Devector &a = b;
1828 
1829     BOOST_TEST(a[0] == 1);
1830     BOOST_TEST(a[4] == 5);
1831     BOOST_TEST(&a[3] == &a[0] + 3);
1832   }
1833 }
1834 
test_at()1835 template <class Devector> void test_at()
1836 {
1837    #ifndef BOOST_NO_EXCEPTIONS
1838    typedef typename Devector::value_type T;
1839 
1840    { // non-const at
1841       Devector a; get_range<Devector>(3, a);
1842 
1843       BOOST_TEST(a.at(0) == 1);
1844       a.at(0) = T(100);
1845       BOOST_TEST(a.at(0) == 100);
1846 
1847       BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
1848    }
1849 
1850    { // const at
1851       Devector b; get_range<Devector>(3, b);
1852       const Devector &a = b;
1853 
1854       BOOST_TEST(a.at(0) == 1);
1855 
1856       BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
1857    }
1858    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1859 }
1860 
test_front()1861 template <class Devector> void test_front()
1862 {
1863   typedef typename Devector::value_type T;
1864 
1865   { // non-const front
1866     Devector a; get_range<Devector>(3, a);
1867     BOOST_TEST(a.front() == 1);
1868     a.front() = T(100);
1869     BOOST_TEST(a.front() == 100);
1870   }
1871 
1872   { // const front
1873     Devector b; get_range<Devector>(3, b); const Devector &a = b;
1874     BOOST_TEST(a.front() == 1);
1875   }
1876 }
1877 
test_back()1878 template <class Devector> void test_back()
1879 {
1880   typedef typename Devector::value_type T;
1881 
1882   { // non-const back
1883     Devector a; get_range<Devector>(3, a);
1884     BOOST_TEST(a.back() == 3);
1885     a.back() = T(100);
1886     BOOST_TEST(a.back() == 100);
1887   }
1888 
1889   { // const back
1890     Devector b; get_range<Devector>(3, b); const Devector &a = b;
1891     BOOST_TEST(a.back() == 3);
1892   }
1893 }
1894 
test_data()1895 void test_data()
1896 {
1897   unsigned c_array[] = {1, 2, 3, 4};
1898 
1899   { // non-const data
1900     devector<unsigned> a(c_array, c_array + 4);
1901     BOOST_TEST(a.data() == &a.front());
1902 
1903     BOOST_TEST(std::memcmp(c_array, a.data(), 4 * sizeof(unsigned)) == 0);
1904 
1905     *(a.data()) = 100;
1906     BOOST_TEST(a.front() == 100u);
1907   }
1908 
1909   { // const data
1910     const devector<unsigned> a(c_array, c_array + 4);
1911     BOOST_TEST(a.data() == &a.front());
1912 
1913     BOOST_TEST(std::memcmp(c_array, a.data(), 4 * sizeof(unsigned)) == 0);
1914   }
1915 }
1916 
test_emplace_front(dtl::true_)1917 template <class Devector> void test_emplace_front(dtl::true_)
1918 {
1919    #ifndef BOOST_NO_EXCEPTIONS
1920    typedef typename Devector::iterator iterator;
1921 
1922    Devector b; get_range<Devector>(4, b);
1923    iterator origi_begin = b.begin();
1924 
1925    test_elem_throw::on_ctor_after(1);
1926    BOOST_TEST_THROWS(b.emplace_front(404), test_exception);
1927    test_elem_throw::do_not_throw();
1928 
1929    iterator new_begin = b.begin();
1930 
1931    BOOST_TEST(origi_begin == new_begin);
1932    BOOST_TEST(b.size() == 4u);
1933    #endif   //#ifndef BOOST_NO_EXCEPTIONS
1934 }
1935 
test_emplace_front(dtl::false_)1936 template <class Devector> void test_emplace_front(dtl::false_)
1937 {
1938 }
1939 
test_emplace_front()1940 template <class Devector> void test_emplace_front()
1941 {
1942   typedef typename Devector::value_type T;
1943 
1944   {
1945     Devector a;
1946 
1947     a.emplace_front(3);
1948     a.emplace_front(2);
1949     a.emplace_front(1);
1950 
1951     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(3, expected);
1952 
1953     test_equal_range(a, expected);
1954   }
1955 
1956    test_emplace_front<Devector>
1957       (dtl::bool_<!boost::move_detail::is_nothrow_default_constructible<T>::value>());
1958 }
1959 
test_push_front()1960 template <class Devector> void test_push_front()
1961 {
1962    typedef typename Devector::value_type T;
1963    {
1964       boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
1965       std::reverse(expected.begin(), expected.end());
1966       Devector a;
1967 
1968       for (int i = 1; i <= 16; ++i)
1969       {
1970       T elem(i);
1971       a.push_front(elem);
1972       }
1973 
1974       test_equal_range(a, expected);
1975    }
1976 
1977    #ifndef BOOST_NO_EXCEPTIONS
1978    typedef typename Devector::iterator iterator;
1979    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
1980    {
1981       Devector b; get_range<Devector>(4, b);
1982       iterator origi_begin = b.begin();
1983 
1984       const T elem(404);
1985 
1986       test_elem_throw::on_copy_after(1);
1987       BOOST_TEST_THROWS(b.push_front(elem), test_exception);
1988       test_elem_throw::do_not_throw();
1989 
1990       iterator new_begin = b.begin();
1991 
1992       BOOST_TEST(origi_begin == new_begin);
1993       BOOST_TEST(b.size() == 4u);
1994    }
1995 
1996    // test when tmp is already inserted
1997    {
1998       Devector c; get_range<Devector>(4, c);
1999       const T& tmp = *(c.begin() + 1);
2000       c.push_front(tmp);
2001       const int expected[] = {2, 1, 2, 3, 4};
2002       test_equal_range(c, expected);
2003    }
2004    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2005 }
2006 
test_push_front_rvalue_throwing(dtl::true_)2007 template <class Devector> void test_push_front_rvalue_throwing(dtl::true_)
2008 {
2009    #ifndef BOOST_NO_EXCEPTIONS
2010    typedef typename Devector::value_type T;
2011    typedef typename Devector::iterator iterator;
2012 
2013    Devector b; get_range<Devector>(4, b);
2014    iterator origi_begin = b.begin();
2015 
2016    test_elem_throw::on_move_after(1);
2017    BOOST_TEST_THROWS(b.push_front(T(404)), test_exception);
2018    test_elem_throw::do_not_throw();
2019 
2020    iterator new_begin = b.begin();
2021 
2022    BOOST_TEST(origi_begin == new_begin);
2023    BOOST_TEST(b.size() == 4u);
2024    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2025 }
2026 
test_push_front_rvalue_throwing(dtl::false_)2027 template <class Devector> void test_push_front_rvalue_throwing(dtl::false_)
2028 {}
2029 
test_push_front_rvalue()2030 template <class Devector> void test_push_front_rvalue()
2031 {
2032   typedef typename Devector::value_type T;
2033 
2034   {
2035     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2036     Devector a;
2037 
2038     for (int i = 16; i > 0; --i)
2039     {
2040       T elem(i);
2041       a.push_front(boost::move(elem));
2042     }
2043 
2044     test_equal_range(a, expected);
2045   }
2046 
2047   test_push_front_rvalue_throwing<Devector>(dtl::bool_<! boost::is_nothrow_move_constructible<T>::value>());
2048 }
2049 
test_pop_front()2050 template <class Devector> void test_pop_front()
2051 {
2052   {
2053     Devector a;
2054     a.emplace_front(1);
2055     a.pop_front();
2056     BOOST_TEST(a.empty());
2057   }
2058 
2059   {
2060     Devector b;
2061 
2062     b.emplace_back(2);
2063     b.pop_front();
2064     BOOST_TEST(b.empty());
2065 
2066     b.emplace_front(3);
2067     b.pop_front();
2068     BOOST_TEST(b.empty());
2069   }
2070 
2071   {
2072     Devector c; get_range<Devector>(20, c);
2073     for (int i = 0; i < 20; ++i)
2074     {
2075       BOOST_TEST(!c.empty());
2076       c.pop_front();
2077     }
2078     BOOST_TEST(c.empty());
2079   }
2080 }
2081 
test_emplace_back_throwing(dtl::true_)2082 template <class Devector> void test_emplace_back_throwing(dtl::true_)
2083 {
2084    #ifndef BOOST_NO_EXCEPTIONS
2085    typedef typename Devector::iterator iterator;
2086 
2087    Devector b; get_range<Devector>(4, b);
2088    iterator origi_begin = b.begin();
2089 
2090    test_elem_throw::on_ctor_after(1);
2091    BOOST_TEST_THROWS(b.emplace_back(404), test_exception);
2092    test_elem_throw::do_not_throw();
2093 
2094    iterator new_begin = b.begin();
2095 
2096    BOOST_TEST(origi_begin == new_begin);
2097    BOOST_TEST(b.size() == 4u);
2098    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2099 }
2100 
test_emplace_back_throwing(dtl::false_)2101 template <class Devector> void test_emplace_back_throwing(dtl::false_)
2102 {}
2103 
test_emplace_back()2104 template <class Devector> void test_emplace_back()
2105 {
2106   typedef typename Devector::value_type T;
2107 
2108   {
2109     Devector a;
2110 
2111     a.emplace_back(1);
2112     a.emplace_back(2);
2113     a.emplace_back(3);
2114 
2115     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(3, expected);
2116 
2117     test_equal_range<Devector>(a, expected);
2118   }
2119 
2120    test_emplace_back_throwing<Devector>
2121       (dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
2122 }
2123 
test_push_back_throwing(dtl::true_)2124 template <class Devector> void test_push_back_throwing(dtl::true_)
2125 {
2126    #ifndef BOOST_NO_EXCEPTIONS
2127    typedef typename Devector::value_type T;
2128    typedef typename Devector::iterator iterator;
2129 
2130    Devector b; get_range<Devector>(4, b);
2131    iterator origi_begin = b.begin();
2132 
2133    const T elem(404);
2134 
2135    test_elem_throw::on_copy_after(1);
2136    BOOST_TEST_THROWS(b.push_back(elem), test_exception);
2137    test_elem_throw::do_not_throw();
2138 
2139    iterator new_begin = b.begin();
2140 
2141    BOOST_TEST(origi_begin == new_begin);
2142    BOOST_TEST(b.size() == 4u);
2143    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2144 }
2145 
test_push_back_throwing(dtl::false_)2146 template <class Devector> void test_push_back_throwing(dtl::false_)
2147 {}
2148 
test_push_back()2149 template <class Devector> void test_push_back()
2150 {
2151    typedef typename Devector::value_type T;
2152    {
2153       boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2154       Devector a;
2155 
2156       for (int i = 1; i <= 16; ++i)
2157       {
2158          T elem(i);
2159          a.push_back(elem);
2160       }
2161 
2162       test_equal_range(a, expected);
2163    }
2164 
2165    test_push_back_throwing<Devector>(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
2166 
2167    // test when tmp is already inserted
2168    {
2169       Devector c; get_range<Devector>(4, c);
2170       const T& tmp = *(c.begin() + 1);
2171       c.push_back(tmp);
2172       const int expected[] = {1, 2, 3, 4, 2};
2173       test_equal_range(c, expected);
2174    }
2175 }
2176 
test_push_back_rvalue_throwing(dtl::true_)2177 template <class Devector> void test_push_back_rvalue_throwing(dtl::true_)
2178 {
2179    #ifndef BOOST_NO_EXCEPTIONS
2180    typedef typename Devector::value_type T;
2181    typedef typename Devector::iterator iterator;
2182 
2183    Devector b; get_range<Devector>(4, b);
2184    iterator origi_begin = b.begin();
2185 
2186    test_elem_throw::on_move_after(1);
2187    BOOST_TEST_THROWS(b.push_back(T(404)), test_exception);
2188    test_elem_throw::do_not_throw();
2189 
2190    iterator new_begin = b.begin();
2191 
2192    BOOST_TEST(origi_begin == new_begin);
2193    BOOST_TEST(b.size() == 4u);
2194    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2195 }
2196 
test_push_back_rvalue_throwing(dtl::false_)2197 template <class Devector> void test_push_back_rvalue_throwing(dtl::false_)
2198 {}
2199 
test_push_back_rvalue()2200 template <class Devector> void test_push_back_rvalue()
2201 {
2202   typedef typename Devector::value_type T;
2203 
2204   {
2205     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2206     Devector a;
2207 
2208     for (int i = 1; i <= 16; ++i)
2209     {
2210       T elem(i);
2211       a.push_back(boost::move(elem));
2212     }
2213 
2214     test_equal_range(a, expected);
2215   }
2216 
2217   test_push_back_rvalue_throwing<Devector>(dtl::bool_<! boost::is_nothrow_move_constructible<T>::value>());
2218 }
2219 
2220 /*
2221 template <class Devector> void test_unsafe_push_front()
2222 {
2223    typedef typename Devector::value_type T;
2224    typedef typename Devector::iterator iterator;
2225 
2226    {
2227       boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2228       std::reverse(expected.begin(), expected.end());
2229       Devector a;
2230       a.reserve_front(16);
2231 
2232       for (std::size_t i = 1; i <= 16; ++i)
2233       {
2234       T elem(i);
2235       a.unsafe_push_front(elem);
2236       }
2237 
2238       test_equal_range(a, expected);
2239    }
2240 
2241    #ifndef BOOST_NO_EXCEPTIONS
2242    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
2243    {
2244       Devector b; get_range<Devector>(4, b);
2245       b.reserve_front(5);
2246       iterator origi_begin = b.begin();
2247 
2248       const T elem(404);
2249 
2250       test_elem_throw::on_copy_after(1);
2251       BOOST_TEST_THROWS(b.unsafe_push_front(elem), test_exception);
2252       test_elem_throw::do_not_throw();
2253 
2254       iterator new_begin = b.begin();
2255 
2256       BOOST_TEST(origi_begin == new_begin);
2257       BOOST_TEST(b.size() == 4u);
2258    }
2259    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2260 }
2261 
2262 template <class Devector> void test_unsafe_push_front_rvalue()
2263 {
2264   typedef typename Devector::value_type T;
2265 
2266   {
2267     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2268     std::reverse(expected.begin(), expected.end());
2269     Devector a;
2270     a.reserve_front(16);
2271 
2272     for (std::size_t i = 1; i <= 16; ++i)
2273     {
2274       T elem(i);
2275       a.unsafe_push_front(boost::move(elem));
2276     }
2277 
2278     test_equal_range(a, expected);
2279   }
2280 }
2281 */
2282 /*
2283 template <class Devector> void test_unsafe_push_back()
2284 {
2285    typedef typename Devector::value_type T;
2286    typedef typename Devector::iterator iterator;
2287 
2288    {
2289       boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2290       Devector a;
2291       a.reserve(16);
2292 
2293       for (std::size_t i = 1; i <= 16; ++i)
2294       {
2295       T elem(i);
2296       a.unsafe_push_back(elem);
2297       }
2298 
2299       test_equal_range(a, expected);
2300    }
2301 
2302    #ifndef BOOST_NO_EXCEPTIONS
2303    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
2304    {
2305       Devector b; get_range<Devector>(4, b);
2306       b.reserve(5);
2307       iterator origi_begin = b.begin();
2308 
2309       const T elem(404);
2310 
2311       test_elem_throw::on_copy_after(1);
2312       BOOST_TEST_THROWS(b.unsafe_push_back(elem), test_exception);
2313       test_elem_throw::do_not_throw();
2314 
2315       iterator new_begin = b.begin();
2316 
2317       BOOST_TEST(origi_begin == new_begin);
2318       BOOST_TEST(b.size() == 4u);
2319    }
2320    #endif
2321 }
2322 
2323 template <class Devector> void test_unsafe_push_back_rvalue()
2324 {
2325   typedef typename Devector::value_type T;
2326 
2327   {
2328     boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
2329     Devector a;
2330     a.reserve(16);
2331 
2332     for (std::size_t i = 1; i <= 16; ++i)
2333     {
2334       T elem(i);
2335       a.unsafe_push_back(boost::move(elem));
2336     }
2337 
2338     test_equal_range(a, expected);
2339   }
2340 }
2341 */
test_pop_back()2342 template <class Devector> void test_pop_back()
2343 {
2344   {
2345     Devector a;
2346     a.emplace_back(1);
2347     a.pop_back();
2348     BOOST_TEST(a.empty());
2349   }
2350 
2351   {
2352     Devector b;
2353 
2354     b.emplace_front(2);
2355     b.pop_back();
2356     BOOST_TEST(b.empty());
2357 
2358     b.emplace_back(3);
2359     b.pop_back();
2360     BOOST_TEST(b.empty());
2361   }
2362 
2363   {
2364     Devector c; get_range<Devector>(20, c);
2365     for (int i = 0; i < 20; ++i)
2366     {
2367       BOOST_TEST(!c.empty());
2368       c.pop_back();
2369     }
2370     BOOST_TEST(c.empty());
2371   }
2372 }
2373 
test_emplace_throwing(dtl::true_)2374 template <class Devector> void test_emplace_throwing(dtl::true_)
2375 {
2376    #ifndef BOOST_NO_EXCEPTIONS
2377    typedef typename Devector::iterator iterator;
2378 
2379    Devector j; get_range<Devector>(4, j);
2380    iterator origi_begin = j.begin();
2381 
2382    test_elem_throw::on_ctor_after(1);
2383    BOOST_TEST_THROWS(j.emplace(j.begin() + 2, 404), test_exception);
2384    test_elem_throw::do_not_throw();
2385 
2386    const int expected[] = {1, 2, 3, 4};
2387    test_equal_range(j, expected);
2388    BOOST_TEST(origi_begin == j.begin());
2389    #endif
2390 }
2391 
test_emplace_throwing(dtl::false_)2392 template <class Devector> void test_emplace_throwing(dtl::false_)
2393 {}
2394 
2395 
test_emplace()2396 template <class Devector> void test_emplace()
2397 {
2398    typedef typename Devector::iterator iterator;
2399 
2400   {
2401     Devector a; get_range<Devector>(16, a);
2402     typename Devector::iterator it = a.emplace(a.begin(), 123);
2403     const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2404     test_equal_range(a, expected);
2405     BOOST_TEST(*it == 123);
2406   }
2407 
2408   {
2409     Devector b; get_range<Devector>(16, b);
2410     typename Devector::iterator it = b.emplace(b.end(), 123);
2411     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
2412     test_equal_range(b, expected);
2413     BOOST_TEST(*it == 123);
2414   }
2415 
2416   {
2417     Devector c; get_range<Devector>(16, c);
2418     c.pop_front();
2419     typename Devector::iterator it = c.emplace(c.begin(), 123);
2420     const int expected [] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2421     test_equal_range(c, expected);
2422     BOOST_TEST(*it == 123);
2423   }
2424 
2425   {
2426     Devector d; get_range<Devector>(16, d);
2427     d.pop_back();
2428     typename Devector::iterator it = d.emplace(d.end(), 123);
2429     const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
2430     test_equal_range(d, expected);
2431     BOOST_TEST(*it == 123);
2432   }
2433 
2434   {
2435     Devector e; get_range<Devector>(16, e);
2436     typename Devector::iterator it = e.emplace(e.begin() + 5, 123);
2437     const int expected [] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2438     test_equal_range(e, expected);
2439     BOOST_TEST(*it == 123);
2440   }
2441 
2442   {
2443     Devector f; get_range<Devector>(16, f);
2444     f.pop_front();
2445     f.pop_back();
2446     iterator valid = f.begin() + 1;
2447     typename Devector::iterator it = f.emplace(f.begin() + 1, 123);
2448     const int expected [] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
2449     test_equal_range(f, expected);
2450     BOOST_TEST(*it == 123);
2451     BOOST_TEST(*valid == 3);
2452   }
2453 
2454   {
2455     Devector g; get_range<Devector>(16, g);
2456     g.pop_front();
2457     g.pop_back();
2458     iterator valid = g.end() - 2;
2459     typename Devector::iterator it = g.emplace(g.end() - 1, 123);
2460     const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
2461     test_equal_range(g, expected);
2462     BOOST_TEST(*it == 123);
2463     BOOST_TEST(*valid == 14);
2464   }
2465 
2466   {
2467     Devector h; get_range<Devector>(16, h);
2468     h.pop_front();
2469     h.pop_back();
2470     iterator valid = h.begin() + 7;
2471     typename Devector::iterator it = h.emplace(h.begin() + 7, 123);
2472     const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
2473     test_equal_range(h, expected);
2474     BOOST_TEST(*it == 123);
2475     BOOST_TEST(*valid == 9);
2476   }
2477 
2478   {
2479     Devector i;
2480     i.emplace(i.begin(), 1);
2481     i.emplace(i.end(), 10);
2482     for (int j = 2; j < 10; ++j)
2483     {
2484       i.emplace(i.begin() + (j-1), j);
2485     }
2486     const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
2487     test_equal_range(i, expected);
2488   }
2489 
2490    typedef typename Devector::value_type T;
2491    test_emplace_throwing<Devector>
2492       (dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
2493 }
2494 
test_insert_throwing(dtl::true_)2495 template <class Devector> void test_insert_throwing(dtl::true_)
2496 {
2497    #ifndef BOOST_NO_EXCEPTIONS
2498    typedef typename Devector::value_type T;
2499    typedef typename Devector::iterator iterator;
2500 
2501    T test_elem(123);
2502 
2503    Devector j; get_range<Devector>(4, j);
2504    iterator origi_begin = j.begin();
2505 
2506    test_elem_throw::on_copy_after(1);
2507    BOOST_TEST_THROWS(j.insert(j.begin() + 2, test_elem), test_exception);
2508    test_elem_throw::do_not_throw();
2509 
2510    const int expected[] = {1, 2, 3, 4};
2511    test_equal_range(j, expected);
2512    BOOST_TEST(origi_begin == j.begin());
2513    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2514 }
2515 
test_insert_throwing(dtl::false_)2516 template <class Devector> void test_insert_throwing(dtl::false_)
2517 {}
2518 
test_insert()2519 template <class Devector> void test_insert()
2520 {
2521    typedef typename Devector::value_type T;
2522    typedef typename Devector::iterator iterator;
2523 
2524    T test_elem(123);
2525 
2526    {
2527       Devector a; get_range<Devector>(16, a);
2528       typename Devector::iterator it = a.insert(a.begin(), test_elem);
2529       const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2530       test_equal_range(a, expected);
2531       BOOST_TEST(*it == 123);
2532    }
2533 
2534    {
2535       Devector b; get_range<Devector>(16, b);
2536       typename Devector::iterator it = b.insert(b.end(), test_elem);
2537       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
2538       test_equal_range(b, expected);
2539       BOOST_TEST(*it == 123);
2540    }
2541 
2542    {
2543       Devector c; get_range<Devector>(16, c);
2544       c.pop_front();
2545       typename Devector::iterator it = c.insert(c.begin(), test_elem);
2546       const int expected[] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2547       test_equal_range(c, expected);
2548       BOOST_TEST(*it == 123);
2549    }
2550 
2551    {
2552       Devector d; get_range<Devector>(16, d);
2553       d.pop_back();
2554       typename Devector::iterator it = d.insert(d.end(), test_elem);
2555       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
2556       test_equal_range(d, expected);
2557       BOOST_TEST(*it == 123);
2558    }
2559 
2560    {
2561       Devector e; get_range<Devector>(16, e);
2562       typename Devector::iterator it = e.insert(e.begin() + 5, test_elem);
2563       const int expected[] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2564       test_equal_range(e, expected);
2565       BOOST_TEST(*it == 123);
2566    }
2567 
2568    {
2569       Devector f; get_range<Devector>(16, f);
2570       f.pop_front();
2571       f.pop_back();
2572       iterator valid = f.begin() + 1;
2573       typename Devector::iterator it = f.insert(f.begin() + 1, test_elem);
2574       const int expected[] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
2575       test_equal_range(f, expected);
2576       BOOST_TEST(*it == 123);
2577       BOOST_TEST(*valid == 3);
2578    }
2579 
2580    {
2581       Devector g; get_range<Devector>(16, g);
2582       g.pop_front();
2583       g.pop_back();
2584       iterator valid = g.end() - 2;
2585       typename Devector::iterator it = g.insert(g.end() - 1, test_elem);
2586       const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
2587       test_equal_range(g, expected);
2588       BOOST_TEST(*it == 123);
2589       BOOST_TEST(*valid == 14);
2590    }
2591 
2592    {
2593       Devector h; get_range<Devector>(16, h);
2594       h.pop_front();
2595       h.pop_back();
2596       iterator valid = h.begin() + 7;
2597       typename Devector::iterator it = h.insert(h.begin() + 7, test_elem);
2598       const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
2599       test_equal_range(h, expected);
2600       BOOST_TEST(*it == 123);
2601       BOOST_TEST(*valid == 9);
2602    }
2603 
2604    {
2605       Devector i;
2606       i.insert(i.begin(), T(1));
2607       i.insert(i.end(), T(10));
2608       for (int j = 2; j < 10; ++j)
2609       {
2610          i.insert(i.begin() + (j-1), T(j));
2611       }
2612       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
2613       test_equal_range(i, expected);
2614    }
2615 
2616    test_insert_throwing<Devector>
2617       (dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
2618 
2619    // test when tmp is already inserted and there's free capacity
2620    {
2621       Devector c; get_range<Devector>(6, c);
2622       c.pop_back();
2623       const T& tmp = *(c.begin() + 2);
2624       c.insert(c.begin() + 1, tmp);
2625       const int expected[] = {1, 3, 2, 3, 4, 5};
2626       test_equal_range(c, expected);
2627    }
2628 
2629    // test when tmp is already inserted and maybe there's no free capacity
2630    {
2631       Devector c; get_range<Devector>(6, c);
2632       const T& tmp = *(c.begin() + 2);
2633       c.insert(c.begin() + 1, tmp);
2634       const int expected[] = {1, 3, 2, 3, 4, 5, 6};
2635       test_equal_range(c, expected);
2636    }
2637 }
2638 
test_insert_rvalue_throwing(dtl::true_)2639 template <class Devector> void test_insert_rvalue_throwing(dtl::true_)
2640 {
2641    #ifndef BOOST_NO_EXCEPTIONS
2642    typedef typename Devector::value_type T;
2643    typedef typename Devector::iterator iterator;
2644 
2645    Devector j; get_range<Devector>(4, j);
2646    iterator origi_begin = j.begin();
2647 
2648    test_elem_throw::on_ctor_after(1);
2649    BOOST_TEST_THROWS(j.insert(j.begin() + 2, T(404)), test_exception);
2650    test_elem_throw::do_not_throw();
2651 
2652    const int expected[] = {1, 2, 3, 4};
2653    test_equal_range(j, expected);
2654    BOOST_TEST(origi_begin == j.begin());
2655    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2656 }
2657 
test_insert_rvalue_throwing(dtl::false_)2658 template <class Devector> void test_insert_rvalue_throwing(dtl::false_)
2659 {}
2660 
2661 
test_insert_rvalue()2662 template <class Devector> void test_insert_rvalue()
2663 {
2664    typedef typename Devector::value_type T;
2665    typedef typename Devector::iterator iterator;
2666 
2667    {
2668       Devector a; get_range<Devector>(16, a);
2669       typename Devector::iterator it = a.insert(a.begin(), T(123));
2670       const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2671       test_equal_range(a, expected);
2672       BOOST_TEST(*it == 123);
2673    }
2674 
2675    {
2676       Devector b; get_range<Devector>(16, b);
2677       typename Devector::iterator it = b.insert(b.end(), T(123));
2678       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
2679       test_equal_range(b, expected);
2680       BOOST_TEST(*it == 123);
2681    }
2682 
2683   {
2684     Devector c; get_range<Devector>(16, c);
2685     c.pop_front();
2686     typename Devector::iterator it = c.insert(c.begin(), T(123));
2687     const int expected[] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2688     test_equal_range(c, expected);
2689     BOOST_TEST(*it == 123);
2690   }
2691 
2692   {
2693     Devector d; get_range<Devector>(16, d);
2694     d.pop_back();
2695     typename Devector::iterator it = d.insert(d.end(), T(123));
2696     const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
2697     test_equal_range(d, expected);
2698     BOOST_TEST(*it == 123);
2699   }
2700 
2701   {
2702     Devector e; get_range<Devector>(16, e);
2703     typename Devector::iterator it = e.insert(e.begin() + 5, T(123));
2704     const int expected[] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
2705     test_equal_range(e, expected);
2706     BOOST_TEST(*it == 123);
2707   }
2708 
2709   {
2710     Devector f; get_range<Devector>(16, f);
2711     f.pop_front();
2712     f.pop_back();
2713     iterator valid = f.begin() + 1;
2714     typename Devector::iterator it = f.insert(f.begin() + 1, T(123));
2715     const int expected[] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
2716     test_equal_range(f, expected);
2717     BOOST_TEST(*it == 123);
2718     BOOST_TEST(*valid == 3);
2719   }
2720 
2721   {
2722     Devector g; get_range<Devector>(16, g);
2723     g.pop_front();
2724     g.pop_back();
2725     iterator valid = g.end() - 2;
2726     typename Devector::iterator it = g.insert(g.end() - 1, T(123));
2727     const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
2728     test_equal_range(g, expected);
2729     BOOST_TEST(*it == 123);
2730     BOOST_TEST(*valid == 14);
2731   }
2732 
2733   {
2734     Devector h; get_range<Devector>(16, h);
2735     h.pop_front();
2736     h.pop_back();
2737     iterator valid = h.begin() + 7;
2738     typename Devector::iterator it = h.insert(h.begin() + 7, T(123));
2739     const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
2740     test_equal_range(h, expected);
2741     BOOST_TEST(*it == 123);
2742     BOOST_TEST(*valid == 9);
2743   }
2744 
2745   {
2746     Devector i;
2747     i.insert(i.begin(), T(1));
2748     i.insert(i.end(), T(10));
2749     for (int j = 2; j < 10; ++j)
2750     {
2751       i.insert(i.begin() + (j-1), T(j));
2752     }
2753     const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
2754     test_equal_range(i, expected);
2755   }
2756 
2757    test_insert_rvalue_throwing<Devector>
2758       (dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
2759 }
2760 
test_insert_n_throwing(dtl::true_)2761 template <class Devector> void test_insert_n_throwing(dtl::true_)
2762 {
2763    #ifndef BOOST_NO_EXCEPTIONS
2764    typedef typename Devector::value_type T;
2765    // insert at begin
2766    {
2767       Devector j; get_range<Devector>(4, j);
2768 
2769       const T x(404);
2770 
2771       test_elem_throw::on_copy_after(3);
2772       BOOST_TEST_THROWS(j.insert(j.begin(), 4, x), test_exception);
2773       test_elem_throw::do_not_throw();
2774    }
2775 
2776    // insert at end
2777    {
2778       Devector k; get_range<Devector>(4, k);
2779 
2780       const T x(404);
2781 
2782       test_elem_throw::on_copy_after(3);
2783       BOOST_TEST_THROWS(k.insert(k.end(), 4, x), test_exception);
2784       test_elem_throw::do_not_throw();
2785    }
2786    #endif   //#ifndef BOOST_NO_EXCEPTIONS
2787 }
2788 
test_insert_n_throwing(dtl::false_)2789 template <class Devector> void test_insert_n_throwing(dtl::false_)
2790 {}
2791 
test_insert_n()2792 template <class Devector> void test_insert_n()
2793 {
2794    typedef typename Devector::value_type T;
2795    typedef typename Devector::iterator iterator;
2796 
2797    {
2798       Devector a;
2799       const T x(123);
2800       iterator ret = a.insert(a.end(), 5, x);
2801       const int expected[] = {123, 123, 123, 123, 123};
2802       test_equal_range(a, expected);
2803       BOOST_TEST(ret == a.begin());
2804    }
2805 
2806    {
2807       Devector b; get_range<Devector>(8, b);
2808       const T x(9);
2809       iterator ret = b.insert(b.begin(), 3, x);
2810       const int expected[] = {9, 9, 9, 1, 2, 3, 4, 5, 6, 7, 8};
2811       test_equal_range(b, expected);
2812       BOOST_TEST(ret == b.begin());
2813    }
2814 
2815    {
2816       Devector c; get_range<Devector>(8, c);
2817       const T x(9);
2818       iterator ret = c.insert(c.end(), 3, x);
2819       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9};
2820       test_equal_range(c, expected);
2821       BOOST_TEST(ret == c.begin() + 8);
2822    }
2823 
2824    {
2825       Devector d; get_range<Devector>(8, d);
2826 
2827       d.pop_front();
2828       d.pop_front();
2829       d.pop_front();
2830 
2831       const T x(9);
2832       iterator origi_end = d.end();
2833       iterator ret = d.insert(d.begin(), 3, x);
2834 
2835       const int expected[] = {9, 9, 9, 4, 5, 6, 7, 8};
2836       test_equal_range(d, expected);
2837       BOOST_TEST(origi_end == d.end());
2838       BOOST_TEST(ret == d.begin());
2839    }
2840 
2841    {
2842       Devector e; get_range<Devector>(8, e);
2843 
2844       e.pop_back();
2845       e.pop_back();
2846       e.pop_back();
2847 
2848       const T x(9);
2849       iterator origi_begin = e.begin();
2850       iterator ret = e.insert(e.end(), 3, x);
2851 
2852       const int expected[] = {1, 2, 3, 4, 5, 9, 9, 9};
2853       test_equal_range(e, expected);
2854       BOOST_TEST(origi_begin == e.begin());
2855       BOOST_TEST(ret == e.begin() + 5);
2856    }
2857 
2858    {
2859       Devector f; get_range<Devector>(8, f);
2860       f.reset_alloc_stats();
2861 
2862       f.pop_front();
2863       f.pop_front();
2864       f.pop_back();
2865       f.pop_back();
2866 
2867       const T x(9);
2868       iterator ret = f.insert(f.begin() + 2, 4, x);
2869 
2870       const int expected[] = {3, 4, 9, 9, 9, 9, 5, 6};
2871       test_equal_range(f, expected);
2872       BOOST_TEST(f.get_alloc_count() == 0u);
2873       BOOST_TEST(ret == f.begin() + 2);
2874    }
2875 
2876    {
2877       Devector g; get_range<Devector>(8, g);
2878       g.reset_alloc_stats();
2879 
2880       g.pop_front();
2881       g.pop_front();
2882       g.pop_back();
2883       g.pop_back();
2884       g.pop_back();
2885 
2886       const T x(9);
2887       iterator ret = g.insert(g.begin() + 2, 5, x);
2888 
2889       const int expected[] = {3, 4, 9, 9, 9, 9, 9, 5};
2890       test_equal_range(g, expected);
2891       BOOST_TEST(g.get_alloc_count() == 0u);
2892       BOOST_TEST(ret == g.begin() + 2);
2893    }
2894 
2895    {
2896       Devector g; get_range<Devector>(8, g);
2897 
2898       const T x(9);
2899       iterator ret = g.insert(g.begin() + 2, 5, x);
2900 
2901       const int expected[] = {1, 2, 9, 9, 9, 9, 9, 3, 4, 5, 6, 7, 8};
2902       test_equal_range(g, expected);
2903       BOOST_TEST(ret == g.begin() + 2);
2904    }
2905 
2906    { // n == 0
2907       Devector h; get_range<Devector>(8, h);
2908       h.reset_alloc_stats();
2909 
2910       const T x(9);
2911 
2912       iterator ret = h.insert(h.begin(), 0, x);
2913       BOOST_TEST(ret == h.begin());
2914 
2915       ret = h.insert(h.begin() + 4, 0, x);
2916       BOOST_TEST(ret == h.begin() + 4);
2917 
2918       ret = h.insert(h.end(), 0, x);
2919       BOOST_TEST(ret == h.end());
2920 
2921       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
2922       test_equal_range(h, expected);
2923       BOOST_TEST(h.get_alloc_count() == 0u);
2924    }
2925 
2926    { // test insert already inserted
2927       Devector i; get_range<Devector>(8, i);
2928       i.reset_alloc_stats();
2929 
2930       i.pop_front();
2931       i.pop_front();
2932 
2933       iterator ret = i.insert(i.end() - 1, 2, *i.begin());
2934 
2935       const int expected[] = {3, 4, 5, 6, 7, 3, 3, 8};
2936       test_equal_range(i, expected);
2937       BOOST_TEST(i.get_alloc_count() == 0u);
2938       BOOST_TEST(ret == i.begin() + 5);
2939    }
2940 
2941    test_insert_n_throwing<Devector>
2942       (dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
2943 }
2944 
test_insert_input_range()2945 template <class Devector> void test_insert_input_range()
2946 {
2947    typedef typename Devector::value_type T;
2948    typedef typename Devector::iterator iterator;
2949 
2950    devector<T> x;
2951    x.emplace_back(9);
2952    x.emplace_back(9);
2953    x.emplace_back(9);
2954    x.emplace_back(9);
2955    x.emplace_back(9);
2956 
2957    {
2958       devector<T> input = x;
2959 
2960       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
2961       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 5);
2962 
2963       Devector a;
2964       iterator ret = a.insert(a.end(), input_begin, input_end);
2965       const int expected[] = {9, 9, 9, 9, 9};
2966       test_equal_range(a, expected);
2967       BOOST_TEST(ret == a.begin());
2968    }
2969 
2970    {
2971       devector<T> input = x;
2972 
2973       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
2974       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 3);
2975 
2976       Devector b; get_range<Devector>(8, b);
2977       iterator ret = b.insert(b.begin(), input_begin, input_end);
2978       const int expected[] = {9, 9, 9, 1, 2, 3, 4, 5, 6, 7, 8};
2979       test_equal_range(b, expected);
2980       BOOST_TEST(ret == b.begin());
2981    }
2982 
2983    {
2984       devector<T> input = x;
2985 
2986       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
2987       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 3);
2988 
2989       Devector c; get_range<Devector>(8, c);
2990       iterator ret = c.insert(c.end(), input_begin, input_end);
2991       const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9};
2992       test_equal_range(c, expected);
2993       BOOST_TEST(ret == c.begin() + 8);
2994    }
2995 
2996    {
2997       devector<T> input = x;
2998 
2999       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3000       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 3);
3001 
3002       Devector d; get_range<Devector>(8, d);
3003 
3004       d.pop_front();
3005       d.pop_front();
3006       d.pop_front();
3007 
3008       iterator ret = d.insert(d.begin(), input_begin, input_end);
3009       const int expected[] = {9, 9, 9, 4, 5, 6, 7, 8};
3010       test_equal_range(d, expected);
3011       BOOST_TEST(ret == d.begin());
3012    }
3013 
3014    {
3015       devector<T> input = x;
3016 
3017       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3018       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 3);
3019 
3020       Devector e; get_range<Devector>(8, e);
3021 
3022       e.pop_back();
3023       e.pop_back();
3024       e.pop_back();
3025 
3026       iterator origi_begin = e.begin();
3027       iterator ret = e.insert(e.end(), input_begin, input_end);
3028       const int expected[] = {1, 2, 3, 4, 5, 9, 9, 9};
3029       test_equal_range(e, expected);
3030       BOOST_TEST(origi_begin == e.begin());
3031       BOOST_TEST(ret == e.begin() + 5);
3032    }
3033 
3034    {
3035       devector<T> input = x;
3036 
3037       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3038       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 4);
3039 
3040       Devector f; get_range<Devector>(8, f);
3041       f.reset_alloc_stats();
3042 
3043       f.pop_front();
3044       f.pop_front();
3045       f.pop_back();
3046       f.pop_back();
3047 
3048       iterator ret = f.insert(f.begin() + 2, input_begin, input_end);
3049 
3050       const int expected[] = {3, 4, 9, 9, 9, 9, 5, 6};
3051       test_equal_range(f, expected);
3052       BOOST_TEST(ret == f.begin() + 2);
3053    }
3054 
3055    {
3056       devector<T> input = x;
3057 
3058       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3059       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 5);
3060 
3061       Devector g; get_range<Devector>(8, g);
3062       g.reset_alloc_stats();
3063 
3064       g.pop_front();
3065       g.pop_front();
3066       g.pop_back();
3067       g.pop_back();
3068       g.pop_back();
3069 
3070       iterator ret = g.insert(g.begin() + 2, input_begin, input_end);
3071 
3072       const int expected [] = {3, 4, 9, 9, 9, 9, 9, 5};
3073       test_equal_range(g, expected);
3074       BOOST_TEST(ret == g.begin() + 2);
3075    }
3076 
3077    {
3078       devector<T> input = x;
3079 
3080       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3081       input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 5);
3082 
3083       Devector g; get_range<Devector>(8, g);
3084 
3085       iterator ret = g.insert(g.begin() + 2, input_begin, input_end);
3086 
3087       const int expected [] = {1, 2, 9, 9, 9, 9, 9, 3, 4, 5, 6, 7, 8};
3088       test_equal_range(g, expected);
3089       BOOST_TEST(ret == g.begin() + 2);
3090    }
3091 
3092    { // n == 0
3093       devector<T> input = x;
3094 
3095       input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3096 
3097       Devector h; get_range<Devector>(8, h);
3098       h.reset_alloc_stats();
3099 
3100       iterator ret = h.insert(h.begin(), input_begin, input_begin);
3101       BOOST_TEST(ret == h.begin());
3102 
3103       ret = h.insert(h.begin() + 4, input_begin, input_begin);
3104       BOOST_TEST(ret == h.begin() + 4);
3105 
3106       ret = h.insert(h.end(), input_begin, input_begin);
3107       BOOST_TEST(ret == h.end());
3108 
3109       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
3110       test_equal_range(h, expected);
3111    }
3112 
3113    #ifndef BOOST_NO_EXCEPTIONS
3114    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
3115    {
3116       // insert at begin
3117       {
3118          devector<T> input = x;
3119 
3120          input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3121          input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 4);
3122 
3123          Devector j; get_range<Devector>(4, j);
3124 
3125          test_elem_throw::on_copy_after(3);
3126          BOOST_TEST_THROWS(j.insert(j.begin(), input_begin, input_end), test_exception);
3127          test_elem_throw::do_not_throw();
3128       }
3129 
3130       // insert at end
3131       {
3132          devector<T> input = x;
3133 
3134          input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
3135          input_iterator<Devector> input_end   = make_input_iterator(input, input.begin() + 4);
3136 
3137          Devector k; get_range<Devector>(4, k);
3138 
3139          test_elem_throw::on_copy_after(3);
3140          BOOST_TEST_THROWS(k.insert(k.end(), input_begin, input_end), test_exception);
3141          test_elem_throw::do_not_throw();
3142       }
3143    }
3144    #endif   //#ifndef BOOST_NO_EXCEPTIONS
3145 }
3146 
test_insert_range()3147 template <class Devector> void test_insert_range()
3148 {
3149    typedef typename Devector::value_type T;
3150    typedef typename Devector::iterator iterator;
3151    typedef boost::container::vector<T> Vector;
3152 
3153    Vector x;
3154    x.emplace_back(9);
3155    x.emplace_back(10);
3156    x.emplace_back(11);
3157    x.emplace_back(12);
3158    x.emplace_back(13);
3159 
3160    typename Vector::iterator xb = x.begin();
3161 
3162    {
3163       Devector a;
3164       iterator ret = a.insert(a.end(), xb, xb+5);
3165       const int expected [] = {9, 10, 11, 12, 13};
3166       test_equal_range(a, expected);
3167       BOOST_TEST(ret == a.begin());
3168    }
3169 
3170    {
3171       Devector b; get_range<Devector>(8, b);
3172       iterator ret = b.insert(b.begin(), xb, xb+3);
3173       const int expected [] = {9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8};
3174       test_equal_range(b, expected);
3175       BOOST_TEST(ret == b.begin());
3176    }
3177 
3178    {
3179       Devector c; get_range<Devector>(8, c);
3180       iterator ret = c.insert(c.end(), xb, xb+3);
3181       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
3182       test_equal_range(c, expected);
3183       BOOST_TEST(ret == c.begin() + 8);
3184    }
3185 
3186    {
3187       Devector d; get_range<Devector>(8, d);
3188 
3189       d.pop_front();
3190       d.pop_front();
3191       d.pop_front();
3192 
3193       iterator origi_end = d.end();
3194       iterator ret = d.insert(d.begin(), xb, xb+3);
3195 
3196       const int expected [] = {9, 10, 11, 4, 5, 6, 7, 8};
3197       test_equal_range(d, expected);
3198 
3199       BOOST_TEST(origi_end == d.end());
3200       BOOST_TEST(ret == d.begin());
3201    }
3202 
3203    {
3204       Devector e; get_range<Devector>(8, e);
3205 
3206       e.pop_back();
3207       e.pop_back();
3208       e.pop_back();
3209 
3210       iterator origi_begin = e.begin();
3211       iterator ret = e.insert(e.end(), xb, xb+3);
3212 
3213       const int expected [] = {1, 2, 3, 4, 5, 9, 10, 11};
3214       test_equal_range(e, expected);
3215 
3216       BOOST_TEST(origi_begin == e.begin());
3217       BOOST_TEST(ret == e.begin() + 5);
3218    }
3219 
3220    {
3221       Devector f; get_range<Devector>(8, f);
3222       f.reset_alloc_stats();
3223 
3224       f.pop_front();
3225       f.pop_front();
3226       f.pop_back();
3227       f.pop_back();
3228 
3229       iterator ret = f.insert(f.begin() + 2, xb, xb+4);
3230 
3231       const int expected [] = {3, 4, 9, 10, 11, 12, 5, 6};
3232       test_equal_range(f, expected);
3233 
3234       BOOST_TEST(f.get_alloc_count() == 0u);
3235       BOOST_TEST(ret == f.begin() + 2);
3236    }
3237 
3238    {
3239       Devector g; get_range<Devector>(8, g);
3240       g.reset_alloc_stats();
3241 
3242       g.pop_front();
3243       g.pop_front();
3244       g.pop_back();
3245       g.pop_back();
3246       g.pop_back();
3247 
3248       iterator ret = g.insert(g.begin() + 2, xb, xb+5);
3249 
3250       const int expected [] = {3, 4, 9, 10, 11, 12, 13, 5};
3251       test_equal_range(g, expected);
3252 
3253       BOOST_TEST(g.get_alloc_count() == 0u);
3254       BOOST_TEST(ret == g.begin() + 2);
3255    }
3256 
3257    {
3258       Devector g; get_range<Devector>(8, g);
3259 
3260       iterator ret = g.insert(g.begin() + 2, xb, xb+5);
3261 
3262       const int expected [] = {1, 2, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8};
3263       test_equal_range(g, expected);
3264 
3265       BOOST_TEST(ret == g.begin() + 2);
3266    }
3267 
3268    { // n == 0
3269       Devector h; get_range<Devector>(8, h);
3270       h.reset_alloc_stats();
3271 
3272       iterator ret = h.insert(h.begin(), xb, xb);
3273       BOOST_TEST(ret == h.begin());
3274 
3275       ret = h.insert(h.begin() + 4, xb, xb);
3276       BOOST_TEST(ret == h.begin() + 4);
3277 
3278       ret = h.insert(h.end(), xb, xb);
3279       BOOST_TEST(ret == h.end());
3280 
3281       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
3282       test_equal_range(h, expected);
3283 
3284       BOOST_TEST(h.get_alloc_count() == 0u);
3285    }
3286 
3287    #ifndef BOOST_NO_EXCEPTIONS
3288    if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
3289    {
3290       // insert at begin
3291       {
3292          Devector j; get_range<Devector>(4, j);
3293 
3294          test_elem_throw::on_copy_after(3);
3295          BOOST_TEST_THROWS(j.insert(j.begin(), xb, xb+4), test_exception);
3296          test_elem_throw::do_not_throw();
3297       }
3298 
3299       // insert at end
3300       {
3301          Devector k; get_range<Devector>(4, k);
3302 
3303          test_elem_throw::on_copy_after(3);
3304          BOOST_TEST_THROWS(k.insert(k.end(), xb, xb+4), test_exception);
3305          test_elem_throw::do_not_throw();
3306       }
3307    }
3308    #endif   //#ifndef BOOST_NO_EXCEPTIONS
3309 }
3310 
test_insert_init_list()3311 template <class Devector> void test_insert_init_list()
3312 {
3313    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
3314    typedef typename Devector::value_type T;
3315    typedef typename Devector::iterator iterator;
3316 
3317    {
3318       Devector a;
3319       iterator ret = a.insert(a.end(), {T(123), T(124), T(125), T(126), T(127)});
3320       test_equal_range(a, {123, 124, 125, 126, 127});
3321       BOOST_TEST(ret == a.begin());
3322    }
3323 
3324    {
3325       Devector b; get_range<Devector>(8, b);
3326       iterator ret = b.insert(b.begin(), {T(9), T(10), T(11)});
3327       test_equal_range(b, {9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8});
3328       BOOST_TEST(ret == b.begin());
3329    }
3330 
3331    {
3332       Devector c; get_range<Devector>(8, c);
3333       iterator ret = c.insert(c.end(), {T(9), T(10), T(11)});
3334       test_equal_range(c, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
3335       BOOST_TEST(ret == c.begin() + 8);
3336    }
3337 
3338    {
3339       Devector d; get_range<Devector>(8, d);
3340 
3341       d.pop_front();
3342       d.pop_front();
3343       d.pop_front();
3344 
3345       iterator origi_end = d.end();
3346       iterator ret = d.insert(d.begin(), {T(9), T(10), T(11)});
3347 
3348       test_equal_range(d, {9, 10, 11, 4, 5, 6, 7, 8});
3349       BOOST_TEST(origi_end == d.end());
3350       BOOST_TEST(ret == d.begin());
3351    }
3352 
3353    {
3354       Devector e; get_range<Devector>(8, e);
3355 
3356       e.pop_back();
3357       e.pop_back();
3358       e.pop_back();
3359 
3360       iterator origi_begin = e.begin();
3361       iterator ret = e.insert(e.end(), {T(9), T(10), T(11)});
3362 
3363       test_equal_range(e, {1, 2, 3, 4, 5, 9, 10, 11});
3364       BOOST_TEST(origi_begin == e.begin());
3365       BOOST_TEST(ret == e.begin() + 5);
3366    }
3367 
3368    {
3369       Devector f; get_range<Devector>(8, f);
3370       f.reset_alloc_stats();
3371 
3372       f.pop_front();
3373       f.pop_front();
3374       f.pop_back();
3375       f.pop_back();
3376 
3377       iterator ret = f.insert(f.begin() + 2, {T(9), T(10), T(11), T(12)});
3378 
3379       test_equal_range(f, {3, 4, 9, 10, 11, 12, 5, 6});
3380       BOOST_TEST(f.get_alloc_count() == 0u);
3381       BOOST_TEST(ret == f.begin() + 2);
3382    }
3383 
3384    {
3385       Devector g; get_range<Devector>(8, g);
3386       g.reset_alloc_stats();
3387 
3388       g.pop_front();
3389       g.pop_front();
3390       g.pop_back();
3391       g.pop_back();
3392       g.pop_back();
3393 
3394       iterator ret = g.insert(g.begin() + 2, {T(9), T(10), T(11), T(12), T(13)});
3395 
3396       test_equal_range(g, {3, 4, 9, 10, 11, 12, 13, 5});
3397       BOOST_TEST(g.get_alloc_count() == 0u);
3398       BOOST_TEST(ret == g.begin() + 2);
3399    }
3400 
3401    {
3402       Devector g; get_range<Devector>(8, g);
3403 
3404       iterator ret = g.insert(g.begin() + 2, {T(9), T(10), T(11), T(12), T(13)});
3405 
3406       test_equal_range(g, {1, 2, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8});
3407       BOOST_TEST(ret == g.begin() + 2);
3408    }
3409 
3410    #ifndef BOOST_NO_EXCEPTIONS
3411    BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
3412    {
3413       // insert at begin
3414       {
3415          Devector j; get_range<Devector>(4, j);
3416 
3417          test_elem_throw::on_copy_after(3);
3418          BOOST_TEST_THROWS(j.insert(j.begin(), {T(9), T(9), T(9), T(9), T(9)}), test_exception);
3419          test_elem_throw::do_not_throw();
3420       }
3421 
3422       // insert at end
3423       {
3424          Devector k; get_range<Devector>(4, k);
3425          test_elem_throw::on_copy_after(3);
3426          BOOST_TEST_THROWS(k.insert(k.end(), {T(9), T(9), T(9), T(9), T(9)}), test_exception);
3427          test_elem_throw::do_not_throw();
3428       }
3429    }
3430    #endif   //#ifndef BOOST_NO_EXCEPTIONS
3431    #endif   //   #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
3432 }
3433 
test_erase()3434 template <class Devector> void test_erase()
3435 {
3436    typedef typename Devector::iterator iterator;
3437    {
3438       Devector a; get_range<Devector>(4, a);
3439       iterator ret = a.erase(a.begin());
3440       const int expected[] = {2, 3, 4};
3441       test_equal_range(a, expected);
3442       BOOST_TEST(ret == a.begin());
3443    }
3444 
3445    {
3446       Devector b; get_range<Devector>(4, b);
3447       iterator ret = b.erase(b.end() - 1);
3448       const int expected[] = {1, 2, 3};
3449       test_equal_range(b, expected);
3450       BOOST_TEST(ret == b.end());
3451    }
3452 
3453    {
3454       Devector c; get_range<Devector>(6, c);
3455       iterator ret = c.erase(c.begin() + 2);
3456       const int expected [] = {1, 2, 4, 5, 6};
3457       test_equal_range(c, expected);
3458       BOOST_TEST(ret == c.begin() + 2);
3459       BOOST_TEST(c.front_free_capacity() > 0u);
3460    }
3461 
3462    {
3463       Devector d; get_range<Devector>(6, d);
3464       iterator ret = d.erase(d.begin() + 4);
3465       const int expected [] = {1, 2, 3, 4, 6};
3466       test_equal_range(d, expected);
3467       BOOST_TEST(ret == d.begin() + 4);
3468       BOOST_TEST(d.back_free_capacity() > 0u);
3469    }
3470 }
3471 
test_erase_range()3472 template <class Devector> void test_erase_range()
3473 {
3474    typedef typename Devector::iterator iterator;
3475    {
3476       Devector a; get_range<Devector>(4, a);
3477       a.erase(a.end(), a.end());
3478       a.erase(a.begin(), a.begin());
3479    }
3480 
3481    {
3482       Devector b; get_range<Devector>(8, b);
3483       iterator ret = b.erase(b.begin(), b.begin() + 2);
3484       const int expected [] = {3, 4, 5, 6, 7, 8};
3485       test_equal_range(b, expected);
3486       BOOST_TEST(ret == b.begin());
3487       BOOST_TEST(b.front_free_capacity() > 0u);
3488    }
3489 
3490    {
3491       Devector c; get_range<Devector>(8, c);
3492       iterator ret = c.erase(c.begin() + 1, c.begin() + 3);
3493       const int expected [] = {1, 4, 5, 6, 7, 8};
3494       test_equal_range(c, expected);
3495       BOOST_TEST(ret == c.begin() + 1);
3496       BOOST_TEST(c.front_free_capacity() > 0u);
3497    }
3498 
3499    {
3500       Devector d; get_range<Devector>(8, d);
3501       iterator ret = d.erase(d.end() - 2, d.end());
3502       const int expected [] = {1, 2, 3, 4, 5, 6};
3503       test_equal_range(d, expected);
3504       BOOST_TEST(ret == d.end());
3505       BOOST_TEST(d.back_free_capacity() > 0u);
3506    }
3507 
3508    {
3509       Devector e; get_range<Devector>(8, e);
3510       iterator ret = e.erase(e.end() - 3, e.end() - 1);
3511       const int expected [] = {1, 2, 3, 4, 5, 8};
3512       test_equal_range(e, expected);
3513       BOOST_TEST(ret == e.end() - 1);
3514       BOOST_TEST(e.back_free_capacity() > 0u);
3515    }
3516 
3517    {
3518       Devector f; get_range<Devector>(8, f);
3519       iterator ret = f.erase(f.begin(), f.end());
3520       test_equal_range(f);
3521       BOOST_TEST(ret == f.end());
3522    }
3523 }
3524 
test_swap()3525 template <class Devector> void test_swap()
3526 {
3527    using std::swap; // test if ADL works
3528 
3529    // empty-empty
3530    {
3531       Devector a;
3532       Devector b;
3533 
3534       swap(a, b);
3535 
3536       BOOST_TEST(a.empty());
3537       BOOST_TEST(b.empty());
3538    }
3539 
3540    // empty-not empty
3541    {
3542       Devector a;
3543       Devector b; get_range<Devector>(4, b);
3544 
3545       swap(a, b);
3546 
3547       const int expected [] = {1, 2, 3, 4};
3548    {
3549       BOOST_TEST(b.empty());
3550       test_equal_range(a, expected);
3551    }
3552 
3553       swap(a, b);
3554    {
3555       BOOST_TEST(a.empty());
3556       test_equal_range(b, expected);
3557    }
3558    }
3559 
3560    // small-small / big-big
3561    {
3562       Devector a; get_range<Devector>(1, 5, 5, 7, a);
3563       Devector b; get_range<Devector>(13, 15, 15, 19, b);
3564 
3565       swap(a, b);
3566 
3567       const int expected [] = {13, 14, 15, 16, 17, 18};
3568       test_equal_range(a, expected);
3569       const int expected2 [] = {1, 2, 3, 4, 5, 6};
3570       test_equal_range(b, expected2);
3571 
3572       swap(a, b);
3573 
3574       const int expected3 [] = {13, 14, 15, 16, 17, 18};
3575       test_equal_range(b, expected3);
3576       const int expected4 [] = {1, 2, 3, 4, 5, 6};
3577       test_equal_range(a, expected4);
3578    }
3579 
3580    // big-small + small-big
3581    {
3582       Devector a; get_range<Devector>(10, a);
3583       Devector b; get_range<Devector>(9, 11, 11, 17, b);
3584 
3585       swap(a, b);
3586 
3587       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
3588       test_equal_range(b, expected);
3589       const int expected2 [] = {9, 10, 11, 12, 13, 14, 15, 16};
3590       test_equal_range(a, expected2);
3591 
3592       swap(a, b);
3593 
3594       const int expected3 [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
3595       test_equal_range(a, expected3);
3596       const int expected4 [] = {9, 10, 11, 12, 13, 14, 15, 16};
3597       test_equal_range(b, expected4);
3598    }
3599 
3600    // self swap
3601    {
3602       Devector a; get_range<Devector>(10, a);
3603 
3604       swap(a, a);
3605 
3606       const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
3607       test_equal_range(a, expected);
3608    }
3609 
3610    // no overlap
3611    {
3612       Devector a; get_range<Devector>(1, 9, 0, 0, a);
3613       Devector b; get_range<Devector>(0, 0, 11, 17, b);
3614 
3615       a.pop_back();
3616       a.pop_back();
3617 
3618       b.pop_front();
3619       b.pop_front();
3620 
3621       swap(a, b);
3622 
3623       const int expected [] = {13, 14, 15, 16};
3624       test_equal_range(a, expected);
3625       const int expected2 [] = {1, 2, 3, 4, 5, 6};
3626       test_equal_range(b, expected2);
3627    }
3628 
3629    // big-big does not copy or move
3630    {
3631       Devector a; get_range<Devector>(32, a);
3632       Devector b; get_range<Devector>(32, b);
3633       boost::container::vector<int> c; get_range<boost::container::vector<int> >(32, c);
3634 
3635       test_elem_throw::on_copy_after(1);
3636       test_elem_throw::on_move_after(1);
3637 
3638       swap(a, b);
3639 
3640       test_elem_throw::do_not_throw();
3641 
3642       test_equal_range(a, c);
3643       test_equal_range(b, c);
3644    }
3645 }
3646 
test_clear()3647 template <class Devector> void test_clear()
3648 {
3649    {
3650       Devector a;
3651       a.clear();
3652       BOOST_TEST(a.empty());
3653    }
3654 
3655    {
3656       Devector a; get_range<Devector>(8, a);
3657       typename Devector::size_type cp = a.capacity();
3658       a.clear();
3659       BOOST_TEST(a.empty());
3660       BOOST_TEST(cp == a.capacity());
3661    }
3662 }
3663 
test_op_eq()3664 template <class Devector> void test_op_eq()
3665 {
3666    { // equal
3667       Devector a; get_range<Devector>(8, a);
3668       Devector b; get_range<Devector>(8, b);
3669 
3670       BOOST_TEST(a == b);
3671    }
3672 
3673    { // diff size
3674       Devector a; get_range<Devector>(8, a);
3675       Devector b; get_range<Devector>(9, b);
3676 
3677       BOOST_TEST(!(a == b));
3678    }
3679 
3680    { // diff content
3681       Devector a; get_range<Devector>(8, a);
3682       Devector b; get_range<Devector>(2,6,6,10, b);
3683 
3684       BOOST_TEST(!(a == b));
3685    }
3686 }
3687 
test_op_lt()3688 template <class Devector> void test_op_lt()
3689 {
3690    { // little than
3691       Devector a; get_range<Devector>(7, a);
3692       Devector b; get_range<Devector>(8, b);
3693 
3694       BOOST_TEST((a < b));
3695    }
3696 
3697    { // equal
3698       Devector a; get_range<Devector>(8, a);
3699       Devector b; get_range<Devector>(8, b);
3700 
3701       BOOST_TEST(!(a < b));
3702    }
3703 
3704    { // greater than
3705       Devector a; get_range<Devector>(8, a);
3706       Devector b; get_range<Devector>(7, b);
3707 
3708       BOOST_TEST(!(a < b));
3709    }
3710 }
3711 
test_op_ne()3712 template <class Devector> void test_op_ne()
3713 {
3714   { // equal
3715     Devector a; get_range<Devector>(8, a);
3716     Devector b; get_range<Devector>(8, b);
3717 
3718     BOOST_TEST(!(a != b));
3719   }
3720 
3721   { // diff size
3722     Devector a; get_range<Devector>(8, a);
3723     Devector b; get_range<Devector>(9, b);
3724 
3725     BOOST_TEST((a != b));
3726   }
3727 
3728   { // diff content
3729     Devector a; get_range<Devector>(8, a);
3730     Devector b; get_range<Devector>(2,6,6,10, b);
3731 
3732     BOOST_TEST((a != b));
3733   }
3734 }
3735 
3736 
test_op_gt()3737 template <class Devector> void test_op_gt()
3738 {
3739    { // little than
3740       Devector a; get_range<Devector>(7, a);
3741       Devector b; get_range<Devector>(8, b);
3742 
3743       BOOST_TEST(!(a > b));
3744    }
3745 
3746    { // equal
3747       Devector a; get_range<Devector>(8, a);
3748       Devector b; get_range<Devector>(8, b);
3749 
3750       BOOST_TEST(!(a > b));
3751    }
3752 
3753    { // greater than
3754       Devector a; get_range<Devector>(8, a);
3755       Devector b; get_range<Devector>(7, b);
3756 
3757       BOOST_TEST((a > b));
3758    }
3759 }
3760 
test_op_ge()3761 template <class Devector> void test_op_ge()
3762 {
3763    { // little than
3764       Devector a; get_range<Devector>(7, a);
3765       Devector b; get_range<Devector>(8, b);
3766 
3767       BOOST_TEST(!(a >= b));
3768    }
3769 
3770    { // equal
3771       Devector a; get_range<Devector>(8, a);
3772       Devector b; get_range<Devector>(8, b);
3773 
3774       BOOST_TEST((a >= b));
3775    }
3776 
3777    { // greater than
3778       Devector a; get_range<Devector>(8, a);
3779       Devector b; get_range<Devector>(7, b);
3780 
3781       BOOST_TEST((a >= b));
3782    }
3783 }
3784 
test_op_le()3785 template <class Devector> void test_op_le()
3786 {
3787    { // little than
3788       Devector a; get_range<Devector>(7, a);
3789       Devector b; get_range<Devector>(8, b);
3790 
3791       BOOST_TEST((a <= b));
3792    }
3793 
3794    { // equal
3795       Devector a; get_range<Devector>(8, a);
3796       Devector b; get_range<Devector>(8, b);
3797 
3798       BOOST_TEST((a <= b));
3799    }
3800 
3801    { // greater than
3802       Devector a; get_range<Devector>(8, a);
3803       Devector b; get_range<Devector>(7, b);
3804 
3805       BOOST_TEST(!(a <= b));
3806    }
3807 }
3808 
3809 
3810 template <class Devector>
test_devector_default_constructible(dtl::true_)3811 void test_devector_default_constructible(dtl::true_)
3812 {
3813    test_constructor_n<Devector>();
3814    test_resize_front<Devector>();
3815    test_resize_back<Devector>();
3816 }
3817 
3818 template <class Devector>
test_devector_default_constructible(dtl::false_)3819 void test_devector_default_constructible(dtl::false_)
3820 {}
3821 
3822 template <class Devector>
test_devector_copy_constructible(dtl::false_)3823 void test_devector_copy_constructible(dtl::false_)
3824 {}
3825 
3826 
3827 template <class Devector>
test_devector_copy_constructible(dtl::true_)3828 void test_devector_copy_constructible(dtl::true_)
3829 {
3830    test_constructor_n_copy<Devector>();
3831    test_constructor_input_range<Devector>();
3832    test_constructor_forward_range<Devector>();
3833    test_constructor_pointer_range<Devector>();
3834    test_copy_constructor<Devector>();
3835    test_assignment<Devector>();
3836    test_assign_input_range<Devector>();
3837    test_assign_pointer_range<Devector>();
3838    test_assign_n<Devector>();
3839    test_resize_front_copy<Devector>();
3840    test_push_back<Devector>();
3841    //test_unsafe_push_back<Devector>();
3842    test_push_front<Devector>();
3843    //test_unsafe_push_front<Devector>();
3844    test_resize_back_copy<Devector>();
3845    test_insert<Devector>();
3846    test_insert_n<Devector>();
3847    test_insert_input_range<Devector>();
3848    test_insert_range<Devector>();
3849    test_insert_init_list<Devector>();
3850 }
3851 
3852 template <class Devector>
test_devector()3853 void test_devector()
3854 {
3855    test_devector_default_constructible<Devector>(dtl::bool_<boost::is_default_constructible<typename Devector::value_type>::value>());
3856    test_devector_copy_constructible<Devector>(dtl::bool_<boost::move_detail::is_copy_constructible<typename Devector::value_type>::value>());
3857 
3858    test_constructor_default<Devector>();
3859    test_constructor_allocator<Devector>();
3860 
3861    test_constructor_reserve_only<Devector>();
3862    test_constructor_reserve_only_front_back<Devector>();
3863    //test_constructor_unsafe_uninitialized<Devector>();
3864 
3865    test_move_constructor<Devector>();
3866    test_destructor<Devector>();
3867 
3868    test_move_assignment<Devector>();
3869    test_get_allocator<Devector>();
3870    test_begin_end<Devector>();
3871    test_empty<Devector>();
3872    test_size<Devector>();
3873    test_capacity<Devector>();
3874 
3875    //test_unsafe_uninitialized_resize_front<Devector>();
3876    //test_unsafe_uninitialized_resize_back<Devector>();
3877    test_reserve_front<Devector>();
3878    test_reserve_back<Devector>();
3879    test_index_operator<Devector>();
3880    test_at<Devector>();
3881    test_front<Devector>();
3882    test_back<Devector>();
3883    test_emplace_front<Devector>();
3884    test_push_front_rvalue<Devector>();
3885 
3886    //test_unsafe_push_front_rvalue<Devector>();
3887    test_pop_front<Devector>();
3888    test_emplace_back<Devector>();
3889    test_push_back_rvalue<Devector>();
3890 
3891    //test_unsafe_push_back_rvalue<Devector>();
3892    test_pop_back<Devector>();
3893    test_emplace<Devector>();
3894    test_insert_rvalue<Devector>();
3895 
3896    test_erase<Devector>();
3897    test_erase_range<Devector>();
3898    test_swap<Devector>();
3899    test_clear<Devector>();
3900    test_op_eq<Devector>();
3901    test_op_lt<Devector>();
3902    test_op_ne<Devector>();
3903    test_op_gt<Devector>();
3904    test_op_ge<Devector>();
3905    test_op_le<Devector>();
3906 }
3907 
3908 class recursive_devector
3909 {
3910    public:
recursive_devector(const recursive_devector & x)3911    recursive_devector(const recursive_devector &x)
3912       : devector_(x.devector_)
3913    {}
3914 
operator =(const recursive_devector & x)3915    recursive_devector & operator=(const recursive_devector &x)
3916    {  this->devector_ = x.devector_;   return *this; }
3917 
3918    int id_;
3919    devector<recursive_devector> devector_;
3920    devector<recursive_devector>::iterator it_;
3921    devector<recursive_devector>::const_iterator cit_;
3922    devector<recursive_devector>::reverse_iterator rit_;
3923    devector<recursive_devector>::const_reverse_iterator crit_;
3924 };
3925 
test_recursive_devector()3926 void test_recursive_devector()//Test for recursive types
3927 {
3928    devector<recursive_devector> rdv;
3929    BOOST_TEST(rdv.empty());
3930    BOOST_TEST(rdv.get_alloc_count() == 0u);
3931    BOOST_TEST(rdv.capacity() == 0u);
3932 }
3933 
3934 template<class VoidAllocator>
3935 struct GetAllocatorCont
3936 {
3937    template<class ValueType>
3938    struct apply
3939    {
3940       typedef vector< ValueType
3941                     , typename allocator_traits<VoidAllocator>
3942                         ::template portable_rebind_alloc<ValueType>::type
3943                     > type;
3944    };
3945 };
3946 
3947 #ifdef _MSC_VER
3948    #pragma warning (pop)
3949 #endif
3950 
3951 
test_all()3952 void test_all()
3953 {/*
3954    test_recursive_devector();
3955    test_max_size();
3956    test_exceeding_max_size();
3957    shrink_to_fit();
3958    test_data();
3959    test_il_assignment< devector<int> >();
3960    test_assign_forward_range< devector<int> >();
3961    test_assign_il<devector<int> >();
3962 */
3963    //test_devector< devector<int> >();
3964    test_devector< devector<regular_elem> >();
3965    test_devector< devector<noex_move> >();
3966    test_devector< devector<noex_copy> >();
3967    test_devector< devector<only_movable> >();
3968    test_devector< devector<no_default_ctor> >();
3969 
3970    ////////////////////////////////////
3971    //    Allocator propagation testing
3972    ////////////////////////////////////
3973    (void)boost::container::test::test_propagate_allocator<boost_container_devector>();
3974 }
3975 
3976 
getom()3977 boost::container::vector<only_movable> getom()
3978 {
3979    typedef boost::container::vector<only_movable> V;
3980    V v;
3981    return BOOST_MOVE_RET(V, v);
3982 }
3983 
3984 
get()3985 boost::container::vector<boost::container::test::movable_int> get()
3986 {
3987    typedef boost::container::vector<boost::container::test::movable_int> V;
3988    V v;
3989    return BOOST_MOVE_RET(V, v);
3990 }
3991 
main()3992 int main()
3993 {
3994 //   boost::container::vector<boost::container::test::movable_int>a(get());
3995    //boost::container::vector<only_movable> b(getom());
3996    //boost::container::vector<only_movable> c(get_range< boost::container::vector<only_movable> >(1, 5, 5, 9));
3997    test_all();
3998    return boost::report_errors();
3999 }
4000