small_vector: Added copy/move constructor/assignments from small_vector_base

This commit is contained in:
Ion Gaztañaga
2015-12-24 13:46:00 +01:00
parent 75f7c8fa73
commit 641d1a5d5a
4 changed files with 61 additions and 21 deletions

View File

@@ -1215,9 +1215,11 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes_boost_1_61_00 Boost 1.61 Release] [section:release_notes_boost_1_61_00 Boost 1.61 Release]
* [classref boost::container::small_vector] supports more constructors and assignments.
* Fixed bugs: * Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/11820 Trac #11820 : ['"compilier error when using operator[] of map"]]. * [@https://svn.boost.org/trac/boost/ticket/11820 Trac #11820 : ['"compiler error when using operator[] of map"]].
* [@https://svn.boost.org/trac/boost/ticket/11856 Trac #11856 : ['"pool_resource.cpp error: declaration changes meaning"]]. * [@https://svn.boost.org/trac/boost/ticket/11856 Trac #11856 : ['"pool_resource.cpp error: declaration changes meaning"]].
* [@https://svn.boost.org/trac/boost/ticket/11867 Trac #11867 : ['"small_vector should have constructor and assignment operator taking other small_vector"]].
* [@https://github.com/boostorg/container/pull/33 GitHub #33: ['Make sure std::string constructor is available]]. * [@https://github.com/boostorg/container/pull/33 GitHub #33: ['Make sure std::string constructor is available]].
[endsect] [endsect]

View File

@@ -355,9 +355,6 @@ class small_vector_base
//~small_vector_base(){} //~small_vector_base(){}
using base_type::is_propagable_from;
using base_type::steal_resources;
private: private:
//The only member //The only member
storage_type m_storage_start; storage_type m_storage_start;
@@ -373,6 +370,21 @@ class small_vector_base
BOOST_CONTAINER_FORCEINLINE void swap(small_vector_base &other) BOOST_CONTAINER_FORCEINLINE void swap(small_vector_base &other)
{ return this->base_type::swap(other); } { return this->base_type::swap(other); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
protected:
void move_construct_impl(base_type &x, const allocator_type &a)
{
if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
this->steal_resources(x);
}
else{
this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ()))
);
}
}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}; };
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -508,6 +520,15 @@ class small_vector : public small_vector_base<T, Allocator>
: base_type(initial_capacity_t(), internal_capacity(), a) : base_type(initial_capacity_t(), internal_capacity(), a)
{ this->assign(other.cbegin(), other.cend()); } { this->assign(other.cbegin(), other.cend()); }
explicit small_vector(const base_type &other)
: base_type( initial_capacity_t(), internal_capacity()
, allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
{ this->assign(other.cbegin(), other.cend()); }
explicit small_vector(BOOST_RV_REF(base_type) other)
: base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
{ this->move_construct_impl(other, other.get_stored_allocator()); }
small_vector(BOOST_RV_REF(small_vector) other) small_vector(BOOST_RV_REF(small_vector) other)
: base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator())) : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
{ this->move_construct_impl(other, other.get_stored_allocator()); } { this->move_construct_impl(other, other.get_stored_allocator()); }
@@ -530,23 +551,14 @@ class small_vector : public small_vector_base<T, Allocator>
BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(small_vector) other) BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(small_vector) other)
{ return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); } { return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
BOOST_CONTAINER_FORCEINLINE small_vector& operator=(const base_type &other)
{ return static_cast<small_vector&>(this->base_type::operator=(other)); }
BOOST_CONTAINER_FORCEINLINE small_vector& operator=(BOOST_RV_REF(base_type) other)
{ return static_cast<small_vector&>(this->base_type::operator=(boost::move(other))); }
BOOST_CONTAINER_FORCEINLINE void swap(small_vector &other) BOOST_CONTAINER_FORCEINLINE void swap(small_vector &other)
{ return this->base_type::swap(other); } { return this->base_type::swap(other); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
void move_construct_impl(small_vector &x, const allocator_type &a)
{
if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
this->steal_resources(x);
}
else{
this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
, boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ()))
);
}
}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}; };
}} }}

View File

@@ -88,7 +88,7 @@ class alloc_propagate_wrapper
{} {}
alloc_propagate_wrapper &operator=(BOOST_COPY_ASSIGN_REF(alloc_propagate_wrapper) x) alloc_propagate_wrapper &operator=(BOOST_COPY_ASSIGN_REF(alloc_propagate_wrapper) x)
{ this->Base::operator=(x); return *this; } { this->Base::operator=((const Base &)x); return *this; }
alloc_propagate_wrapper &operator=(BOOST_RV_REF(alloc_propagate_wrapper) x) alloc_propagate_wrapper &operator=(BOOST_RV_REF(alloc_propagate_wrapper) x)
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; } { this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }

View File

@@ -96,7 +96,7 @@ bool test_small_vector_base_test()
return false; return false;
} }
{ {
typedef boost::container::small_vector<int, 5> sm7_t; typedef boost::container::small_vector<int, 7> sm7_t;
sm7_t sm7; sm7_t sm7;
smb_t &smb = sm7; smb_t &smb = sm7;
smb.push_back(2); smb.push_back(2);
@@ -105,6 +105,32 @@ bool test_small_vector_base_test()
if (!boost::container::test::CheckEqualContainers(sm7, smb)) if (!boost::container::test::CheckEqualContainers(sm7, smb))
return false; return false;
} }
{
typedef boost::container::small_vector<int, 5> sm5_t;
sm5_t sm5;
smb_t &smb = sm5;
smb.push_back(1);
sm5_t sm5_copy(smb);
if (!boost::container::test::CheckEqualContainers(sm5, sm5_copy))
return false;
smb.push_back(2);
if(smb.size() != 2){
return false;
}
sm5_copy = smb;
if (!boost::container::test::CheckEqualContainers(sm5, sm5_copy))
return false;
sm5_t sm5_move(boost::move(smb));
smb.clear();
if (!boost::container::test::CheckEqualContainers(sm5_move, sm5_copy))
return false;
smb = sm5_copy;
sm5_move = boost::move(smb);
smb.clear();
if (!boost::container::test::CheckEqualContainers(sm5_move, sm5_copy))
return false;
}
return true; return true;
} }