mirror of
https://github.com/boostorg/container.git
synced 2026-02-26 04:32:21 +00:00
Integrate and adapt "devector's", from Thaler Benedek's implementation.
This commit is contained in:
121
test/devector_options_test.cpp
Normal file
121
test/devector_options_test.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. 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/container/devector.hpp>
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/detail/next_capacity.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
template<class Unsigned, class DevectorType>
|
||||
void test_stored_size_type_impl()
|
||||
{
|
||||
DevectorType v;
|
||||
typedef typename DevectorType::size_type size_type;
|
||||
typedef typename DevectorType::value_type value_type;
|
||||
size_type const max = Unsigned(-1);
|
||||
v.resize(5);
|
||||
v.resize(max);
|
||||
BOOST_TEST_THROWS(v.resize(max+1), std::exception);
|
||||
BOOST_TEST_THROWS(v.push_back(value_type(1)), std::exception);
|
||||
BOOST_TEST_THROWS(v.insert(v.begin(), value_type(1)), std::exception);
|
||||
BOOST_TEST_THROWS(v.emplace(v.begin(), value_type(1)),std::exception);
|
||||
BOOST_TEST_THROWS(v.reserve(max+1), std::exception);
|
||||
BOOST_TEST_THROWS(DevectorType v2(max+1), std::exception);
|
||||
}
|
||||
|
||||
template<class Unsigned>
|
||||
void test_stored_size_type()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
using options_t = devector_options_t< stored_size<Unsigned> >;
|
||||
#else
|
||||
typedef typename devector_options
|
||||
< stored_size<Unsigned> >::type options_t;
|
||||
#endif
|
||||
|
||||
//Test first with a typical allocator
|
||||
{
|
||||
typedef devector<unsigned char, new_allocator<unsigned char>, options_t> devector_t;
|
||||
test_stored_size_type_impl<Unsigned, devector_t>();
|
||||
}
|
||||
//Test with a V2 allocator
|
||||
{
|
||||
typedef devector<unsigned char, allocator<unsigned char>, options_t> devector_t;
|
||||
test_stored_size_type_impl<Unsigned, devector_t>();
|
||||
}
|
||||
}
|
||||
|
||||
void test_growth_factor_50()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
using options_t = devector_options_t< growth_factor<growth_factor_50> >;
|
||||
#else
|
||||
typedef devector_options
|
||||
< growth_factor<growth_factor_50> >::type options_t;
|
||||
#endif
|
||||
|
||||
devector<int, new_allocator<int>, options_t> v;
|
||||
|
||||
v.resize(5);
|
||||
v.resize(v.capacity());
|
||||
std::size_t old_capacity = v.capacity();
|
||||
v.push_back(0);
|
||||
std::size_t new_capacity = v.capacity();
|
||||
BOOST_TEST(new_capacity == old_capacity + old_capacity/2);
|
||||
}
|
||||
|
||||
void test_growth_factor_60()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
using options_t = devector_options_t< growth_factor<growth_factor_60> >;
|
||||
#else
|
||||
typedef devector_options
|
||||
< growth_factor<growth_factor_60> >::type options_t;
|
||||
#endif
|
||||
|
||||
devector<int, new_allocator<int>, options_t> v;
|
||||
|
||||
v.resize(5);
|
||||
v.resize(v.capacity());
|
||||
std::size_t old_capacity = v.capacity();
|
||||
v.push_back(0);
|
||||
std::size_t new_capacity = v.capacity();
|
||||
BOOST_TEST(new_capacity == old_capacity + 3*old_capacity/5);
|
||||
}
|
||||
|
||||
void test_growth_factor_100()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
using options_t = devector_options_t< growth_factor<growth_factor_100> >;
|
||||
#else
|
||||
typedef devector_options
|
||||
< growth_factor<growth_factor_100> >::type options_t;
|
||||
#endif
|
||||
|
||||
devector<int, new_allocator<int>, options_t> v;
|
||||
|
||||
v.resize(5);
|
||||
v.resize(v.capacity());
|
||||
std::size_t old_capacity = v.capacity();
|
||||
v.push_back(0);
|
||||
std::size_t new_capacity = v.capacity();
|
||||
BOOST_TEST(new_capacity == 2*old_capacity);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_growth_factor_50();
|
||||
test_growth_factor_60();
|
||||
test_growth_factor_100();
|
||||
test_stored_size_type<unsigned char>();
|
||||
test_stored_size_type<unsigned short>();
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
3932
test/devector_test.cpp
Normal file
3932
test/devector_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
41
test/explicit_inst_devector_test.cpp
Normal file
41
test/explicit_inst_devector_test.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// \(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/container/devector.hpp>
|
||||
#include "movable_int.hpp"
|
||||
|
||||
struct empty
|
||||
{
|
||||
friend bool operator == (const empty &, const empty &){ return true; }
|
||||
friend bool operator < (const empty &, const empty &){ return true; }
|
||||
};
|
||||
|
||||
template class ::boost::container::devector<empty>;
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//Test stored_size option
|
||||
template class devector< test::movable_and_copyable_int
|
||||
, new_allocator<test::movable_and_copyable_int>
|
||||
, devector_options< stored_size<unsigned short> >::type
|
||||
>;
|
||||
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
int main()
|
||||
{
|
||||
::boost::container::devector<empty> dummy;
|
||||
(void)dummy;
|
||||
return 0;
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/devector.hpp>
|
||||
#include <boost/container/deque.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
@@ -99,6 +100,15 @@ int main()
|
||||
std::cout << "Error in map_test<deque<std::pair<int, int> > >" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != test::map_test
|
||||
< GetMapContainer<devector<std::pair<int, int> > >::apply<int>::map_type
|
||||
, MyStdMap
|
||||
, GetMapContainer<devector<std::pair<int, int> > >::apply<int>::multimap_type
|
||||
, MyStdMultiMap>()) {
|
||||
std::cout << "Error in map_test<vector<std::pair<int, int> > >" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/container/deque.hpp>
|
||||
#include <boost/container/devector.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/container/detail/container_or_allocator_rebind.hpp>
|
||||
@@ -96,6 +97,14 @@ int main()
|
||||
std::cout << "Error in set_test<deque<int> >" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (0 != test::set_test
|
||||
< GetSetContainer<devector<int> >::apply<int>::set_type
|
||||
, MyStdSet
|
||||
, GetSetContainer<devector<int> >::apply<int>::multiset_type
|
||||
, MyStdMultiSet>()) {
|
||||
std::cout << "Error in set_test<deque<int> >" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
using namespace boost::container;
|
||||
|
||||
119
test/input_iterator.hpp
Normal file
119
test/input_iterator.hpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// \(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://erenon.hu/double_ended for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Emulates input iterator, validates algorithm
|
||||
* does a single pass only, removes visited elements.
|
||||
*
|
||||
* Container::erase(front_iterator) must not invalidate other iterators.
|
||||
*
|
||||
* The hack around `_erase_on_destroy` is required to make `*it++` work.
|
||||
*/
|
||||
template <typename Container>
|
||||
class input_iterator
|
||||
{
|
||||
typedef typename Container::iterator iterator;
|
||||
|
||||
public:
|
||||
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename Container::pointer pointer;
|
||||
typedef typename Container::reference reference;
|
||||
typedef typename Container::difference_type difference_type;
|
||||
|
||||
struct erase_on_destroy {};
|
||||
|
||||
public:
|
||||
|
||||
input_iterator()
|
||||
: _container()
|
||||
, _it()
|
||||
, _erase_on_destroy()
|
||||
{}
|
||||
|
||||
input_iterator(Container& c, iterator it)
|
||||
:_container(&c)
|
||||
, _it(it)
|
||||
, _erase_on_destroy()
|
||||
{}
|
||||
|
||||
input_iterator(const input_iterator& rhs)
|
||||
:_container(rhs._container),
|
||||
_it(rhs._it),
|
||||
_erase_on_destroy(rhs._erase_on_destroy)
|
||||
{
|
||||
rhs._erase_on_destroy = false;
|
||||
}
|
||||
|
||||
input_iterator & operator=(const input_iterator& rhs)
|
||||
{
|
||||
_container = rhs._container;
|
||||
_it = rhs._it;
|
||||
_erase_on_destroy = rhs._erase_on_destroy;
|
||||
rhs._erase_on_destroy = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
input_iterator(const input_iterator& rhs, erase_on_destroy)
|
||||
:_container(rhs._container),
|
||||
_it(rhs._it),
|
||||
_erase_on_destroy(true)
|
||||
{}
|
||||
|
||||
~input_iterator()
|
||||
{
|
||||
if (_erase_on_destroy)
|
||||
{
|
||||
_container->erase(_it); // must not invalidate other iterators
|
||||
}
|
||||
}
|
||||
|
||||
const value_type& operator*()
|
||||
{
|
||||
return *_it;
|
||||
}
|
||||
|
||||
input_iterator operator++()
|
||||
{
|
||||
_container->erase(_it);
|
||||
++_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
input_iterator operator++(int)
|
||||
{
|
||||
input_iterator old(*this, erase_on_destroy());
|
||||
++_it;
|
||||
return old;
|
||||
}
|
||||
|
||||
friend bool operator==(const input_iterator a, const input_iterator b)
|
||||
{
|
||||
return a._it == b._it;
|
||||
}
|
||||
|
||||
friend bool operator!=(const input_iterator a, const input_iterator b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
private:
|
||||
Container* _container;
|
||||
iterator _it;
|
||||
mutable bool _erase_on_destroy;
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
input_iterator<Container> make_input_iterator(Container& c, typename Container::iterator it)
|
||||
{
|
||||
return input_iterator<Container>(c, it);
|
||||
}
|
||||
26
test/pmr_devector_test.cpp
Normal file
26
test/pmr_devector_test.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2015-2015. 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/container/pmr/devector.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
using boost::container::dtl::is_same;
|
||||
|
||||
typedef devector<int, growth_factor_60, pmr::polymorphic_allocator<int> > intcontainer_t;
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::devector_of<int>::type >::value ));
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::devector<int> >::value ));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
319
test/test_elem.hpp
Normal file
319
test/test_elem.hpp
Normal file
@@ -0,0 +1,319 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// \(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://erenon.hu/double_ended for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_TEST_TEST_ELEM_HPP
|
||||
#define BOOST_CONTAINER_TEST_TEST_ELEM_HPP
|
||||
|
||||
#include <boost/utility/compare_pointees.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
struct test_exception {};
|
||||
|
||||
struct test_elem_throw
|
||||
{
|
||||
private:
|
||||
static int throw_on_ctor_after /*= -1*/;
|
||||
static int throw_on_copy_after /*= -1*/;
|
||||
static int throw_on_move_after /*= -1*/;
|
||||
|
||||
public:
|
||||
static void on_ctor_after(int x) { throw_on_ctor_after = x; }
|
||||
static void on_copy_after(int x) { throw_on_copy_after = x; }
|
||||
static void on_move_after(int x) { throw_on_move_after = x; }
|
||||
|
||||
static void do_not_throw()
|
||||
{
|
||||
throw_on_ctor_after = -1;
|
||||
throw_on_copy_after = -1;
|
||||
throw_on_move_after = -1;
|
||||
}
|
||||
|
||||
static void in_constructor() { maybe_throw(throw_on_ctor_after); }
|
||||
static void in_copy() { maybe_throw(throw_on_copy_after); }
|
||||
static void in_move() { maybe_throw(throw_on_move_after); }
|
||||
|
||||
private:
|
||||
static void maybe_throw(int& counter)
|
||||
{
|
||||
if (counter > 0)
|
||||
{
|
||||
--counter;
|
||||
if (counter == 0)
|
||||
{
|
||||
--counter;
|
||||
throw test_exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int test_elem_throw::throw_on_ctor_after = -1;
|
||||
int test_elem_throw::throw_on_copy_after = -1;
|
||||
int test_elem_throw::throw_on_move_after = -1;
|
||||
|
||||
struct test_elem_base
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(test_elem_base)
|
||||
|
||||
public:
|
||||
test_elem_base()
|
||||
{
|
||||
test_elem_throw::in_constructor();
|
||||
_index = new int(0);
|
||||
++_live_count;
|
||||
}
|
||||
|
||||
test_elem_base(int index)
|
||||
{
|
||||
test_elem_throw::in_constructor();
|
||||
_index = new int(index);
|
||||
++_live_count;
|
||||
}
|
||||
|
||||
explicit test_elem_base(const test_elem_base& rhs)
|
||||
{
|
||||
test_elem_throw::in_copy();
|
||||
_index = new int(*rhs._index);
|
||||
++_live_count;
|
||||
}
|
||||
|
||||
test_elem_base(BOOST_RV_REF(test_elem_base) rhs)
|
||||
{
|
||||
test_elem_throw::in_move();
|
||||
_index = rhs._index;
|
||||
rhs._index = 0;
|
||||
++_live_count;
|
||||
}
|
||||
|
||||
test_elem_base &operator=(BOOST_COPY_ASSIGN_REF(test_elem_base) rhs)
|
||||
{
|
||||
test_elem_throw::in_copy();
|
||||
if (_index) { delete _index; }
|
||||
_index = new int(*rhs._index);
|
||||
return *this;
|
||||
}
|
||||
|
||||
test_elem_base &operator=(BOOST_RV_REF(test_elem_base) rhs)
|
||||
{
|
||||
test_elem_throw::in_move();
|
||||
if (_index) { delete _index; }
|
||||
_index = rhs._index;
|
||||
rhs._index = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~test_elem_base()
|
||||
{
|
||||
if (_index) { delete _index; }
|
||||
--_live_count;
|
||||
}
|
||||
|
||||
friend bool operator==(const test_elem_base& a, const test_elem_base& b)
|
||||
{
|
||||
return a._index && b._index && *(a._index) == *(b._index);
|
||||
}
|
||||
|
||||
friend bool operator==(int a, const test_elem_base& b)
|
||||
{
|
||||
return b._index != 0 && a == *(b._index);
|
||||
}
|
||||
|
||||
friend bool operator==(const test_elem_base& a, int b)
|
||||
{
|
||||
return a._index != 0 && *(a._index) == b;
|
||||
}
|
||||
|
||||
friend bool operator<(const test_elem_base& a, const test_elem_base& b)
|
||||
{
|
||||
return boost::less_pointees(a._index, b._index);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const test_elem_base& elem)
|
||||
{
|
||||
if (elem._index) { out << *elem._index; }
|
||||
else { out << "null"; }
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename Archive>
|
||||
void serialize(Archive& ar, unsigned /* version */)
|
||||
{
|
||||
ar & *_index;
|
||||
}
|
||||
|
||||
static bool no_living_elem()
|
||||
{
|
||||
return _live_count == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int* _index;
|
||||
|
||||
static int _live_count;
|
||||
};
|
||||
|
||||
int test_elem_base::_live_count = 0;
|
||||
|
||||
struct regular_elem : test_elem_base
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(regular_elem)
|
||||
|
||||
public:
|
||||
regular_elem()
|
||||
{}
|
||||
|
||||
regular_elem(int index) : test_elem_base(index) {}
|
||||
|
||||
regular_elem(const regular_elem& rhs)
|
||||
:test_elem_base(rhs)
|
||||
{}
|
||||
|
||||
regular_elem(BOOST_RV_REF(regular_elem) rhs)
|
||||
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
|
||||
{}
|
||||
|
||||
regular_elem &operator=(BOOST_COPY_ASSIGN_REF(regular_elem) rhs)
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
regular_elem &operator=(BOOST_RV_REF(regular_elem) rhs)
|
||||
{
|
||||
regular_elem &r = rhs;
|
||||
static_cast<test_elem_base&>(*this) = boost::move(r);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct noex_move : test_elem_base
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(noex_move)
|
||||
|
||||
public:
|
||||
noex_move()
|
||||
{}
|
||||
|
||||
noex_move(int index) : test_elem_base(index) {}
|
||||
|
||||
noex_move(const noex_move& rhs)
|
||||
:test_elem_base(rhs)
|
||||
{}
|
||||
|
||||
noex_move(BOOST_RV_REF(noex_move) rhs) BOOST_NOEXCEPT
|
||||
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
|
||||
{}
|
||||
|
||||
noex_move &operator=(BOOST_COPY_ASSIGN_REF(noex_move) rhs)
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
noex_move &operator=(BOOST_RV_REF(noex_move) rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
noex_move & r = rhs;
|
||||
static_cast<test_elem_base&>(*this) = boost::move(r);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct noex_copy : test_elem_base
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(noex_copy)
|
||||
|
||||
public:
|
||||
noex_copy(){}
|
||||
|
||||
noex_copy(int index) : test_elem_base(index) {}
|
||||
|
||||
noex_copy(const noex_copy& rhs) BOOST_NOEXCEPT
|
||||
:test_elem_base(rhs)
|
||||
{}
|
||||
|
||||
noex_copy(BOOST_RV_REF(noex_copy) rhs)
|
||||
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
|
||||
{}
|
||||
|
||||
noex_copy &operator=(BOOST_COPY_ASSIGN_REF(noex_copy) rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
noex_copy &operator=(BOOST_RV_REF(noex_copy) rhs)
|
||||
{
|
||||
noex_copy &r = rhs;
|
||||
static_cast<test_elem_base&>(*this) = boost::move(r);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct only_movable : test_elem_base
|
||||
{
|
||||
private:
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable)
|
||||
|
||||
public:
|
||||
only_movable(){};
|
||||
|
||||
only_movable(int index) : test_elem_base(index) {}
|
||||
|
||||
only_movable(BOOST_RV_REF(only_movable) rhs)
|
||||
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
|
||||
{}
|
||||
|
||||
only_movable &operator=(BOOST_RV_REF(only_movable) rhs)
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = boost::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct no_default_ctor : test_elem_base
|
||||
{
|
||||
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(no_default_ctor)
|
||||
|
||||
public:
|
||||
no_default_ctor(int index) : test_elem_base(index) {}
|
||||
|
||||
no_default_ctor(const no_default_ctor& rhs)
|
||||
:test_elem_base(rhs)
|
||||
{}
|
||||
|
||||
no_default_ctor(BOOST_RV_REF(no_default_ctor) rhs)
|
||||
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
|
||||
{}
|
||||
|
||||
no_default_ctor &operator=(BOOST_RV_REF(no_default_ctor) rhs)
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = boost::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
no_default_ctor &operator=(BOOST_COPY_ASSIGN_REF(no_default_ctor) rhs)
|
||||
{
|
||||
static_cast<test_elem_base&>(*this) = rhs;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_TEST_ELEM_HPP
|
||||
139
test/test_util.hpp
Normal file
139
test/test_util.hpp
Normal file
@@ -0,0 +1,139 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// \(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://erenon.hu/double_ended for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_TEST_TEST_UTIL_HPP
|
||||
#define BOOST_CONTAINER_TEST_TEST_UTIL_HPP
|
||||
|
||||
#include "test_elem.hpp"
|
||||
|
||||
// get_range
|
||||
|
||||
template <typename DeVector>
|
||||
void get_range(int fbeg, int fend, int bbeg, int bend, DeVector &c)
|
||||
{
|
||||
c.clear();
|
||||
|
||||
for (int i = fend; i > fbeg ;)
|
||||
{
|
||||
c.emplace_front(--i);
|
||||
}
|
||||
|
||||
for (int i = bbeg; i < bend; ++i)
|
||||
{
|
||||
c.emplace_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void get_range(int count, Container &c)
|
||||
{
|
||||
c.clear();
|
||||
|
||||
for (int i = 1; i <= count; ++i)
|
||||
{
|
||||
c.emplace_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void get_range(Container &c)
|
||||
{
|
||||
get_range<Container>(1, 13, 13, 25, c);
|
||||
}
|
||||
|
||||
template <typename C1>
|
||||
void test_equal_range(const C1& a)
|
||||
{
|
||||
BOOST_TEST(a.empty());
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void print_range(std::ostream& out, Iterator b, Iterator e)
|
||||
{
|
||||
out << '[';
|
||||
bool first = true;
|
||||
|
||||
for (; b != e; ++b)
|
||||
{
|
||||
if (first) { first = false; }
|
||||
else { out << ','; }
|
||||
out << *b;
|
||||
}
|
||||
out << ']';
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
void print_range(std::ostream& out, const Range& range)
|
||||
{
|
||||
print_range(out, range.cbegin(), range.cend());
|
||||
}
|
||||
|
||||
template <typename Array, std::size_t N>
|
||||
void print_range(std::ostream& out, Array (&range)[N])
|
||||
{
|
||||
print_range(out, range, range + N);
|
||||
}
|
||||
|
||||
template <typename C1, typename C2, unsigned N>
|
||||
void test_equal_range(const C1& a, const C2 (&b)[N])
|
||||
{
|
||||
bool equals = boost::algorithm::equal
|
||||
(a.begin(), a.end(), b, b+N);
|
||||
|
||||
BOOST_TEST(equals);
|
||||
|
||||
if (!equals)
|
||||
{
|
||||
print_range(std::cerr, a);
|
||||
std::cerr << "\n";
|
||||
print_range(std::cerr, b);
|
||||
std::cerr << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename C1, typename C2>
|
||||
void test_equal_range(const C1& a, const C2&b)
|
||||
{
|
||||
bool equals = boost::algorithm::equal
|
||||
(a.begin(), a.end(), b.begin(), b.end());
|
||||
|
||||
BOOST_TEST(equals);
|
||||
|
||||
if (!equals)
|
||||
{
|
||||
print_range(std::cerr, a);
|
||||
std::cerr << "\n";
|
||||
print_range(std::cerr, b);
|
||||
std::cerr << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
// support initializer_list
|
||||
template <typename C>
|
||||
void test_equal_range(const C& a, std::initializer_list<unsigned> il)
|
||||
{
|
||||
typedef typename C::value_type T;
|
||||
boost::container::vector<T> b;
|
||||
|
||||
for (auto&& elem : il)
|
||||
{
|
||||
b.emplace_back(elem);
|
||||
}
|
||||
|
||||
test_equal_range(a, b);
|
||||
}
|
||||
|
||||
#endif //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
#endif //BOOST_CONTAINER_TEST_TEST_UTIL_HPP
|
||||
Reference in New Issue
Block a user