4066 lines
106 KiB
C++
4066 lines
106 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// \(C\) Copyright Benedek Thaler 2015-2016
|
|
// \(C\) Copyright Ion Gaztanaga 2019-2020. Distributed under the Boost
|
|
// Software License, Version 1.0. (See accompanying file
|
|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// See http://www.boost.org/libs/container for documentation.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <boost/core/lightweight_test.hpp>
|
|
#include <cstring> // memcmp
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <limits>
|
|
#include <memory>
|
|
#include <boost/container/list.hpp>
|
|
#include <boost/container/allocator.hpp>
|
|
#include <boost/container/vector.hpp>
|
|
#include <boost/type_traits/is_default_constructible.hpp>
|
|
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
|
#include "dummy_test_allocator.hpp"
|
|
#include "propagate_allocator_test.hpp"
|
|
#include "check_equal_containers.hpp"
|
|
#include "movable_int.hpp"
|
|
#include <boost/static_assert.hpp>
|
|
|
|
#include <boost/algorithm/cxx14/equal.hpp>
|
|
|
|
#define BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
|
|
#include <boost/container/devector.hpp>
|
|
#undef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
|
|
|
|
#include "test_util.hpp"
|
|
#include "test_elem.hpp"
|
|
#include "input_iterator.hpp"
|
|
#include "vector_test.hpp"
|
|
#include "default_init_test.hpp"
|
|
#include "../../intrusive/test/iterator_test.hpp"
|
|
|
|
using namespace boost::container;
|
|
|
|
struct boost_container_devector;
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (push)
|
|
#pragma warning (disable : 4127) // conditional expression is constant
|
|
#endif
|
|
|
|
namespace boost {
|
|
namespace container {
|
|
namespace test {
|
|
|
|
template<>
|
|
struct alloc_propagate_base<boost_container_devector>
|
|
{
|
|
template <class T, class Allocator>
|
|
struct apply
|
|
{
|
|
typedef devector<T, Allocator> type;
|
|
};
|
|
};
|
|
|
|
}}} //namespace boost::container::test {
|
|
|
|
struct different_growth_policy
|
|
{
|
|
template <typename SizeType>
|
|
static SizeType new_capacity(SizeType capacity)
|
|
{
|
|
return (capacity) ? capacity * 4u : 32u;
|
|
}
|
|
};
|
|
|
|
// END HELPERS
|
|
|
|
template <class Devector> void test_constructor_default()
|
|
{
|
|
Devector a;
|
|
|
|
BOOST_TEST(a.empty());
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
BOOST_TEST(a.capacity() == 0u);
|
|
}
|
|
|
|
template <class Devector> void test_constructor_allocator()
|
|
{
|
|
typename Devector::allocator_type alloc_template;
|
|
|
|
Devector a(alloc_template);
|
|
|
|
BOOST_TEST(a.empty());
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
BOOST_TEST(a.capacity() == 0u);
|
|
}
|
|
|
|
template <class Devector> void test_constructor_reserve_only()
|
|
{
|
|
{
|
|
Devector a(16, reserve_only_tag_t());
|
|
BOOST_TEST(a.size() == 0u);
|
|
BOOST_TEST(a.capacity() >= 16u);
|
|
}
|
|
|
|
{
|
|
Devector b(0, reserve_only_tag_t());
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_constructor_reserve_only_front_back()
|
|
{
|
|
{
|
|
Devector a(8, 8, reserve_only_tag_t());
|
|
BOOST_TEST(a.size() == 0u);
|
|
BOOST_TEST(a.front_free_capacity() >= 8u);
|
|
BOOST_TEST(a.back_free_capacity() >= 8u);
|
|
|
|
for (int i = 8; i; --i)
|
|
{
|
|
a.emplace_front(i);
|
|
}
|
|
|
|
for (int i = 9; i < 17; ++i)
|
|
{
|
|
a.emplace_back(i);
|
|
}
|
|
|
|
const int expected [] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() <= 1u);
|
|
}
|
|
|
|
{
|
|
Devector b(0, 0, reserve_only_tag_t());
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_constructor_n()
|
|
{
|
|
{
|
|
Devector a(8);
|
|
const int expected [] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{
|
|
Devector b(0);
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_default_constructible<T>::value)
|
|
{
|
|
test_elem_throw::on_ctor_after(4);
|
|
BOOST_TEST_THROWS(Devector(8), test_exception);
|
|
BOOST_TEST(test_elem_base::no_living_elem());
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_constructor_n_copy_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
test_elem_throw::on_copy_after(4);
|
|
const T x(404);
|
|
BOOST_TEST_THROWS(Devector(8, x), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
|
|
template <class Devector> void test_constructor_n_copy_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_constructor_n_copy()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
{
|
|
const T x(9);
|
|
Devector a(8, x);
|
|
const int expected [] = {9, 9, 9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{
|
|
const T x(9);
|
|
Devector b(0, x);
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
test_constructor_n_copy_throwing<Devector>
|
|
(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
|
|
BOOST_TEST(test_elem_base::no_living_elem());
|
|
}
|
|
|
|
template <class Devector> void test_constructor_input_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
{
|
|
devector<T> expected; get_range<devector<T> >(16, expected);
|
|
devector<T> input = expected;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a(input_begin, input_end);
|
|
BOOST_TEST(a == expected);
|
|
}
|
|
|
|
{ // empty range
|
|
devector<T> input;
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
|
|
Devector b(input_begin, input_begin);
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
BOOST_TEST(test_elem_base::no_living_elem());
|
|
/* //if move_if_noexcept is implemented
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
devector<T> input; get_range<devector<T> >(16, input);
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
test_elem_throw::on_copy_after(4);
|
|
|
|
BOOST_TEST_THROWS(Devector c(input_begin, input_end), test_exception);
|
|
}
|
|
|
|
BOOST_TEST(test_elem_base::no_living_elem());
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
*/
|
|
}
|
|
|
|
|
|
void test_constructor_forward_range_throwing(dtl::true_)
|
|
{}
|
|
|
|
void test_constructor_forward_range_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_constructor_forward_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
boost::container::list<T> ncx;
|
|
ncx.emplace_back(1);
|
|
ncx.emplace_back(2);
|
|
ncx.emplace_back(3);
|
|
ncx.emplace_back(4);
|
|
ncx.emplace_back(5);
|
|
ncx.emplace_back(6);
|
|
ncx.emplace_back(7);
|
|
ncx.emplace_back(8);
|
|
const boost::container::list<T> &x = ncx;
|
|
|
|
{
|
|
Devector a(x.begin(), x.end());
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() <= 1u);
|
|
a.reset_alloc_stats();
|
|
}
|
|
|
|
{
|
|
Devector b(x.begin(), x.begin());
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
test_elem_throw::on_copy_after(4);
|
|
BOOST_TEST_THROWS(Devector c(x.begin(), x.end()), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_constructor_pointer_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
boost::container::vector<T> x; get_range<boost::container::vector<T> >(8, x);
|
|
const T* xbeg = x.data();
|
|
const T* xend = x.data() + x.size();
|
|
|
|
{
|
|
Devector a(xbeg, xend);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() <= 1u);
|
|
}
|
|
|
|
{
|
|
Devector b(xbeg, xbeg);
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
test_elem_throw::on_copy_after(4);
|
|
BOOST_TEST_THROWS(Devector c(xbeg, xend), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_copy_constructor()
|
|
{
|
|
{
|
|
Devector a;
|
|
Devector b(a);
|
|
|
|
test_equal_range(b);
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b(a);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(b.get_alloc_count() <= 1u);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
Devector a; get_range<Devector>(8, a);
|
|
|
|
test_elem_throw::on_copy_after(4);
|
|
BOOST_TEST_THROWS(Devector b(a), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_move_constructor()
|
|
{
|
|
{ // empty
|
|
Devector a;
|
|
Devector b(boost::move(a));
|
|
|
|
BOOST_TEST(a.empty());
|
|
BOOST_TEST(b.empty());
|
|
}
|
|
|
|
{ // maybe small
|
|
Devector a; get_range<Devector>(1, 5, 5, 9, a);
|
|
Devector b(boost::move(a));
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
|
|
// a is unspecified but valid state
|
|
a.clear();
|
|
BOOST_TEST(a.empty());
|
|
}
|
|
|
|
{ // big
|
|
Devector a; get_range<Devector>(32, a);
|
|
Devector b(boost::move(a));
|
|
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(32, expected);
|
|
test_equal_range(b, expected);
|
|
|
|
// a is unspecified but valid state
|
|
a.clear();
|
|
BOOST_TEST(a.empty());
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_destructor()
|
|
{
|
|
Devector a;
|
|
|
|
Devector b; get_range<Devector>(3, b);
|
|
}
|
|
|
|
template <class Devector> void test_assignment()
|
|
{
|
|
const typename Devector::size_type alloc_count =
|
|
boost::container::allocator_traits
|
|
< typename Devector::allocator_type >::propagate_on_container_copy_assignment::value;
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
Devector c; get_range<Devector>(6, c);
|
|
Devector &b = c;
|
|
|
|
a = b;
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
const Devector b;
|
|
|
|
a = b;
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
Devector c; get_range<Devector>(6, c);
|
|
const Devector &b = c;
|
|
|
|
a = b;
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
Devector c; get_range<Devector>(6, c);
|
|
const Devector &b = c;
|
|
|
|
a = b;
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == alloc_count);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
Devector c; get_range<Devector>(6, c);
|
|
const Devector &b = c;
|
|
|
|
a = b;
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == alloc_count);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
Devector c; get_range<Devector>(12, c);
|
|
const Devector &b = c;
|
|
|
|
a = b;
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == alloc_count);
|
|
}
|
|
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
Devector c; get_range<Devector>(12, c);
|
|
const Devector &b = c;
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(a = b, test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
*/
|
|
}
|
|
|
|
template <class Devector> void test_move_assignment_throwing(dtl::true_)
|
|
// move should be used on the slow path
|
|
{
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
Devector b; get_range<Devector>(6, b);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
a = boost::move(b);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
|
|
b.clear();
|
|
test_equal_range(b);
|
|
}
|
|
|
|
template <class Devector> void test_move_assignment_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_move_assignment()
|
|
{
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
Devector b; get_range<Devector>(6, b);
|
|
|
|
a = boost::move(b);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
|
|
// b is in unspecified but valid state
|
|
b.clear();
|
|
test_equal_range(b);
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
Devector b;
|
|
|
|
a = boost::move(b);
|
|
|
|
test_equal_range(a);
|
|
test_equal_range(b);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
Devector b; get_range<Devector>(6, b);
|
|
|
|
a = boost::move(b);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
|
|
b.clear();
|
|
test_equal_range(b);
|
|
}
|
|
|
|
typedef typename Devector::value_type T;
|
|
test_move_assignment_throwing<Devector>
|
|
(boost::move_detail::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_il_assignment()
|
|
{
|
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
a = {1, 2, 3, 4, 5, 6 };
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
|
|
//Visual 2013 has some problems with empty initializer lists.
|
|
#if defined(_MSC_VER) && (_MSC_VER > 1800)
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
a = {};
|
|
|
|
test_equal_range(a);
|
|
}
|
|
#endif
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
|
|
a = {1, 2, 3, 4, 5, 6};
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a = {1, 2, 3, 4, 5, 6};
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a = {1, 2, 3, 4, 5, 6};
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
|
|
BOOST_CONTAINER_TRY
|
|
{
|
|
a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
BOOST_TEST(false);
|
|
}
|
|
BOOST_CONTAINER_CATCH(const test_exception&) {}
|
|
BOOST_CONTAINER_CATCH_END
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
#endif //BOOST_NO_EXCEPTIONS*/
|
|
#endif //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
}
|
|
|
|
template <class Devector> void test_assign_input_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // assign to empty, keep it small
|
|
devector<T> expected; get_range<Devector>(1, 13, 13, 25, expected);
|
|
devector<T> input = expected;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a;
|
|
a.reset_alloc_stats();
|
|
a.assign(input_begin, input_end);
|
|
|
|
BOOST_TEST(a == expected);
|
|
}
|
|
|
|
{ // assign to empty (maybe small)
|
|
devector<T> input; get_range<devector<T> >(6, input);
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a;
|
|
|
|
a.assign(input_begin, input_end);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign from empty
|
|
devector<T> input; get_range<devector<T> >(6, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
|
|
Devector a; get_range<Devector>(6, a);
|
|
a.assign(input_begin, input_begin);
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
devector<T> input; get_range<devector<T> >(6, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.assign(input_begin, input_end);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign to free front
|
|
devector<T> input; get_range<devector<T> >(6, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(input_begin, input_end);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
devector<T> input; get_range<devector<T> >(6, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(input_begin, input_end);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
devector<T> input; get_range<devector<T> >(12, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(input_begin, input_end);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
|
|
devector<T> input; get_range<devector<T> >(12, input);
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.end());
|
|
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(a.assign(input_begin, input_end), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
*/
|
|
}
|
|
|
|
template <class Devector> void test_assign_forward_range_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_assign_forward_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef boost::container::list<T> List;
|
|
|
|
boost::container::list<T> x;
|
|
typedef typename List::iterator list_iterator;
|
|
x.emplace_back(1);
|
|
x.emplace_back(2);
|
|
x.emplace_back(3);
|
|
x.emplace_back(4);
|
|
x.emplace_back(5);
|
|
x.emplace_back(6);
|
|
x.emplace_back(7);
|
|
x.emplace_back(8);
|
|
x.emplace_back(9);
|
|
x.emplace_back(10);
|
|
x.emplace_back(11);
|
|
x.emplace_back(12);
|
|
|
|
list_iterator one = x.begin();
|
|
list_iterator six = one;
|
|
list_iterator twelve = one;
|
|
|
|
iterator_advance(six, 6);
|
|
iterator_advance(twelve, 12);
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
a.assign(one, one);
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, twelve);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR(! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(a.assign(one, twelve), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS*/
|
|
}
|
|
|
|
template <class Devector> void test_assign_pointer_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
boost::container::vector<T> x; get_range<boost::container::vector<T> >(12, x);
|
|
const T* one = x.data();
|
|
const T* six = one + 6;
|
|
const T* twelve = one + 12;
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
a.assign(one, one);
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, six);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(one, twelve);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(a.assign(one, twelve), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS*/
|
|
}
|
|
|
|
template <class Devector> void test_assign_n()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
|
|
a.assign(6, T(9));
|
|
|
|
const int expected[] = {9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
a.assign(0, T(404));
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
|
|
a.assign(6, T(9));
|
|
|
|
const int expected[] = {9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(6, T(9));
|
|
|
|
const int expected[] = {9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(6, T(9));
|
|
|
|
const int expected[] = {9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign(12, T(9));
|
|
|
|
const int expected[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(a.assign(32, T(9)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
*/
|
|
}
|
|
|
|
template <class Devector> void test_assign_il()
|
|
{
|
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
|
|
{ // assign to empty (maybe small)
|
|
Devector a;
|
|
|
|
a.assign({1, 2, 3, 4, 5, 6});
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
|
|
{ // assign from empty
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
a.assign({});
|
|
|
|
test_equal_range(a);
|
|
}
|
|
|
|
{ // assign to non-empty
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
|
|
a.assign({1, 2, 3, 4, 5, 6});
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
|
|
{ // assign to free front
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign({1, 2, 3, 4, 5, 6});
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment overlaps contents
|
|
Devector a; get_range<Devector>(11, 15, 15, 19, a);
|
|
a.reserve_front(12);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign({1, 2, 3, 4, 5, 6});
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // assignment exceeds contents
|
|
Devector a; get_range<Devector>(11, 13, 13, 15, a);
|
|
a.reserve_front(8);
|
|
a.reserve_back(8);
|
|
a.reset_alloc_stats();
|
|
|
|
a.assign({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// strong guarantee if reallocation is needed (no guarantee otherwise)
|
|
Devector a; get_range<Devector>(6, a);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
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);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6});
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS*/
|
|
#endif //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
}
|
|
|
|
template <class Devector> void test_get_allocator()
|
|
{
|
|
Devector a;
|
|
(void) a.get_allocator();
|
|
}
|
|
|
|
template <class Devector> void test_begin_end()
|
|
{
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(10, expected);
|
|
{
|
|
Devector actual; get_range<Devector>(10, actual);
|
|
|
|
BOOST_TEST(boost::algorithm::equal(expected.begin(), expected.end(), actual.begin(), actual.end()));
|
|
BOOST_TEST(boost::algorithm::equal(expected.rbegin(), expected.rend(), actual.rbegin(), actual.rend()));
|
|
BOOST_TEST(boost::algorithm::equal(expected.cbegin(), expected.cend(), actual.cbegin(), actual.cend()));
|
|
BOOST_TEST(boost::algorithm::equal(expected.crbegin(), expected.crend(), actual.crbegin(), actual.crend()));
|
|
}
|
|
|
|
{
|
|
Devector cactual; get_range<Devector>(10, cactual);
|
|
|
|
BOOST_TEST(boost::algorithm::equal(expected.begin(), expected.end(), cactual.begin(), cactual.end()));
|
|
BOOST_TEST(boost::algorithm::equal(expected.rbegin(), expected.rend(), cactual.rbegin(), cactual.rend()));
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_empty()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
Devector a;
|
|
BOOST_TEST(a.empty());
|
|
|
|
a.push_front(T(1));
|
|
BOOST_TEST(! a.empty());
|
|
|
|
a.pop_back();
|
|
BOOST_TEST(a.empty());
|
|
|
|
Devector b(16, reserve_only_tag_t());
|
|
BOOST_TEST(b.empty());
|
|
|
|
Devector c; get_range<Devector>(3, c);
|
|
BOOST_TEST(! c.empty());
|
|
}
|
|
|
|
//template <typename ST>
|
|
//using gp_devector = devector<unsigned, different_growth_policy>;
|
|
|
|
void test_max_size()
|
|
{/*
|
|
gp_devector<unsigned char> a;
|
|
BOOST_TEST(a.max_size() == (std::numeric_limits<unsigned char>::max)());
|
|
|
|
gp_devector<unsigned short> b;
|
|
BOOST_TEST(b.max_size() == (std::numeric_limits<unsigned short>::max)());
|
|
|
|
gp_devector<unsigned int> c;
|
|
BOOST_TEST(c.max_size() >= b.max_size());
|
|
|
|
gp_devector<std::size_t> d;
|
|
BOOST_TEST(d.max_size() >= c.max_size());
|
|
*/
|
|
}
|
|
|
|
void test_exceeding_max_size()
|
|
{/*
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
using Devector = gp_devector<unsigned char>;
|
|
|
|
Devector a((std::numeric_limits<typename Devector::size_type>::max)());
|
|
BOOST_TEST_THROWS(a.emplace_back(404), std::length_error);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
*/
|
|
}
|
|
|
|
template <class Devector> void test_size()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
Devector a;
|
|
BOOST_TEST(a.size() == 0u);
|
|
|
|
a.push_front(T(1));
|
|
BOOST_TEST(a.size() == 1u);
|
|
|
|
a.pop_back();
|
|
BOOST_TEST(a.size() == 0u);
|
|
|
|
Devector b(16, reserve_only_tag_t());
|
|
BOOST_TEST(b.size() == 0u);
|
|
|
|
Devector c; get_range<Devector>(3, c);
|
|
BOOST_TEST(c.size() == 3u);
|
|
}
|
|
|
|
template <class Devector> void test_capacity()
|
|
{
|
|
Devector a;
|
|
BOOST_TEST(a.capacity() == 0u);
|
|
|
|
Devector b(128, reserve_only_tag_t());
|
|
BOOST_TEST(b.capacity() >= 128u);
|
|
|
|
Devector c; get_range<Devector>(10, c);
|
|
BOOST_TEST(c.capacity() >= 10u);
|
|
}
|
|
|
|
template <class Devector> void test_resize_front_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector d; get_range<Devector>(5, d);
|
|
boost::container::vector<int> d_origi; get_range<boost::container::vector<int> >(5, d_origi);
|
|
iterator origi_begin = d.begin();
|
|
|
|
test_elem_throw::on_ctor_after(3);
|
|
BOOST_TEST_THROWS(d.resize_front(256), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(d, d_origi);
|
|
BOOST_TEST(origi_begin == d.begin());
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_resize_front_throwing(dtl::false_)
|
|
{}
|
|
|
|
|
|
template <class Devector> void test_resize_front()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
// size < required, alloc needed
|
|
{
|
|
Devector a; get_range<Devector>(5, a);
|
|
a.resize_front(8);
|
|
const int expected [] = {0, 0, 0, 1, 2, 3, 4, 5};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
// size < required, but capacity provided
|
|
{
|
|
Devector b; get_range<Devector>(5, b);
|
|
b.reserve_front(16);
|
|
b.resize_front(8);
|
|
const int expected [] = {0, 0, 0, 1, 2, 3, 4, 5};
|
|
test_equal_range(b, expected);
|
|
}
|
|
/*
|
|
// size < required, move would throw
|
|
if (! boost::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value)
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
|
|
test_elem_throw::on_move_after(3);
|
|
c.resize_front(8); // shouldn't use the throwing move
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, {0, 0, 0, 1, 2, 3, 4, 5});
|
|
}
|
|
*/
|
|
|
|
test_resize_front_throwing<Devector>
|
|
(dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
|
|
// size >= required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_front(4);
|
|
const int expected [] = {3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, does not fit front small buffer
|
|
{
|
|
boost::container::vector<int> expected(128);
|
|
Devector g;
|
|
g.resize_front(128);
|
|
test_equal_range(g, expected);
|
|
}
|
|
|
|
// size = required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_front(6);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_resize_front_copy_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
// size < required, copy throws
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(c.resize_front(256, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, c_origi);
|
|
}
|
|
|
|
// size < required, copy throws, but later
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
|
|
iterator origi_begin = c.begin();
|
|
|
|
test_elem_throw::on_copy_after(7);
|
|
BOOST_TEST_THROWS(c.resize_front(256, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, c_origi);
|
|
BOOST_TEST(origi_begin == c.begin());
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_resize_front_copy_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_resize_front_copy()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
// size < required, alloc needed
|
|
{
|
|
Devector a; get_range<Devector>(5, a);
|
|
a.resize_front(8, T(9));
|
|
const int expected [] = {9, 9, 9, 1, 2, 3, 4, 5};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
// size < required, but capacity provided
|
|
{
|
|
Devector b; get_range<Devector>(5, b);
|
|
b.reserve_front(16);
|
|
b.resize_front(8, T(9));
|
|
const int expected [] = {9, 9, 9, 1, 2, 3, 4, 5};
|
|
test_equal_range(b, expected);
|
|
}
|
|
|
|
test_resize_front_copy_throwing<Devector>
|
|
(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
|
|
// size >= required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_front(4, T(404));
|
|
const int expected[] = {3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, does not fit front small buffer
|
|
{
|
|
boost::container::vector<int> expected(128, 9);
|
|
Devector g;
|
|
g.resize_front(128, T(9));
|
|
test_equal_range(g, expected);
|
|
}
|
|
|
|
// size = required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_front(6, T(9));
|
|
const int expected[] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, tmp is already inserted
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
T tmp = *(f.begin() + 1);
|
|
f.resize_front(16, tmp);
|
|
const int expected[] = {2,2,2,2,2,2,2,2,1,2,3,4,5,6,7,8};
|
|
test_equal_range(f, expected);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_resize_back_throwing(dtl::true_)
|
|
// size < required, constructor throws
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector d; get_range<Devector>(5, d);
|
|
boost::container::vector<int> d_origi; get_range<boost::container::vector<int> >(5, d_origi);
|
|
iterator origi_begin = d.begin();
|
|
|
|
test_elem_throw::on_ctor_after(3);
|
|
BOOST_TEST_THROWS(d.resize_back(256), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(d, d_origi);
|
|
BOOST_TEST(origi_begin == d.begin());
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_resize_back_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_resize_back()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
// size < required, alloc needed
|
|
{
|
|
Devector a; get_range<Devector>(5, a);
|
|
a.resize_back(8);
|
|
const int expected [] = {1, 2, 3, 4, 5, 0, 0, 0};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
// size < required, but capacity provided
|
|
{
|
|
Devector b; get_range<Devector>(5, b);
|
|
b.reserve_back(16);
|
|
b.resize_back(8);
|
|
const int expected [] = {1, 2, 3, 4, 5, 0, 0, 0};
|
|
test_equal_range(b, expected);
|
|
}
|
|
/*
|
|
// size < required, move would throw
|
|
if (! boost::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value)
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
|
|
test_elem_throw::on_move_after(3);
|
|
c.resize_back(8); // shouldn't use the throwing move
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, {1, 2, 3, 4, 5, 0, 0, 0});
|
|
}
|
|
*/
|
|
|
|
test_resize_back_throwing<Devector>
|
|
(dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
|
|
// size >= required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_back(4);
|
|
const int expected [] = {1, 2, 3, 4};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, does not fit front small buffer
|
|
{
|
|
boost::container::vector<int> expected(128);
|
|
Devector g;
|
|
g.resize_back(128);
|
|
test_equal_range(g, expected);
|
|
}
|
|
|
|
// size = required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_back(6);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_resize_back_copy_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
// size < required, copy throws
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, c_origi);
|
|
}
|
|
|
|
// size < required, copy throws, but later
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
|
|
iterator origi_begin = c.begin();
|
|
|
|
test_elem_throw::on_copy_after(7);
|
|
BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, c_origi);
|
|
BOOST_TEST(origi_begin == c.begin());
|
|
}
|
|
|
|
// size < required, copy throws
|
|
{
|
|
Devector c; get_range<Devector>(5, c);
|
|
boost::container::vector<int> c_origi; get_range<boost::container::vector<int> >(5, c_origi);
|
|
iterator origi_begin = c.begin();
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(c.resize_back(256, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(c, c_origi);
|
|
BOOST_TEST(origi_begin == c.begin());
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_resize_back_copy_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_resize_back_copy()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
// size < required, alloc needed
|
|
{
|
|
Devector a; get_range<Devector>(5, a);
|
|
a.resize_back(8, T(9));
|
|
const int expected [] = {1, 2, 3, 4, 5, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
// size < required, but capacity provided
|
|
{
|
|
Devector b; get_range<Devector>(5, b);
|
|
b.reserve_back(16);
|
|
b.resize_back(8, T(9));
|
|
const int expected [] = {1, 2, 3, 4, 5, 9, 9, 9};
|
|
test_equal_range(b, expected);
|
|
}
|
|
|
|
test_resize_back_copy_throwing<Devector>
|
|
(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
|
|
// size >= required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_back(4, T(404));
|
|
const int expected [] = {1, 2, 3, 4};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, does not fit front small buffer
|
|
{
|
|
boost::container::vector<int> expected(128, 9);
|
|
Devector g;
|
|
g.resize_back(128, T(9));
|
|
test_equal_range(g, expected);
|
|
}
|
|
|
|
// size = required
|
|
{
|
|
Devector e; get_range<Devector>(6, e);
|
|
e.resize_back(6, T(9));
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(e, expected);
|
|
}
|
|
|
|
// size < required, tmp is already inserted
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
T tmp = *(f.begin() + 1);
|
|
f.resize_back(16, tmp);
|
|
const int expected [] = {1,2,3,4,5,6,7,8,2,2,2,2,2,2,2,2};
|
|
test_equal_range(f, expected);
|
|
}
|
|
}
|
|
|
|
/*
|
|
template <class Devector> void test_constructor_unsafe_uninitialized()
|
|
{
|
|
{
|
|
Devector a(8, unsafe_uninitialized_tag_t());
|
|
BOOST_TEST(a.size() == 8u);
|
|
|
|
for (int i = 0; i < 8; ++i)
|
|
{
|
|
new (a.data() + i) T(i+1);
|
|
}
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
{
|
|
Devector b(0, unsafe_uninitialized_tag_t());
|
|
BOOST_TEST(b.get_alloc_count() == 0u);
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
template <class Devector> void test_unsafe_uninitialized_resize_front()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // noop
|
|
Devector a; get_range<Devector>(8, a);
|
|
a.reset_alloc_stats();
|
|
|
|
a.unsafe_uninitialized_resize_front(a.size());
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // grow (maybe has enough capacity)
|
|
Devector b; get_range<Devector>(0, 0, 5, 9, b);
|
|
|
|
b.unsafe_uninitialized_resize_front(8);
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
new (b.data() + i) T(i+1);
|
|
}
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
}
|
|
|
|
{ // shrink uninitialized
|
|
Devector c; get_range<Devector>(8, c);
|
|
|
|
c.unsafe_uninitialized_resize_front(16);
|
|
c.unsafe_uninitialized_resize_front(8);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(c, expected );
|
|
}
|
|
|
|
if (std::is_trivially_destructible<T>::value)
|
|
{
|
|
// shrink
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.unsafe_uninitialized_resize_front(4);
|
|
|
|
test_equal_range(d, {5, 6, 7, 8});
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_unsafe_uninitialized_resize_back()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // noop
|
|
Devector a; get_range<Devector>(8, a);
|
|
a.reset_alloc_stats();
|
|
|
|
a.unsafe_uninitialized_resize_back(a.size());
|
|
|
|
test_equal_range(a, {1, 2, 3, 4, 5, 6, 7, 8});
|
|
BOOST_TEST(a.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // grow (maybe has enough capacity)
|
|
Devector b; get_range<Devector>(1, 5, 0, 0, b);
|
|
|
|
b.unsafe_uninitialized_resize_back(8);
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
new (b.data() + 4 + i) T(i+5);
|
|
}
|
|
|
|
test_equal_range(b, {1, 2, 3, 4, 5, 6, 7, 8});
|
|
}
|
|
|
|
{ // shrink uninitialized
|
|
Devector c; get_range<Devector>(8, c);
|
|
|
|
c.unsafe_uninitialized_resize_back(16);
|
|
c.unsafe_uninitialized_resize_back(8);
|
|
|
|
test_equal_range(c, {1, 2, 3, 4, 5, 6, 7, 8});
|
|
}
|
|
|
|
if (std::is_trivially_destructible<T>::value)
|
|
{
|
|
// shrink
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.unsafe_uninitialized_resize_back(4);
|
|
|
|
test_equal_range(d, {1, 2, 3, 4});
|
|
}
|
|
}
|
|
*/
|
|
|
|
template <class Devector> void test_reserve_front()
|
|
{
|
|
typedef typename Devector::value_type value_type;
|
|
Devector a;
|
|
|
|
a.reserve_front(100);
|
|
for (int i = 0; i < 100; ++i)
|
|
{
|
|
a.push_front(value_type(i));
|
|
}
|
|
|
|
BOOST_TEST(a.get_alloc_count() == 1u);
|
|
|
|
Devector b;
|
|
b.reserve_front(4);
|
|
b.reserve_front(6);
|
|
b.reserve_front(4);
|
|
b.reserve_front(8);
|
|
b.reserve_front(16);
|
|
}
|
|
|
|
template <class Devector> void test_reserve_back()
|
|
{
|
|
Devector a;
|
|
typedef typename Devector::value_type value_type;
|
|
a.reserve_back(100);
|
|
for (int i = 0; i < 100; ++i)
|
|
{
|
|
a.push_back(value_type(i));
|
|
}
|
|
|
|
BOOST_TEST(a.get_alloc_count() == 1u);
|
|
|
|
Devector b;
|
|
b.reserve_back(4);
|
|
b.reserve_back(6);
|
|
b.reserve_back(4);
|
|
b.reserve_back(8);
|
|
b.reserve_back(16);
|
|
}
|
|
|
|
template <typename Devector>
|
|
void test_shrink_to_fit_always()
|
|
{
|
|
typedef typename Devector::value_type value_type;
|
|
Devector a;
|
|
a.reserve(100u);
|
|
|
|
a.push_back(value_type(1));
|
|
a.push_back(value_type(2));
|
|
a.push_back(value_type(3));
|
|
|
|
a.shrink_to_fit();
|
|
|
|
boost::container::vector<unsigned> expected;
|
|
expected.push_back(1u);
|
|
expected.push_back(2u);
|
|
expected.push_back(3u);
|
|
test_equal_range(a, expected);
|
|
|
|
std::size_t exp_capacity = 3u;
|
|
BOOST_TEST(a.capacity() == exp_capacity);
|
|
}
|
|
|
|
template <typename Devector>
|
|
void test_shrink_to_fit_never()
|
|
{
|
|
Devector a;
|
|
a.reserve(100);
|
|
|
|
a.push_back(1);
|
|
a.push_back(2);
|
|
a.push_back(3);
|
|
|
|
a.shrink_to_fit();
|
|
|
|
boost::container::vector<unsigned> expected;
|
|
expected.emplace_back(1);
|
|
expected.emplace_back(2);
|
|
expected.emplace_back(3);
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(a.capacity() == 100u);
|
|
}
|
|
|
|
void shrink_to_fit()
|
|
{
|
|
typedef devector<unsigned> devector_u_shr;
|
|
typedef devector<unsigned> small_devector_u_shr;
|
|
test_shrink_to_fit_always<devector_u_shr>();
|
|
test_shrink_to_fit_always<small_devector_u_shr>();
|
|
}
|
|
|
|
template <class Devector> void test_index_operator()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // non-const []
|
|
Devector a; get_range<Devector>(5, a);
|
|
|
|
BOOST_TEST(a[0] == 1);
|
|
BOOST_TEST(a[4] == 5);
|
|
BOOST_TEST(&a[3] == &a[0] + 3);
|
|
|
|
a[0] = T(100);
|
|
BOOST_TEST(a[0] == 100);
|
|
}
|
|
|
|
{ // const []
|
|
Devector b; get_range<Devector>(5, b);
|
|
const Devector &a = b;
|
|
|
|
BOOST_TEST(a[0] == 1);
|
|
BOOST_TEST(a[4] == 5);
|
|
BOOST_TEST(&a[3] == &a[0] + 3);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_at()
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // non-const at
|
|
Devector a; get_range<Devector>(3, a);
|
|
|
|
BOOST_TEST(a.at(0) == 1);
|
|
a.at(0) = T(100);
|
|
BOOST_TEST(a.at(0) == 100);
|
|
|
|
BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
|
|
}
|
|
|
|
{ // const at
|
|
Devector b; get_range<Devector>(3, b);
|
|
const Devector &a = b;
|
|
|
|
BOOST_TEST(a.at(0) == 1);
|
|
|
|
BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_front()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // non-const front
|
|
Devector a; get_range<Devector>(3, a);
|
|
BOOST_TEST(a.front() == 1);
|
|
a.front() = T(100);
|
|
BOOST_TEST(a.front() == 100);
|
|
}
|
|
|
|
{ // const front
|
|
Devector b; get_range<Devector>(3, b); const Devector &a = b;
|
|
BOOST_TEST(a.front() == 1);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_back()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{ // non-const back
|
|
Devector a; get_range<Devector>(3, a);
|
|
BOOST_TEST(a.back() == 3);
|
|
a.back() = T(100);
|
|
BOOST_TEST(a.back() == 100);
|
|
}
|
|
|
|
{ // const back
|
|
Devector b; get_range<Devector>(3, b); const Devector &a = b;
|
|
BOOST_TEST(a.back() == 3);
|
|
}
|
|
}
|
|
|
|
void test_data()
|
|
{
|
|
unsigned c_array[] = {1, 2, 3, 4};
|
|
|
|
{ // non-const data
|
|
devector<unsigned> a(c_array, c_array + 4);
|
|
BOOST_TEST(a.data() == &a.front());
|
|
|
|
BOOST_TEST(std::memcmp(c_array, a.data(), 4 * sizeof(unsigned)) == 0);
|
|
|
|
*(a.data()) = 100;
|
|
BOOST_TEST(a.front() == 100u);
|
|
}
|
|
|
|
{ // const data
|
|
const devector<unsigned> a(c_array, c_array + 4);
|
|
BOOST_TEST(a.data() == &a.front());
|
|
|
|
BOOST_TEST(std::memcmp(c_array, a.data(), 4 * sizeof(unsigned)) == 0);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_emplace_front(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
test_elem_throw::on_ctor_after(1);
|
|
BOOST_TEST_THROWS(b.emplace_front(404), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_emplace_front(dtl::false_)
|
|
{
|
|
}
|
|
|
|
template <class Devector> void test_emplace_front()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{
|
|
Devector a;
|
|
|
|
a.emplace_front(3);
|
|
a.emplace_front(2);
|
|
a.emplace_front(1);
|
|
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(3, expected);
|
|
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
test_emplace_front<Devector>
|
|
(dtl::bool_<!boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_push_front()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
{
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
|
|
std::reverse(expected.begin(), expected.end());
|
|
Devector a;
|
|
|
|
for (int i = 1; i <= 16; ++i)
|
|
{
|
|
T elem(i);
|
|
a.push_front(elem);
|
|
}
|
|
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
const T elem(404);
|
|
|
|
test_elem_throw::on_copy_after(1);
|
|
BOOST_TEST_THROWS(b.push_front(elem), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
}
|
|
|
|
// test when tmp is already inserted
|
|
{
|
|
Devector c; get_range<Devector>(4, c);
|
|
T tmp = *(c.begin() + 1);
|
|
c.push_front(tmp);
|
|
const int expected[] = {2, 1, 2, 3, 4};
|
|
test_equal_range(c, expected);
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_push_front_rvalue_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
test_elem_throw::on_move_after(1);
|
|
BOOST_TEST_THROWS(b.push_front(T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_push_front_rvalue_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_push_front_rvalue()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
|
|
Devector a;
|
|
|
|
for (int i = 16; i > 0; --i)
|
|
{
|
|
T elem(i);
|
|
a.push_front(boost::move(elem));
|
|
}
|
|
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
//test_push_front_rvalue_throwing<Devector>(dtl::bool_<! boost::is_nothrow_move_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_pop_front()
|
|
{
|
|
{
|
|
Devector a;
|
|
a.emplace_front(1);
|
|
a.pop_front();
|
|
BOOST_TEST(a.empty());
|
|
}
|
|
|
|
{
|
|
Devector b;
|
|
|
|
b.emplace_back(2);
|
|
b.pop_front();
|
|
BOOST_TEST(b.empty());
|
|
|
|
b.emplace_front(3);
|
|
b.pop_front();
|
|
BOOST_TEST(b.empty());
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(20, c);
|
|
for (int i = 0; i < 20; ++i)
|
|
{
|
|
BOOST_TEST(!c.empty());
|
|
c.pop_front();
|
|
}
|
|
BOOST_TEST(c.empty());
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_emplace_back_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
test_elem_throw::on_ctor_after(1);
|
|
BOOST_TEST_THROWS(b.emplace_back(404), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_emplace_back_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_emplace_back()
|
|
{
|
|
{
|
|
Devector a;
|
|
|
|
a.emplace_back(1);
|
|
a.emplace_back(2);
|
|
a.emplace_back(3);
|
|
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(3, expected);
|
|
|
|
test_equal_range<Devector>(a, expected);
|
|
}
|
|
//typedef typename Devector::value_type T;
|
|
//test_emplace_back_throwing<Devector>
|
|
//(dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_push_back_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
const T elem(404);
|
|
|
|
test_elem_throw::on_copy_after(1);
|
|
BOOST_TEST_THROWS(b.push_back(elem), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_push_back_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_push_back()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
{
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
|
|
Devector a;
|
|
|
|
for (int i = 1; i <= 16; ++i)
|
|
{
|
|
T elem(i);
|
|
|
|
a.push_back(elem);
|
|
}
|
|
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
//test_push_back_throwing<Devector>(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
|
|
// test when tmp is already inserted
|
|
{
|
|
Devector c; get_range<Devector>(4, c);
|
|
T tmp = *(c.begin() + 1);
|
|
c.push_back(tmp);
|
|
const int expected[] = {1, 2, 3, 4, 2};
|
|
test_equal_range(c, expected);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_push_back_rvalue_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator origi_begin = b.begin();
|
|
|
|
test_elem_throw::on_move_after(1);
|
|
BOOST_TEST_THROWS(b.push_back(T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
iterator new_begin = b.begin();
|
|
|
|
BOOST_TEST(origi_begin == new_begin);
|
|
BOOST_TEST(b.size() == 4u);
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_push_back_rvalue_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_push_back_rvalue()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
|
|
{
|
|
boost::container::vector<int> expected; get_range<boost::container::vector<int> >(16, expected);
|
|
Devector a;
|
|
|
|
for (int i = 1; i <= 16; ++i)
|
|
{
|
|
T elem(i);
|
|
a.push_back(boost::move(elem));
|
|
}
|
|
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
//test_push_back_rvalue_throwing<Devector>(dtl::bool_<! boost::is_nothrow_move_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_pop_back()
|
|
{
|
|
{
|
|
Devector a;
|
|
a.emplace_back(1);
|
|
a.pop_back();
|
|
BOOST_TEST(a.empty());
|
|
}
|
|
|
|
{
|
|
Devector b;
|
|
|
|
b.emplace_front(2);
|
|
b.pop_back();
|
|
BOOST_TEST(b.empty());
|
|
|
|
b.emplace_back(3);
|
|
b.pop_back();
|
|
BOOST_TEST(b.empty());
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(20, c);
|
|
for (int i = 0; i < 20; ++i)
|
|
{
|
|
BOOST_TEST(!c.empty());
|
|
c.pop_back();
|
|
}
|
|
BOOST_TEST(c.empty());
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_emplace_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector j; get_range<Devector>(4, j);
|
|
iterator origi_begin = j.begin();
|
|
|
|
test_elem_throw::on_ctor_after(1);
|
|
BOOST_TEST_THROWS(j.emplace(j.begin() + 2, 404), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
//const int expected[] = {1, 2, 3, 4};
|
|
//test_equal_range(j, expected);
|
|
BOOST_TEST(origi_begin == j.begin());
|
|
#endif
|
|
}
|
|
|
|
template <class Devector> void test_emplace_throwing(dtl::false_)
|
|
{}
|
|
|
|
|
|
template <class Devector> void test_emplace()
|
|
{
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
{
|
|
Devector a; get_range<Devector>(16, a);
|
|
typename Devector::iterator it = a.emplace(a.begin(), 123);
|
|
const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(16, b);
|
|
typename Devector::iterator it = b.emplace(b.end(), 123);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(16, c);
|
|
c.pop_front();
|
|
typename Devector::iterator it = c.emplace(c.begin(), 123);
|
|
const int expected [] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(16, d);
|
|
d.pop_back();
|
|
typename Devector::iterator it = d.emplace(d.end(), 123);
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(16, e);
|
|
typename Devector::iterator it = e.emplace(e.begin() + 5, 123);
|
|
const int expected [] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(16, f);
|
|
f.pop_front();
|
|
f.pop_back();
|
|
iterator valid = f.begin() + 1;
|
|
typename Devector::iterator it = f.emplace(f.begin() + 1, 123);
|
|
const int expected [] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(f, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 3);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(16, g);
|
|
g.pop_front();
|
|
g.pop_back();
|
|
iterator valid = g.end() - 2;
|
|
typename Devector::iterator it = g.emplace(g.end() - 1, 123);
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 14);
|
|
}
|
|
|
|
{
|
|
Devector h; get_range<Devector>(16, h);
|
|
h.pop_front();
|
|
h.pop_back();
|
|
//Inserting in the middle, leads to back insertion
|
|
iterator valid = h.begin() + 8;
|
|
typename Devector::iterator it = h.emplace(h.begin() + 7, 123);
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(h, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 9);
|
|
}
|
|
|
|
{
|
|
Devector i;
|
|
i.emplace(i.begin(), 1);
|
|
i.emplace(i.end(), 10);
|
|
for (int j = 2; j < 10; ++j)
|
|
{
|
|
i.emplace(i.begin() + (j-1), j);
|
|
}
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(i, expected);
|
|
}
|
|
|
|
//typedef typename Devector::value_type T;
|
|
//test_emplace_throwing<Devector>
|
|
//(dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_insert_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
T test_elem(123);
|
|
|
|
Devector j; get_range<Devector>(4, j);
|
|
iterator origi_begin = j.begin();
|
|
|
|
test_elem_throw::on_copy_after(1);
|
|
BOOST_TEST_THROWS(j.insert(j.begin() + 2, test_elem), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
//const int expected[] = {1, 2, 3, 4};
|
|
//test_equal_range(j, expected);
|
|
BOOST_TEST(origi_begin == j.begin());
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_insert_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_insert()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
T test_elem(123);
|
|
|
|
{
|
|
Devector a; get_range<Devector>(16, a);
|
|
typename Devector::iterator it = a.insert(a.begin(), test_elem);
|
|
const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(16, b);
|
|
typename Devector::iterator it = b.insert(b.end(), test_elem);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(16, c);
|
|
c.pop_front();
|
|
typename Devector::iterator it = c.insert(c.begin(), test_elem);
|
|
const int expected[] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(16, d);
|
|
d.pop_back();
|
|
typename Devector::iterator it = d.insert(d.end(), test_elem);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(16, e);
|
|
typename Devector::iterator it = e.insert(e.begin() + 5, test_elem);
|
|
const int expected[] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(16, f);
|
|
f.pop_front();
|
|
f.pop_back();
|
|
iterator valid = f.begin() + 1;
|
|
typename Devector::iterator it = f.insert(f.begin() + 1, test_elem);
|
|
const int expected[] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(f, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 3);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(16, g);
|
|
g.pop_front();
|
|
g.pop_back();
|
|
iterator valid = g.end() - 2;
|
|
typename Devector::iterator it = g.insert(g.end() - 1, test_elem);
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 14);
|
|
}
|
|
|
|
{
|
|
Devector h; get_range<Devector>(16, h);
|
|
h.pop_front();
|
|
h.pop_back();
|
|
//Inserting in the middle, leads to back insertion
|
|
iterator valid = h.begin() + 8;
|
|
typename Devector::iterator it = h.insert(h.begin() + 7, test_elem);
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(h, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 9);
|
|
}
|
|
|
|
{
|
|
Devector i;
|
|
i.insert(i.begin(), T(1));
|
|
i.insert(i.end(), T(10));
|
|
for (int j = 2; j < 10; ++j)
|
|
{
|
|
i.insert(i.begin() + (j-1), T(j));
|
|
}
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(i, expected);
|
|
}
|
|
|
|
//test_insert_throwing<Devector>
|
|
//(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
|
|
// test when tmp is already inserted and there's free capacity
|
|
{
|
|
Devector c; get_range<Devector>(6, c);
|
|
c.pop_back();
|
|
c.pop_back();
|
|
T tmp = *(c.begin() + 2);
|
|
c.insert(c.begin() + 1, tmp);
|
|
const int expected[] = {1, 3, 2, 3, 4};
|
|
test_equal_range(c, expected);
|
|
}
|
|
|
|
// test when tmp is already inserted and maybe there's no free capacity
|
|
{
|
|
Devector c; get_range<Devector>(6, c);
|
|
const T tmp = *(c.begin() + 2);
|
|
c.insert(c.begin() + 1, tmp);
|
|
const int expected[] = {1, 3, 2, 3, 4, 5, 6};
|
|
test_equal_range(c, expected);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_insert_rvalue_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
Devector j; get_range<Devector>(4, j);
|
|
iterator origi_begin = j.begin();
|
|
|
|
test_elem_throw::on_ctor_after(1);
|
|
BOOST_TEST_THROWS(j.insert(j.begin() + 2, T(404)), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
|
|
const int expected[] = {1, 2, 3, 4};
|
|
test_equal_range(j, expected);
|
|
BOOST_TEST(origi_begin == j.begin());
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_insert_rvalue_throwing(dtl::false_)
|
|
{}
|
|
|
|
|
|
template <class Devector> void test_insert_rvalue()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
{
|
|
Devector a; get_range<Devector>(16, a);
|
|
typename Devector::iterator it = a.insert(a.begin(), T(123));
|
|
const int expected[] = {123, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(16, b);
|
|
typename Devector::iterator it = b.insert(b.end(), T(123));
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 123};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(16, c);
|
|
c.pop_front();
|
|
typename Devector::iterator it = c.insert(c.begin(), T(123));
|
|
const int expected[] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(16, d);
|
|
d.pop_back();
|
|
typename Devector::iterator it = d.insert(d.end(), T(123));
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 123};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(16, e);
|
|
typename Devector::iterator it = e.insert(e.begin() + 5, T(123));
|
|
const int expected[] = {1, 2, 3, 4, 5, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(*it == 123);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(16, f);
|
|
f.pop_front();
|
|
f.pop_back();
|
|
iterator valid = f.begin() + 1;
|
|
typename Devector::iterator it = f.insert(f.begin() + 1, T(123));
|
|
const int expected[] = {2, 123, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(f, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 3);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(16, g);
|
|
g.pop_front();
|
|
g.pop_back();
|
|
iterator valid = g.end() - 2;
|
|
typename Devector::iterator it = g.insert(g.end() - 1, T(123));
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 123, 15};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 14);
|
|
}
|
|
|
|
{
|
|
Devector h; get_range<Devector>(16, h);
|
|
h.pop_front();
|
|
h.pop_back();
|
|
//Inserting in the middle, leads to back insertion
|
|
iterator valid = h.begin() + 8;
|
|
typename Devector::iterator it = h.insert(h.begin() + 7, T(123));
|
|
const int expected[] = {2, 3, 4, 5, 6, 7, 8, 123, 9, 10, 11, 12, 13, 14, 15};
|
|
test_equal_range(h, expected);
|
|
BOOST_TEST(*it == 123);
|
|
BOOST_TEST(*valid == 9);
|
|
}
|
|
|
|
{
|
|
Devector i;
|
|
i.insert(i.begin(), T(1));
|
|
i.insert(i.end(), T(10));
|
|
for (int j = 2; j < 10; ++j)
|
|
{
|
|
i.insert(i.begin() + (j-1), T(j));
|
|
}
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(i, expected);
|
|
}
|
|
|
|
//test_insert_rvalue_throwing<Devector>
|
|
//(dtl::bool_<! boost::move_detail::is_nothrow_default_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_insert_n_throwing(dtl::true_)
|
|
{
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
typedef typename Devector::value_type T;
|
|
// insert at begin
|
|
{
|
|
Devector j; get_range<Devector>(4, j);
|
|
|
|
const T x(404);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(j.insert(j.begin(), 4, x), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
|
|
// insert at end
|
|
{
|
|
Devector k; get_range<Devector>(4, k);
|
|
|
|
const T x(404);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(k.insert(k.end(), 4, x), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_insert_n_throwing(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector> void test_insert_n()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
{
|
|
Devector a;
|
|
const T x(123);
|
|
iterator ret = a.insert(a.end(), 5, x);
|
|
const int expected[] = {123, 123, 123, 123, 123};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
const T x(9);
|
|
iterator ret = b.insert(b.begin(), 3, x);
|
|
const int expected[] = {9, 9, 9, 1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.begin());
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(8, c);
|
|
const T x(9);
|
|
iterator ret = c.insert(c.end(), 3, x);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(ret == c.begin() + 8);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.pop_front();
|
|
d.pop_front();
|
|
d.pop_front();
|
|
|
|
const T x(9);
|
|
iterator origi_end = d.end();
|
|
iterator ret = d.insert(d.begin(), 3, x);
|
|
|
|
const int expected[] = {9, 9, 9, 4, 5, 6, 7, 8};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(origi_end == d.end());
|
|
BOOST_TEST(ret == d.begin());
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(8, e);
|
|
|
|
e.pop_back();
|
|
e.pop_back();
|
|
e.pop_back();
|
|
|
|
const T x(9);
|
|
iterator origi_begin = e.begin();
|
|
iterator ret = e.insert(e.end(), 3, x);
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 9, 9, 9};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(origi_begin == e.begin());
|
|
BOOST_TEST(ret == e.begin() + 5);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
f.reset_alloc_stats();
|
|
|
|
f.pop_front();
|
|
f.pop_front();
|
|
f.pop_back();
|
|
f.pop_back();
|
|
|
|
const T x(9);
|
|
iterator ret = f.insert(f.begin() + 2, 4, x);
|
|
|
|
const int expected[] = {3, 4, 9, 9, 9, 9, 5, 6};
|
|
test_equal_range(f, expected);
|
|
BOOST_TEST(f.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == f.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
g.reset_alloc_stats();
|
|
|
|
g.pop_front();
|
|
g.pop_front();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
|
|
const T x(9);
|
|
iterator ret = g.insert(g.begin() + 2, 5, x);
|
|
|
|
const int expected[] = {3, 4, 9, 9, 9, 9, 9, 5};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(g.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
|
|
const T x(9);
|
|
iterator ret = g.insert(g.begin() + 2, 5, x);
|
|
|
|
const int expected[] = {1, 2, 9, 9, 9, 9, 9, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{ // n == 0
|
|
Devector h; get_range<Devector>(8, h);
|
|
h.reset_alloc_stats();
|
|
|
|
const T x(9);
|
|
|
|
iterator ret = h.insert(h.begin(), 0, x);
|
|
BOOST_TEST(ret == h.begin());
|
|
|
|
ret = h.insert(h.begin() + 4, 0, x);
|
|
BOOST_TEST(ret == h.begin() + 4);
|
|
|
|
ret = h.insert(h.end(), 0, x);
|
|
BOOST_TEST(ret == h.end());
|
|
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(h, expected);
|
|
BOOST_TEST(h.get_alloc_count() == 0u);
|
|
}
|
|
|
|
{ // test insert already inserted
|
|
Devector i; get_range<Devector>(8, i);
|
|
i.reset_alloc_stats();
|
|
|
|
i.pop_front();
|
|
i.pop_front();
|
|
|
|
iterator ret = i.insert(i.end() - 1, 2, typename Devector::value_type(*i.begin()));
|
|
|
|
const int expected[] = {3, 4, 5, 6, 7, 3, 3, 8};
|
|
test_equal_range(i, expected);
|
|
BOOST_TEST(i.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == i.begin() + 5);
|
|
}
|
|
|
|
//test_insert_n_throwing<Devector>
|
|
//(dtl::bool_<! boost::move_detail::is_nothrow_copy_constructible<T>::value>());
|
|
}
|
|
|
|
template <class Devector> void test_insert_input_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
devector<T> x;
|
|
x.emplace_back(9);
|
|
x.emplace_back(9);
|
|
x.emplace_back(9);
|
|
x.emplace_back(9);
|
|
x.emplace_back(9);
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 5);
|
|
|
|
Devector a;
|
|
iterator ret = a.insert(a.end(), input_begin, input_end);
|
|
const int expected[] = {9, 9, 9, 9, 9};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 3);
|
|
|
|
Devector b; get_range<Devector>(8, b);
|
|
iterator ret = b.insert(b.begin(), input_begin, input_end);
|
|
const int expected[] = {9, 9, 9, 1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.begin());
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 3);
|
|
|
|
Devector c; get_range<Devector>(8, c);
|
|
iterator ret = c.insert(c.end(), input_begin, input_end);
|
|
const int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(ret == c.begin() + 8);
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 3);
|
|
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.pop_front();
|
|
d.pop_front();
|
|
d.pop_front();
|
|
|
|
iterator ret = d.insert(d.begin(), input_begin, input_end);
|
|
const int expected[] = {9, 9, 9, 4, 5, 6, 7, 8};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(ret == d.begin());
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 3);
|
|
|
|
Devector e; get_range<Devector>(8, e);
|
|
|
|
e.pop_back();
|
|
e.pop_back();
|
|
e.pop_back();
|
|
|
|
iterator origi_begin = e.begin();
|
|
iterator ret = e.insert(e.end(), input_begin, input_end);
|
|
const int expected[] = {1, 2, 3, 4, 5, 9, 9, 9};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(origi_begin == e.begin());
|
|
BOOST_TEST(ret == e.begin() + 5);
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 4);
|
|
|
|
Devector f; get_range<Devector>(8, f);
|
|
f.reset_alloc_stats();
|
|
|
|
f.pop_front();
|
|
f.pop_front();
|
|
f.pop_back();
|
|
f.pop_back();
|
|
|
|
iterator ret = f.insert(f.begin() + 2, input_begin, input_end);
|
|
|
|
const int expected[] = {3, 4, 9, 9, 9, 9, 5, 6};
|
|
test_equal_range(f, expected);
|
|
BOOST_TEST(ret == f.begin() + 2);
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 5);
|
|
|
|
Devector g; get_range<Devector>(8, g);
|
|
g.reset_alloc_stats();
|
|
|
|
g.pop_front();
|
|
g.pop_front();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
|
|
iterator ret = g.insert(g.begin() + 2, input_begin, input_end);
|
|
|
|
const int expected [] = {3, 4, 9, 9, 9, 9, 9, 5};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 5);
|
|
|
|
Devector g; get_range<Devector>(8, g);
|
|
|
|
iterator ret = g.insert(g.begin() + 2, input_begin, input_end);
|
|
|
|
const int expected [] = {1, 2, 9, 9, 9, 9, 9, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(g, expected);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{ // n == 0
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
|
|
Devector h; get_range<Devector>(8, h);
|
|
h.reset_alloc_stats();
|
|
|
|
iterator ret = h.insert(h.begin(), input_begin, input_begin);
|
|
BOOST_TEST(ret == h.begin());
|
|
|
|
ret = h.insert(h.begin() + 4, input_begin, input_begin);
|
|
BOOST_TEST(ret == h.begin() + 4);
|
|
|
|
ret = h.insert(h.end(), input_begin, input_begin);
|
|
BOOST_TEST(ret == h.end());
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(h, expected);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// insert at begin
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 4);
|
|
|
|
Devector j; get_range<Devector>(4, j);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(j.insert(j.begin(), input_begin, input_end), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
|
|
// insert at end
|
|
{
|
|
devector<T> input = x;
|
|
|
|
input_iterator<Devector> input_begin = make_input_iterator(input, input.begin());
|
|
input_iterator<Devector> input_end = make_input_iterator(input, input.begin() + 4);
|
|
|
|
Devector k; get_range<Devector>(4, k);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(k.insert(k.end(), input_begin, input_end), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_insert_range()
|
|
{
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
typedef boost::container::vector<T> Vector;
|
|
|
|
Vector x;
|
|
x.emplace_back(9);
|
|
x.emplace_back(10);
|
|
x.emplace_back(11);
|
|
x.emplace_back(12);
|
|
x.emplace_back(13);
|
|
|
|
typename Vector::iterator xb = x.begin();
|
|
|
|
//Insert from empty
|
|
{
|
|
Devector a;
|
|
iterator ret = a.insert(a.end(), xb, xb+5);
|
|
const int expected [] = {9, 10, 11, 12, 13};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
{
|
|
Devector a;
|
|
iterator ret = a.insert(a.begin(), xb, xb + 5);
|
|
const int expected[] = { 9, 10, 11, 12, 13 };
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
//Insert at both ends
|
|
{
|
|
Devector c; get_range<Devector>(8, c);
|
|
iterator ret = c.insert(c.end(), xb, xb + 3);
|
|
const int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(ret == c.begin() + 8);
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
iterator ret = b.insert(b.begin(), xb, xb+3);
|
|
const int expected [] = {9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.begin());
|
|
}
|
|
|
|
//Insert without full data movement
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin(), b.begin() + 3);
|
|
iterator old_end = b.end();
|
|
iterator ret = b.insert(b.begin()+1u, xb, xb + 3);
|
|
const int expected[] = { 4, 9, 10, 11, 5, 6, 7, 8 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == (b.begin() + 1u));
|
|
BOOST_TEST(old_end == b.end());
|
|
}
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin()+5, b.end());
|
|
iterator old_beg = b.begin();
|
|
iterator ret = b.insert(b.end() - 1u, xb, xb + 3);
|
|
const int expected[] = { 1, 2, 3, 4, 9, 10, 11, 5 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == (b.begin() + 4u));
|
|
BOOST_TEST(old_beg == b.begin());
|
|
}
|
|
|
|
//Full data movement
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin(), b.begin() + 4);
|
|
iterator ret = b.insert(b.end(), xb, xb + 3);
|
|
const int expected[] = { 5, 6, 7, 8, 9, 10, 11 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == (b.begin()+4));
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin(), b.begin() + 3);
|
|
b.pop_back();
|
|
iterator ret = b.insert(b.end() - 1, xb, xb + 3);
|
|
const int expected[] = { 4, 5, 6, 9, 10, 11, 7 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == (b.begin()+3));
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin()+4, b.end());
|
|
iterator ret = b.insert(b.begin(), xb, xb + 3);
|
|
const int expected[] = { 9, 10, 11, 1, 2, 3, 4 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.begin());
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
b.erase(b.begin() + 5, b.end());
|
|
b.pop_front();
|
|
iterator ret = b.insert(b.begin()+1, xb, xb + 3);
|
|
const int expected[] = { 2, 9, 10, 11, 3, 4, 5 };
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == (b.begin()+1));
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.pop_front();
|
|
d.pop_front();
|
|
d.pop_front();
|
|
|
|
iterator origi_end = d.end();
|
|
iterator ret = d.insert(d.begin(), xb, xb+3);
|
|
|
|
const int expected [] = {9, 10, 11, 4, 5, 6, 7, 8};
|
|
test_equal_range(d, expected);
|
|
|
|
BOOST_TEST(origi_end == d.end());
|
|
BOOST_TEST(ret == d.begin());
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(8, e);
|
|
|
|
e.pop_back();
|
|
e.pop_back();
|
|
e.pop_back();
|
|
|
|
iterator origi_begin = e.begin();
|
|
iterator ret = e.insert(e.end(), xb, xb+3);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 9, 10, 11};
|
|
test_equal_range(e, expected);
|
|
|
|
BOOST_TEST(origi_begin == e.begin());
|
|
BOOST_TEST(ret == e.begin() + 5);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
f.reset_alloc_stats();
|
|
|
|
f.pop_front();
|
|
f.pop_front();
|
|
f.pop_back();
|
|
f.pop_back();
|
|
|
|
iterator ret = f.insert(f.begin() + 2, xb, xb+4);
|
|
|
|
const int expected [] = {3, 4, 9, 10, 11, 12, 5, 6};
|
|
test_equal_range(f, expected);
|
|
|
|
BOOST_TEST(f.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == f.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
g.reset_alloc_stats();
|
|
|
|
g.pop_front();
|
|
g.pop_front();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
|
|
iterator ret = g.insert(g.begin() + 2, xb, xb+5);
|
|
|
|
const int expected [] = {3, 4, 9, 10, 11, 12, 13, 5};
|
|
test_equal_range(g, expected);
|
|
|
|
BOOST_TEST(g.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
|
|
iterator ret = g.insert(g.begin() + 2, xb, xb+5);
|
|
|
|
const int expected [] = {1, 2, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(g, expected);
|
|
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{ // n == 0
|
|
Devector h; get_range<Devector>(8, h);
|
|
h.reset_alloc_stats();
|
|
|
|
iterator ret = h.insert(h.begin(), xb, xb);
|
|
BOOST_TEST(ret == h.begin());
|
|
|
|
ret = h.insert(h.begin() + 4, xb, xb);
|
|
BOOST_TEST(ret == h.begin() + 4);
|
|
|
|
ret = h.insert(h.end(), xb, xb);
|
|
BOOST_TEST(ret == h.end());
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8};
|
|
test_equal_range(h, expected);
|
|
|
|
BOOST_TEST(h.get_alloc_count() == 0u);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
if (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// insert at begin
|
|
{
|
|
Devector j; get_range<Devector>(4, j);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(j.insert(j.begin(), xb, xb+4), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
|
|
// insert at end
|
|
{
|
|
Devector k; get_range<Devector>(4, k);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(k.insert(k.end(), xb, xb+4), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
}
|
|
|
|
template <class Devector> void test_insert_init_list()
|
|
{
|
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
typedef typename Devector::value_type T;
|
|
typedef typename Devector::iterator iterator;
|
|
|
|
{
|
|
Devector a;
|
|
iterator ret = a.insert(a.end(), {T(123), T(124), T(125), T(126), T(127)});
|
|
test_equal_range(a, {123, 124, 125, 126, 127});
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
iterator ret = b.insert(b.begin(), {T(9), T(10), T(11)});
|
|
test_equal_range(b, {9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8});
|
|
BOOST_TEST(ret == b.begin());
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(8, c);
|
|
iterator ret = c.insert(c.end(), {T(9), T(10), T(11)});
|
|
test_equal_range(c, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
|
|
BOOST_TEST(ret == c.begin() + 8);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(8, d);
|
|
|
|
d.pop_front();
|
|
d.pop_front();
|
|
d.pop_front();
|
|
|
|
iterator origi_end = d.end();
|
|
iterator ret = d.insert(d.begin(), {T(9), T(10), T(11)});
|
|
|
|
test_equal_range(d, {9, 10, 11, 4, 5, 6, 7, 8});
|
|
BOOST_TEST(origi_end == d.end());
|
|
BOOST_TEST(ret == d.begin());
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(8, e);
|
|
|
|
e.pop_back();
|
|
e.pop_back();
|
|
e.pop_back();
|
|
|
|
iterator origi_begin = e.begin();
|
|
iterator ret = e.insert(e.end(), {T(9), T(10), T(11)});
|
|
|
|
test_equal_range(e, {1, 2, 3, 4, 5, 9, 10, 11});
|
|
BOOST_TEST(origi_begin == e.begin());
|
|
BOOST_TEST(ret == e.begin() + 5);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
f.reset_alloc_stats();
|
|
|
|
f.pop_front();
|
|
f.pop_front();
|
|
f.pop_back();
|
|
f.pop_back();
|
|
|
|
iterator ret = f.insert(f.begin() + 2, {T(9), T(10), T(11), T(12)});
|
|
|
|
test_equal_range(f, {3, 4, 9, 10, 11, 12, 5, 6});
|
|
BOOST_TEST(f.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == f.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
g.reset_alloc_stats();
|
|
|
|
g.pop_front();
|
|
g.pop_front();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
g.pop_back();
|
|
|
|
iterator ret = g.insert(g.begin() + 2, {T(9), T(10), T(11), T(12), T(13)});
|
|
|
|
test_equal_range(g, {3, 4, 9, 10, 11, 12, 13, 5});
|
|
BOOST_TEST(g.get_alloc_count() == 0u);
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
{
|
|
Devector g; get_range<Devector>(8, g);
|
|
|
|
iterator ret = g.insert(g.begin() + 2, {T(9), T(10), T(11), T(12), T(13)});
|
|
|
|
test_equal_range(g, {1, 2, 9, 10, 11, 12, 13, 3, 4, 5, 6, 7, 8});
|
|
BOOST_TEST(ret == g.begin() + 2);
|
|
}
|
|
|
|
#ifndef BOOST_NO_EXCEPTIONS
|
|
BOOST_IF_CONSTEXPR (! boost::move_detail::is_nothrow_copy_constructible<T>::value)
|
|
{
|
|
// insert at begin
|
|
{
|
|
Devector j; get_range<Devector>(4, j);
|
|
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(j.insert(j.begin(), {T(9), T(9), T(9), T(9), T(9)}), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
|
|
// insert at end
|
|
{
|
|
Devector k; get_range<Devector>(4, k);
|
|
test_elem_throw::on_copy_after(3);
|
|
BOOST_TEST_THROWS(k.insert(k.end(), {T(9), T(9), T(9), T(9), T(9)}), test_exception);
|
|
test_elem_throw::do_not_throw();
|
|
}
|
|
}
|
|
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
|
#endif // #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
|
}
|
|
|
|
template <class Devector> void test_erase()
|
|
{
|
|
typedef typename Devector::iterator iterator;
|
|
{
|
|
Devector a; get_range<Devector>(4, a);
|
|
iterator ret = a.erase(a.begin());
|
|
const int expected[] = {2, 3, 4};
|
|
test_equal_range(a, expected);
|
|
BOOST_TEST(ret == a.begin());
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(4, b);
|
|
iterator ret = b.erase(b.end() - 1);
|
|
const int expected[] = {1, 2, 3};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.end());
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(6, c);
|
|
iterator ret = c.erase(c.begin() + 2);
|
|
const int expected [] = {1, 2, 4, 5, 6};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(ret == c.begin() + 2);
|
|
BOOST_TEST(c.front_free_capacity() > 0u);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(6, d);
|
|
iterator ret = d.erase(d.begin() + 4);
|
|
const int expected [] = {1, 2, 3, 4, 6};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(ret == d.begin() + 4);
|
|
BOOST_TEST(d.back_free_capacity() > 0u);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_erase_range()
|
|
{
|
|
typedef typename Devector::iterator iterator;
|
|
{
|
|
Devector a; get_range<Devector>(4, a);
|
|
a.erase(a.end(), a.end());
|
|
a.erase(a.begin(), a.begin());
|
|
}
|
|
|
|
{
|
|
Devector b; get_range<Devector>(8, b);
|
|
iterator ret = b.erase(b.begin(), b.begin() + 2);
|
|
const int expected [] = {3, 4, 5, 6, 7, 8};
|
|
test_equal_range(b, expected);
|
|
BOOST_TEST(ret == b.begin());
|
|
BOOST_TEST(b.front_free_capacity() > 0u);
|
|
}
|
|
|
|
{
|
|
Devector c; get_range<Devector>(8, c);
|
|
iterator ret = c.erase(c.begin() + 1, c.begin() + 3);
|
|
const int expected [] = {1, 4, 5, 6, 7, 8};
|
|
test_equal_range(c, expected);
|
|
BOOST_TEST(ret == c.begin() + 1);
|
|
BOOST_TEST(c.front_free_capacity() > 0u);
|
|
}
|
|
|
|
{
|
|
Devector d; get_range<Devector>(8, d);
|
|
iterator ret = d.erase(d.end() - 2, d.end());
|
|
const int expected [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(d, expected);
|
|
BOOST_TEST(ret == d.end());
|
|
BOOST_TEST(d.back_free_capacity() > 0u);
|
|
}
|
|
|
|
{
|
|
Devector e; get_range<Devector>(8, e);
|
|
iterator ret = e.erase(e.end() - 3, e.end() - 1);
|
|
const int expected [] = {1, 2, 3, 4, 5, 8};
|
|
test_equal_range(e, expected);
|
|
BOOST_TEST(ret == e.end() - 1);
|
|
BOOST_TEST(e.back_free_capacity() > 0u);
|
|
}
|
|
|
|
{
|
|
Devector f; get_range<Devector>(8, f);
|
|
iterator ret = f.erase(f.begin(), f.end());
|
|
test_equal_range(f);
|
|
BOOST_TEST(ret == f.end());
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_swap()
|
|
{
|
|
using std::swap; // test if ADL works
|
|
|
|
// empty-empty
|
|
{
|
|
Devector a;
|
|
Devector b;
|
|
|
|
swap(a, b);
|
|
|
|
BOOST_TEST(a.empty());
|
|
BOOST_TEST(b.empty());
|
|
}
|
|
|
|
// empty-not empty
|
|
{
|
|
Devector a;
|
|
Devector b; get_range<Devector>(4, b);
|
|
|
|
swap(a, b);
|
|
|
|
const int expected [] = {1, 2, 3, 4};
|
|
{
|
|
BOOST_TEST(b.empty());
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
swap(a, b);
|
|
{
|
|
BOOST_TEST(a.empty());
|
|
test_equal_range(b, expected);
|
|
}
|
|
}
|
|
|
|
// small-small / big-big
|
|
{
|
|
Devector a; get_range<Devector>(1, 5, 5, 7, a);
|
|
Devector b; get_range<Devector>(13, 15, 15, 19, b);
|
|
|
|
swap(a, b);
|
|
|
|
const int expected [] = {13, 14, 15, 16, 17, 18};
|
|
test_equal_range(a, expected);
|
|
const int expected2 [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(b, expected2);
|
|
|
|
swap(a, b);
|
|
|
|
const int expected3 [] = {13, 14, 15, 16, 17, 18};
|
|
test_equal_range(b, expected3);
|
|
const int expected4 [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(a, expected4);
|
|
}
|
|
|
|
// big-small + small-big
|
|
{
|
|
Devector a; get_range<Devector>(10, a);
|
|
Devector b; get_range<Devector>(9, 11, 11, 17, b);
|
|
|
|
swap(a, b);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(b, expected);
|
|
const int expected2 [] = {9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(a, expected2);
|
|
|
|
swap(a, b);
|
|
|
|
const int expected3 [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(a, expected3);
|
|
const int expected4 [] = {9, 10, 11, 12, 13, 14, 15, 16};
|
|
test_equal_range(b, expected4);
|
|
}
|
|
|
|
// self swap
|
|
{
|
|
Devector a; get_range<Devector>(10, a);
|
|
|
|
swap(a, a);
|
|
|
|
const int expected [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
test_equal_range(a, expected);
|
|
}
|
|
|
|
// no overlap
|
|
{
|
|
Devector a; get_range<Devector>(1, 9, 0, 0, a);
|
|
Devector b; get_range<Devector>(0, 0, 11, 17, b);
|
|
|
|
a.pop_back();
|
|
a.pop_back();
|
|
|
|
b.pop_front();
|
|
b.pop_front();
|
|
|
|
swap(a, b);
|
|
|
|
const int expected [] = {13, 14, 15, 16};
|
|
test_equal_range(a, expected);
|
|
const int expected2 [] = {1, 2, 3, 4, 5, 6};
|
|
test_equal_range(b, expected2);
|
|
}
|
|
|
|
// big-big does not copy or move
|
|
{
|
|
Devector a; get_range<Devector>(32, a);
|
|
Devector b; get_range<Devector>(32, b);
|
|
boost::container::vector<int> c; get_range<boost::container::vector<int> >(32, c);
|
|
|
|
test_elem_throw::on_copy_after(1);
|
|
test_elem_throw::on_move_after(1);
|
|
|
|
swap(a, b);
|
|
|
|
test_elem_throw::do_not_throw();
|
|
|
|
test_equal_range(a, c);
|
|
test_equal_range(b, c);
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_clear()
|
|
{
|
|
{
|
|
Devector a;
|
|
a.clear();
|
|
BOOST_TEST(a.empty());
|
|
}
|
|
|
|
{
|
|
Devector a; get_range<Devector>(8, a);
|
|
typename Devector::size_type cp = a.capacity();
|
|
a.clear();
|
|
BOOST_TEST(a.empty());
|
|
BOOST_TEST(cp == a.capacity());
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_op_eq()
|
|
{
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(a == b);
|
|
}
|
|
|
|
{ // diff size
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(9, b);
|
|
|
|
BOOST_TEST(!(a == b));
|
|
}
|
|
|
|
{ // diff content
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(2,6,6,10, b);
|
|
|
|
BOOST_TEST(!(a == b));
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_op_lt()
|
|
{
|
|
{ // little than
|
|
Devector a; get_range<Devector>(7, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST((a < b));
|
|
}
|
|
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(!(a < b));
|
|
}
|
|
|
|
{ // greater than
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(7, b);
|
|
|
|
BOOST_TEST(!(a < b));
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_op_ne()
|
|
{
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(!(a != b));
|
|
}
|
|
|
|
{ // diff size
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(9, b);
|
|
|
|
BOOST_TEST((a != b));
|
|
}
|
|
|
|
{ // diff content
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(2,6,6,10, b);
|
|
|
|
BOOST_TEST((a != b));
|
|
}
|
|
}
|
|
|
|
|
|
template <class Devector> void test_op_gt()
|
|
{
|
|
{ // little than
|
|
Devector a; get_range<Devector>(7, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(!(a > b));
|
|
}
|
|
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(!(a > b));
|
|
}
|
|
|
|
{ // greater than
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(7, b);
|
|
|
|
BOOST_TEST((a > b));
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_op_ge()
|
|
{
|
|
{ // little than
|
|
Devector a; get_range<Devector>(7, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST(!(a >= b));
|
|
}
|
|
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST((a >= b));
|
|
}
|
|
|
|
{ // greater than
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(7, b);
|
|
|
|
BOOST_TEST((a >= b));
|
|
}
|
|
}
|
|
|
|
template <class Devector> void test_op_le()
|
|
{
|
|
{ // little than
|
|
Devector a; get_range<Devector>(7, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST((a <= b));
|
|
}
|
|
|
|
{ // equal
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(8, b);
|
|
|
|
BOOST_TEST((a <= b));
|
|
}
|
|
|
|
{ // greater than
|
|
Devector a; get_range<Devector>(8, a);
|
|
Devector b; get_range<Devector>(7, b);
|
|
|
|
BOOST_TEST(!(a <= b));
|
|
}
|
|
}
|
|
|
|
|
|
template <class Devector>
|
|
void test_devector_default_constructible(dtl::true_)
|
|
{
|
|
test_constructor_n<Devector>();
|
|
test_resize_front<Devector>();
|
|
test_resize_back<Devector>();
|
|
}
|
|
|
|
template <class Devector>
|
|
void test_devector_default_constructible(dtl::false_)
|
|
{}
|
|
|
|
template <class Devector>
|
|
void test_devector_copy_constructible(dtl::false_)
|
|
{}
|
|
|
|
|
|
template <class Devector>
|
|
void test_devector_copy_constructible(dtl::true_)
|
|
{
|
|
test_constructor_n_copy<Devector>();
|
|
test_constructor_input_range<Devector>();
|
|
test_constructor_forward_range<Devector>();
|
|
test_constructor_pointer_range<Devector>();
|
|
test_copy_constructor<Devector>();
|
|
test_assignment<Devector>();
|
|
test_assign_input_range<Devector>();
|
|
test_assign_pointer_range<Devector>();
|
|
test_assign_n<Devector>();
|
|
test_resize_front_copy<Devector>();
|
|
test_push_back<Devector>();
|
|
//test_unsafe_push_back<Devector>();
|
|
test_push_front<Devector>();
|
|
//test_unsafe_push_front<Devector>();
|
|
test_resize_back_copy<Devector>();
|
|
test_insert<Devector>();
|
|
test_insert_n<Devector>();
|
|
test_insert_input_range<Devector>();
|
|
test_insert_range<Devector>();
|
|
test_insert_init_list<Devector>();
|
|
}
|
|
|
|
template <class Devector>
|
|
void test_devector()
|
|
{
|
|
test_devector_default_constructible<Devector>(dtl::bool_<boost::is_default_constructible<typename Devector::value_type>::value>());
|
|
test_devector_copy_constructible<Devector>(dtl::bool_<boost::move_detail::is_copy_constructible<typename Devector::value_type>::value>());
|
|
|
|
test_constructor_default<Devector>();
|
|
test_constructor_allocator<Devector>();
|
|
|
|
test_constructor_reserve_only<Devector>();
|
|
test_constructor_reserve_only_front_back<Devector>();
|
|
//test_constructor_unsafe_uninitialized<Devector>();
|
|
|
|
test_move_constructor<Devector>();
|
|
test_destructor<Devector>();
|
|
|
|
test_move_assignment<Devector>();
|
|
test_get_allocator<Devector>();
|
|
test_begin_end<Devector>();
|
|
test_empty<Devector>();
|
|
test_size<Devector>();
|
|
test_capacity<Devector>();
|
|
|
|
//test_unsafe_uninitialized_resize_front<Devector>();
|
|
//test_unsafe_uninitialized_resize_back<Devector>();
|
|
test_reserve_front<Devector>();
|
|
test_reserve_back<Devector>();
|
|
test_index_operator<Devector>();
|
|
test_at<Devector>();
|
|
test_front<Devector>();
|
|
test_back<Devector>();
|
|
test_emplace_front<Devector>();
|
|
test_push_front_rvalue<Devector>();
|
|
|
|
//test_unsafe_push_front_rvalue<Devector>();
|
|
test_pop_front<Devector>();
|
|
test_emplace_back<Devector>();
|
|
test_push_back_rvalue<Devector>();
|
|
|
|
//test_unsafe_push_back_rvalue<Devector>();
|
|
test_pop_back<Devector>();
|
|
test_emplace<Devector>();
|
|
test_insert_rvalue<Devector>();
|
|
|
|
test_erase<Devector>();
|
|
test_erase_range<Devector>();
|
|
test_swap<Devector>();
|
|
test_clear<Devector>();
|
|
test_op_eq<Devector>();
|
|
test_op_lt<Devector>();
|
|
test_op_ne<Devector>();
|
|
test_op_gt<Devector>();
|
|
test_op_ge<Devector>();
|
|
test_op_le<Devector>();
|
|
}
|
|
|
|
class recursive_devector
|
|
{
|
|
public:
|
|
recursive_devector(const recursive_devector &x)
|
|
: devector_(x.devector_)
|
|
{}
|
|
|
|
recursive_devector & operator=(const recursive_devector &x)
|
|
{ this->devector_ = x.devector_; return *this; }
|
|
|
|
int id_;
|
|
devector<recursive_devector> devector_;
|
|
devector<recursive_devector>::iterator it_;
|
|
devector<recursive_devector>::const_iterator cit_;
|
|
devector<recursive_devector>::reverse_iterator rit_;
|
|
devector<recursive_devector>::const_reverse_iterator crit_;
|
|
};
|
|
|
|
void test_recursive_devector()//Test for recursive types
|
|
{
|
|
devector<recursive_devector> rdv;
|
|
BOOST_TEST(rdv.empty());
|
|
BOOST_TEST(rdv.get_alloc_count() == 0u);
|
|
BOOST_TEST(rdv.capacity() == 0u);
|
|
}
|
|
|
|
template<class VoidAllocator>
|
|
struct GetAllocatorCont
|
|
{
|
|
template<class ValueType>
|
|
struct apply
|
|
{
|
|
typedef vector< ValueType
|
|
, typename allocator_traits<VoidAllocator>
|
|
::template portable_rebind_alloc<ValueType>::type
|
|
> type;
|
|
};
|
|
};
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
|
|
void test_all()
|
|
{
|
|
test_recursive_devector();/*
|
|
test_max_size();
|
|
test_exceeding_max_size();
|
|
shrink_to_fit();*/
|
|
test_data();
|
|
test_il_assignment< devector<int> >();
|
|
test_assign_forward_range< devector<int> >();
|
|
test_assign_il<devector<int> >();
|
|
|
|
//test_devector< devector<int> >();
|
|
test_devector< devector<regular_elem> >();
|
|
test_devector< devector<noex_move> >();
|
|
test_devector< devector<noex_copy> >();
|
|
test_devector< devector<only_movable> >();
|
|
test_devector< devector<no_default_ctor> >();
|
|
|
|
////////////////////////////////////
|
|
// Allocator propagation testing
|
|
////////////////////////////////////
|
|
(void)boost::container::test::test_propagate_allocator<boost_container_devector>();
|
|
}
|
|
|
|
|
|
boost::container::vector<only_movable> getom()
|
|
{
|
|
typedef boost::container::vector<only_movable> V;
|
|
V v;
|
|
return BOOST_MOVE_RET(V, v);
|
|
}
|
|
|
|
|
|
boost::container::vector<boost::container::test::movable_int> get()
|
|
{
|
|
typedef boost::container::vector<boost::container::test::movable_int> V;
|
|
V v;
|
|
return BOOST_MOVE_RET(V, v);
|
|
}
|
|
|
|
template<class VoidAllocator>
|
|
int test_cont_variants()
|
|
{
|
|
typedef typename GetAllocatorCont<VoidAllocator>::template apply<int>::type MyCont;
|
|
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_int>::type MyMoveCont;
|
|
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::movable_and_copyable_int>::type MyCopyMoveCont;
|
|
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::copyable_int>::type MyCopyCont;
|
|
|
|
if(test::vector_test<MyCont>())
|
|
return 1;
|
|
if(test::vector_test<MyMoveCont>())
|
|
return 1;
|
|
if(test::vector_test<MyCopyMoveCont>())
|
|
return 1;
|
|
if(test::vector_test<MyCopyCont>())
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// boost::container::devector<boost::container::test::movable_int>a(get());
|
|
//boost::container::devector<only_movable> b(getom());
|
|
//boost::container::devector<only_movable> c(get_range< boost::container::devector<only_movable> >(1, 5, 5, 9));
|
|
test_all();
|
|
|
|
////////////////////////////////////
|
|
// Allocator implementations
|
|
////////////////////////////////////
|
|
// std:allocator
|
|
if (test_cont_variants< std::allocator<void> >()) {
|
|
std::cerr << "test_cont_variants< std::allocator<void> > failed" << std::endl;
|
|
return 1;
|
|
}
|
|
// boost::container::allocator
|
|
if (test_cont_variants< allocator<void> >()) {
|
|
std::cerr << "test_cont_variants< allocator<void> > failed" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// Default init test
|
|
////////////////////////////////////
|
|
if (!test::default_init_test< devector<int, test::default_init_allocator<int> > >()) {
|
|
std::cerr << "Default init test failed" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// Emplace testing
|
|
////////////////////////////////////
|
|
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
|
|
|
|
if (!boost::container::test::test_emplace< devector<test::EmplaceInt>, Options>())
|
|
return 1;
|
|
////////////////////////////////////
|
|
// Allocator propagation testing
|
|
////////////////////////////////////
|
|
if (!boost::container::test::test_propagate_allocator<boost_container_devector>())
|
|
return 1;
|
|
|
|
////////////////////////////////////
|
|
// Initializer lists testing
|
|
////////////////////////////////////
|
|
if (!boost::container::test::test_vector_methods_with_initializer_list_as_argument_for
|
|
< boost::container::devector<int> >()) {
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// Iterator testing
|
|
////////////////////////////////////
|
|
{
|
|
typedef boost::container::devector<int> cont_int;
|
|
cont_int a; a.push_back(0); a.push_back(1); a.push_back(2);
|
|
boost::intrusive::test::test_iterator_random< cont_int >(a);
|
|
if (boost::report_errors() != 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////
|
|
// has_trivial_destructor_after_move testing
|
|
////////////////////////////////////
|
|
// default allocator
|
|
{
|
|
typedef boost::container::devector<int> cont;
|
|
typedef cont::allocator_type allocator_type;
|
|
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
|
|
BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move<cont>::value !=
|
|
boost::has_trivial_destructor_after_move<allocator_type>::value &&
|
|
boost::has_trivial_destructor_after_move<pointer>::value)
|
|
, "has_trivial_destructor_after_move(std::allocator) test failed");
|
|
}
|
|
// std::allocator
|
|
{
|
|
typedef boost::container::devector<int, std::allocator<int> > cont;
|
|
typedef cont::allocator_type allocator_type;
|
|
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
|
|
BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move<cont>::value !=
|
|
boost::has_trivial_destructor_after_move<allocator_type>::value &&
|
|
boost::has_trivial_destructor_after_move<pointer>::value)
|
|
, "has_trivial_destructor_after_move(std::allocator) test failed");
|
|
}
|
|
|
|
return boost::report_errors();
|
|
}
|