mirror of
https://github.com/boostorg/container.git
synced 2025-08-01 05:24:31 +02:00
Fixes #233 ("Can't std::move small_vector with move-only type")
This commit is contained in:
@@ -345,7 +345,7 @@ class small_vector_base
|
||||
public:
|
||||
//Make it public as it will be inherited by small_vector and container
|
||||
//must have this public member
|
||||
typedef typename real_allocator<T, SecAlloc>::type secondary_allocator_t;
|
||||
typedef typename real_allocator<T, SecAlloc>::type secondary_allocator_t;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::
|
||||
template portable_rebind_alloc<void>::type void_allocator_t;
|
||||
typedef typename dtl::get_small_vector_opt<Options>::type options_t;
|
||||
@@ -387,6 +387,24 @@ class small_vector_base
|
||||
: base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a))
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(maybe_initial_capacity_t, std::size_t initial_capacity, std::size_t initial_size)
|
||||
: base_type( maybe_initial_capacity_t()
|
||||
, (initial_capacity >= initial_size) ? this->internal_storage() : pointer()
|
||||
, (initial_capacity >= initial_size) ? initial_capacity : initial_size
|
||||
)
|
||||
{}
|
||||
|
||||
template<class AllocFwd>
|
||||
BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(maybe_initial_capacity_t, std::size_t initial_capacity, std::size_t initial_size, BOOST_FWD_REF(AllocFwd) a)
|
||||
: base_type(maybe_initial_capacity_t()
|
||||
, (initial_capacity >= initial_size) ? this->internal_storage() : pointer()
|
||||
, (initial_capacity >= initial_size) ? initial_capacity : initial_size
|
||||
, ::boost::forward<AllocFwd>(a)
|
||||
)
|
||||
{}
|
||||
|
||||
using base_type::protected_set_size;
|
||||
|
||||
//~small_vector_base(){}
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
@@ -408,9 +426,10 @@ class small_vector_base
|
||||
this->steal_resources(x);
|
||||
}
|
||||
else{
|
||||
this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
|
||||
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ()))
|
||||
);
|
||||
const typename base_type::size_type sz = x.size();
|
||||
::boost::container::uninitialized_move_alloc_n_source
|
||||
(this->base_type::get_stored_allocator(), x.begin(), sz, this->begin());
|
||||
this->protected_set_size(sz);
|
||||
x.clear();
|
||||
}
|
||||
}
|
||||
@@ -546,28 +565,28 @@ class small_vector
|
||||
{}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE explicit small_vector(size_type n)
|
||||
: base_type(initial_capacity_t(), internal_capacity())
|
||||
{ this->resize(n); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n)
|
||||
{ this->protected_init_n(n, value_init); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const allocator_type &a)
|
||||
: base_type(initial_capacity_t(), internal_capacity(), a)
|
||||
{ this->resize(n); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
|
||||
{ this->protected_init_n(n, value_init); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t)
|
||||
: base_type(initial_capacity_t(), internal_capacity())
|
||||
{ this->resize(n, default_init_t()); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n)
|
||||
{ this->protected_init_n(n, default_init_t()); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, default_init_t, const allocator_type &a)
|
||||
: base_type(initial_capacity_t(), internal_capacity(), a)
|
||||
{ this->resize(n, default_init_t()); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
|
||||
{ this->protected_init_n(n, default_init_t()); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v)
|
||||
: base_type(initial_capacity_t(), internal_capacity())
|
||||
{ this->resize(n, v); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n)
|
||||
{ this->protected_init_n(n, v); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(size_type n, const value_type &v, const allocator_type &a)
|
||||
: base_type(initial_capacity_t(), internal_capacity(), a)
|
||||
{ this->resize(n, v); }
|
||||
: base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
|
||||
{ this->protected_init_n(n, v); }
|
||||
|
||||
template <class InIt>
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector(InIt first, InIt last
|
||||
|
@@ -257,8 +257,6 @@ struct vector_insert_ordered_cursor
|
||||
BiDirValueIt last_value_it;
|
||||
};
|
||||
|
||||
struct initial_capacity_t{};
|
||||
|
||||
template<class Pointer, bool IsConst>
|
||||
BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return it.get_ptr(); }
|
||||
@@ -267,9 +265,13 @@ template<class Pointer, bool IsConst>
|
||||
BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return it.get_ptr(); }
|
||||
|
||||
struct initial_capacity_t {};
|
||||
|
||||
struct vector_uninitialized_size_t {};
|
||||
static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t();
|
||||
|
||||
struct maybe_initial_capacity_t {};
|
||||
|
||||
template <class T>
|
||||
struct vector_value_traits_base
|
||||
{
|
||||
@@ -312,6 +314,43 @@ struct vector_alloc_holder
|
||||
typedef typename allocator_traits_type::size_type size_type;
|
||||
typedef typename allocator_traits_type::value_type value_type;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
template<class SizeType>
|
||||
void do_initial_capacity(SizeType initial_capacity)
|
||||
{
|
||||
if (BOOST_UNLIKELY(initial_capacity > size_type(-1))) {
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
|
||||
}
|
||||
else if (initial_capacity) {
|
||||
pointer reuse = pointer();
|
||||
size_type final_cap = static_cast<size_type>(initial_capacity);
|
||||
m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
|
||||
this->set_stored_capacity(final_cap);
|
||||
}
|
||||
}
|
||||
|
||||
template<class SizeType>
|
||||
void do_maybe_initial_capacity(pointer p, SizeType initial_capacity)
|
||||
{
|
||||
if (BOOST_UNLIKELY(initial_capacity > size_type(-1))) {
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
|
||||
}
|
||||
else if (p) {
|
||||
m_start = p;
|
||||
}
|
||||
else {
|
||||
BOOST_ASSERT(initial_capacity > 0);
|
||||
pointer reuse = pointer();
|
||||
size_type final_cap = static_cast<size_type>(initial_capacity);
|
||||
m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
|
||||
this->set_stored_capacity(final_cap);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator)
|
||||
{
|
||||
@@ -343,7 +382,7 @@ struct vector_alloc_holder
|
||||
: allocator_type(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
|
||||
{}
|
||||
|
||||
//Constructor, does not throw
|
||||
|
||||
template<class AllocConvertible, class SizeType>
|
||||
vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, SizeType initial_size)
|
||||
: allocator_type(boost::forward<AllocConvertible>(a))
|
||||
@@ -351,19 +390,8 @@ struct vector_alloc_holder
|
||||
//Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size(static_cast<stored_size_type>(initial_size))
|
||||
, m_capacity()
|
||||
{
|
||||
if (BOOST_UNLIKELY(initial_size > size_type(-1))){
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
|
||||
}
|
||||
else if(initial_size){
|
||||
pointer reuse = pointer();
|
||||
size_type final_cap = static_cast<size_type>(initial_size);
|
||||
m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
|
||||
this->set_stored_capacity(final_cap);
|
||||
}
|
||||
}
|
||||
{ this->do_initial_capacity(initial_size); }
|
||||
|
||||
//Constructor, does not throw
|
||||
template<class SizeType>
|
||||
vector_alloc_holder(vector_uninitialized_size_t, SizeType initial_size)
|
||||
: allocator_type()
|
||||
@@ -371,27 +399,7 @@ struct vector_alloc_holder
|
||||
//Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size(static_cast<stored_size_type>(initial_size))
|
||||
, m_capacity()
|
||||
{
|
||||
if (BOOST_UNLIKELY(initial_size > size_type(-1))){
|
||||
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
|
||||
}
|
||||
else if(initial_size){
|
||||
pointer reuse = pointer();
|
||||
size_type final_cap = initial_size;
|
||||
m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse);
|
||||
this->set_stored_capacity(final_cap);
|
||||
}
|
||||
}
|
||||
|
||||
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: allocator_type(BOOST_MOVE_BASE(allocator_type, holder))
|
||||
, m_start(holder.m_start)
|
||||
, m_size(holder.m_size)
|
||||
, m_capacity(holder.m_capacity)
|
||||
{
|
||||
holder.m_start = pointer();
|
||||
holder.m_size = holder.m_capacity = 0;
|
||||
}
|
||||
{ this->do_initial_capacity(initial_size); }
|
||||
|
||||
vector_alloc_holder(initial_capacity_t, pointer p, size_type n)
|
||||
BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
|
||||
@@ -410,6 +418,34 @@ struct vector_alloc_holder
|
||||
, m_capacity(n)
|
||||
{}
|
||||
|
||||
template<class AllocConvertible, class SizeType>
|
||||
vector_alloc_holder(maybe_initial_capacity_t, pointer p, SizeType initial_capacity, BOOST_FWD_REF(AllocConvertible) a)
|
||||
: allocator_type(boost::forward<AllocConvertible>(a))
|
||||
//, m_start()
|
||||
//Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size()
|
||||
, m_capacity(static_cast<stored_size_type>(initial_capacity))
|
||||
{ this->do_maybe_initial_capacity(p, initial_capacity); }
|
||||
|
||||
template<class SizeType>
|
||||
vector_alloc_holder(maybe_initial_capacity_t, pointer p, SizeType initial_capacity)
|
||||
: allocator_type()
|
||||
//, m_start()
|
||||
//Size is initialized here so vector should only call uninitialized_xxx after this
|
||||
, m_size()
|
||||
, m_capacity(static_cast<stored_size_type>(initial_capacity))
|
||||
{ this->do_maybe_initial_capacity(p, initial_capacity); }
|
||||
|
||||
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: allocator_type(BOOST_MOVE_BASE(allocator_type, holder))
|
||||
, m_start(holder.m_start)
|
||||
, m_size(holder.m_size)
|
||||
, m_capacity(holder.m_capacity)
|
||||
{
|
||||
holder.m_start = pointer();
|
||||
holder.m_size = holder.m_capacity = 0;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if(this->m_capacity){
|
||||
@@ -822,6 +858,9 @@ private:
|
||||
BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x)
|
||||
{ return this->m_holder.steal_resources(x.m_holder); }
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE void protected_set_size(size_type n)
|
||||
{ this->m_holder.m_size = static_cast<stored_size_type>(n); }
|
||||
|
||||
template<class AllocFwd>
|
||||
BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type cap, BOOST_FWD_REF(AllocFwd) a)
|
||||
: m_holder(initial_capacity_t(), initial_memory, cap, ::boost::forward<AllocFwd>(a))
|
||||
@@ -831,6 +870,32 @@ private:
|
||||
: m_holder(initial_capacity_t(), initial_memory, cap)
|
||||
{}
|
||||
|
||||
template<class SizeType, class AllocFwd>
|
||||
BOOST_CONTAINER_FORCEINLINE vector(maybe_initial_capacity_t, pointer p, SizeType initial_capacity, BOOST_FWD_REF(AllocFwd) a)
|
||||
: m_holder(maybe_initial_capacity_t(), p, initial_capacity, ::boost::forward<AllocFwd>(a))
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
this->num_alloc += size_type(p != pointer());
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class SizeType>
|
||||
BOOST_CONTAINER_FORCEINLINE vector(maybe_initial_capacity_t, pointer p, SizeType initial_capacity)
|
||||
: m_holder(maybe_initial_capacity_t(), p, initial_capacity)
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
this->num_alloc += size_type(p != pointer());
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class U>
|
||||
void protected_init_n(const size_type new_size, const U& u)
|
||||
{
|
||||
BOOST_ASSERT(this->empty());
|
||||
this->priv_resize_proxy(u).uninitialized_copy_n_and_update(this->m_holder.alloc(), this->priv_raw_begin(), new_size);
|
||||
this->m_holder.set_stored_size(new_size);
|
||||
}
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
public:
|
||||
|
@@ -31,7 +31,19 @@ struct is_copyable<int>
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_move_assignable
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// movable_int
|
||||
//
|
||||
/////////////////////////
|
||||
class movable_int
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_int)
|
||||
@@ -122,13 +134,8 @@ inline movable_int produce_movable_int()
|
||||
{ return movable_int(); }
|
||||
|
||||
template<class E, class T>
|
||||
std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, movable_int const & p)
|
||||
|
||||
{
|
||||
os << p.get_int();
|
||||
return os;
|
||||
}
|
||||
std::basic_ostream<E, T> & operator<<(std::basic_ostream<E, T> & os, movable_int const & p)
|
||||
{ os << p.get_int(); return os; }
|
||||
|
||||
template<>
|
||||
struct is_copyable<movable_int>
|
||||
@@ -136,6 +143,150 @@ struct is_copyable<movable_int>
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// moveconstruct_int
|
||||
//
|
||||
/////////////////////////
|
||||
class moveconstruct_int
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(moveconstruct_int)
|
||||
|
||||
moveconstruct_int& operator= (BOOST_RV_REF(moveconstruct_int) mmi);
|
||||
|
||||
public:
|
||||
|
||||
static unsigned int count;
|
||||
|
||||
moveconstruct_int()
|
||||
: m_int(0)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
|
||||
explicit moveconstruct_int(int a)
|
||||
: m_int(a)
|
||||
{
|
||||
//Disallow INT_MIN
|
||||
BOOST_ASSERT(this->m_int != INT_MIN);
|
||||
++count;
|
||||
}
|
||||
|
||||
moveconstruct_int(BOOST_RV_REF(moveconstruct_int) mmi)
|
||||
: m_int(mmi.m_int)
|
||||
{
|
||||
BOOST_ASSERT(&mmi != this);
|
||||
mmi.m_int = 0; ++count;
|
||||
}
|
||||
|
||||
moveconstruct_int& operator= (int i)
|
||||
{
|
||||
this->m_int = i; BOOST_ASSERT(this->m_int != INT_MIN); return *this;
|
||||
}
|
||||
|
||||
~moveconstruct_int()
|
||||
{
|
||||
//Double destructor called
|
||||
BOOST_ASSERT(this->m_int != INT_MIN);
|
||||
this->m_int = INT_MIN;
|
||||
--count;
|
||||
}
|
||||
|
||||
friend bool operator ==(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int == r.m_int;
|
||||
}
|
||||
|
||||
friend bool operator !=(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int != r.m_int;
|
||||
}
|
||||
|
||||
friend bool operator <(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int < r.m_int;
|
||||
}
|
||||
|
||||
friend bool operator <=(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int <= r.m_int;
|
||||
}
|
||||
|
||||
friend bool operator >=(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int >= r.m_int;
|
||||
}
|
||||
|
||||
friend bool operator >(const moveconstruct_int& l, const moveconstruct_int& r)
|
||||
{
|
||||
return l.m_int > r.m_int;
|
||||
}
|
||||
|
||||
int get_int() const
|
||||
{
|
||||
return m_int;
|
||||
}
|
||||
|
||||
friend bool operator==(const moveconstruct_int& l, int r)
|
||||
{
|
||||
return l.get_int() == r;
|
||||
}
|
||||
|
||||
friend bool operator==(int l, const moveconstruct_int& r)
|
||||
{
|
||||
return l == r.get_int();
|
||||
}
|
||||
|
||||
friend bool operator<(const moveconstruct_int& l, int r)
|
||||
{
|
||||
return l.get_int() < r;
|
||||
}
|
||||
|
||||
friend bool operator<(int l, const moveconstruct_int& r)
|
||||
{
|
||||
return l < r.get_int();
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(const moveconstruct_int& v)
|
||||
{
|
||||
return (std::size_t)v.get_int();
|
||||
}
|
||||
|
||||
private:
|
||||
int m_int;
|
||||
};
|
||||
|
||||
unsigned int moveconstruct_int::count = 0;
|
||||
|
||||
inline moveconstruct_int produce_movableconstruct_int()
|
||||
{
|
||||
return moveconstruct_int();
|
||||
}
|
||||
|
||||
template<class E, class T>
|
||||
std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& os, moveconstruct_int const& p)
|
||||
{
|
||||
os << p.get_int(); return os;
|
||||
}
|
||||
|
||||
template<>
|
||||
struct is_copyable<moveconstruct_int>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct is_move_assignable<moveconstruct_int>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// movable_and_copyable_int
|
||||
//
|
||||
/////////////////////////
|
||||
class movable_and_copyable_int
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(movable_and_copyable_int)
|
||||
@@ -236,13 +387,8 @@ inline movable_and_copyable_int produce_movable_and_copyable_int()
|
||||
{ return movable_and_copyable_int(); }
|
||||
|
||||
template<class E, class T>
|
||||
std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
|
||||
|
||||
{
|
||||
os << p.get_int();
|
||||
return os;
|
||||
}
|
||||
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, movable_and_copyable_int const & p)
|
||||
{ os << p.get_int(); return os; }
|
||||
|
||||
template<>
|
||||
struct is_copyable<movable_and_copyable_int>
|
||||
@@ -250,6 +396,12 @@ struct is_copyable<movable_and_copyable_int>
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// copyable_int
|
||||
//
|
||||
/////////////////////////
|
||||
class copyable_int
|
||||
{
|
||||
public:
|
||||
@@ -332,13 +484,8 @@ inline copyable_int produce_copyable_int()
|
||||
{ return copyable_int(); }
|
||||
|
||||
template<class E, class T>
|
||||
std::basic_ostream<E, T> & operator<<
|
||||
(std::basic_ostream<E, T> & os, copyable_int const & p)
|
||||
|
||||
{
|
||||
os << p.get_int();
|
||||
return os;
|
||||
}
|
||||
std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, copyable_int const & p)
|
||||
{ os << p.get_int(); return os; }
|
||||
|
||||
template<>
|
||||
struct is_copyable<copyable_int>
|
||||
@@ -346,6 +493,11 @@ struct is_copyable<copyable_int>
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
/////////////////////////
|
||||
//
|
||||
// non_copymovable_int
|
||||
//
|
||||
/////////////////////////
|
||||
class non_copymovable_int
|
||||
{
|
||||
non_copymovable_int(const non_copymovable_int& mmi);
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "../../intrusive/test/iterator_test.hpp"
|
||||
|
||||
#include <boost/container/allocator.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -149,6 +150,43 @@ bool test_swap()
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class VoidAllocator>
|
||||
struct GetAllocatorCont
|
||||
{
|
||||
template<class ValueType>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::container::small_vector< ValueType, 10
|
||||
, typename boost::container::allocator_traits<VoidAllocator>
|
||||
::template portable_rebind_alloc<ValueType>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class VoidAllocator>
|
||||
int test_cont_variants()
|
||||
{
|
||||
using namespace boost::container;
|
||||
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;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::moveconstruct_int>::type MyMoveConstructCont;
|
||||
|
||||
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;
|
||||
if (test::vector_test<MyMoveConstructCont>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::container;
|
||||
@@ -162,6 +200,9 @@ int main()
|
||||
if(test::vector_test< small_vector<int, 2000> >())
|
||||
return 1;
|
||||
|
||||
if (test_cont_variants< new_allocator<void> >())
|
||||
return 1;
|
||||
|
||||
////////////////////////////////////
|
||||
// Default init test
|
||||
////////////////////////////////////
|
||||
|
@@ -127,6 +127,7 @@ int test_cont_variants()
|
||||
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;
|
||||
typedef typename GetAllocatorCont<VoidAllocator>::template apply<test::moveconstruct_int>::type MyMoveConstructCont;
|
||||
|
||||
if(test::vector_test<MyCont>())
|
||||
return 1;
|
||||
@@ -136,6 +137,8 @@ int test_cont_variants()
|
||||
return 1;
|
||||
if(test::vector_test<MyCopyCont>())
|
||||
return 1;
|
||||
if (test::vector_test<MyMoveConstructCont>())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -271,49 +271,23 @@ bool vector_copyable_only(MyBoostVector &boostvector, MyStdVector &stdvector, bo
|
||||
}
|
||||
|
||||
template<class MyBoostVector>
|
||||
int vector_test()
|
||||
int vector_move_assignable_only(boost::container::dtl::false_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Function to check if both sets are equal
|
||||
template<class MyBoostVector>
|
||||
int vector_move_assignable_only(boost::container::dtl::true_type)
|
||||
{
|
||||
const int max = 100;
|
||||
typedef std::vector<int> MyStdVector;
|
||||
typedef typename MyBoostVector::value_type IntType;
|
||||
typedef typename MyBoostVector::difference_type difference_type;
|
||||
const int max = 100;
|
||||
|
||||
if(!test_range_insertion<MyBoostVector>()){
|
||||
return 1;
|
||||
}
|
||||
{ //Vector(n)
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(n, alloc)
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u, typename MyBoostVector::allocator_type());
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(Vector &&)
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
|
||||
::boost::movelib::make_unique<MyBoostVector>(::boost::move(*boostvectorp));
|
||||
if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(Vector &&, alloc)
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
|
||||
::boost::movelib::make_unique<MyBoostVector>
|
||||
(::boost::move(*boostvectorp), typename MyBoostVector::allocator_type());
|
||||
if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
|
||||
}
|
||||
|
||||
{ //Vector operator=(Vector &&)
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
@@ -521,7 +495,7 @@ int vector_test()
|
||||
stdvector.assign(l.begin(), l.end());
|
||||
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
|
||||
}
|
||||
|
||||
|
||||
if(!vector_capacity_test(boostvector, stdvector, dtl::bool_<vector_has_function_capacity<MyBoostVector>::value>()))
|
||||
return 1;
|
||||
|
||||
@@ -534,8 +508,53 @@ int vector_test()
|
||||
boostvector.resize(100u);
|
||||
if(!test_nth_index_of(boostvector))
|
||||
return 1;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class MyBoostVector>
|
||||
int vector_test()
|
||||
{
|
||||
typedef std::vector<int> MyStdVector;
|
||||
typedef typename MyBoostVector::value_type IntType;
|
||||
|
||||
{ //Vector(n)
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(n, alloc)
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u, typename MyBoostVector::allocator_type());
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
if(!test::CheckEqualContainers(*boostvectorp, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(Vector &&)
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
|
||||
::boost::movelib::make_unique<MyBoostVector>(::boost::move(*boostvectorp));
|
||||
if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
|
||||
}
|
||||
{ //Vector(Vector &&, alloc)
|
||||
::boost::movelib::unique_ptr<MyStdVector> const stdvectorp =
|
||||
::boost::movelib::make_unique<MyStdVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp =
|
||||
::boost::movelib::make_unique<MyBoostVector>(100u);
|
||||
::boost::movelib::unique_ptr<MyBoostVector> const boostvectorp2 =
|
||||
::boost::movelib::make_unique<MyBoostVector>
|
||||
(::boost::move(*boostvectorp), typename MyBoostVector::allocator_type());
|
||||
if(!test::CheckEqualContainers(*boostvectorp2, *stdvectorp)) return 1;
|
||||
}
|
||||
|
||||
if (0 != vector_move_assignable_only< MyBoostVector>(dtl::bool_<boost::container::test::is_copyable<IntType>::value>()))
|
||||
return 1;
|
||||
|
||||
std::cout << std::endl << "Test OK!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user