Fixed #9916: "Allocator propagation incorrect in the assignment operator of most".

Fixed #9932: "Missing assignment operator from related static_vector".
Added missing details from issue #9915
This commit is contained in:
Ion Gaztañaga committed 2014-04-21 13:59:49 +02:00
1 parent bffd6c036c
commit 0b720f82b4
16 files changed
+372 -283

No files matched your search

+30 -26
View File
@@ -542,7 +542,7 @@ class deque : protected deque_base<Allocator>
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor
//! throws or T's value initialization or copy constructor throws.
//! throws or T's value initialization throws.
//!
//! <b>Complexity</b>: Linear to n.
explicit deque(size_type n)
@@ -704,35 +704,39 @@ class deque : protected deque_base<Allocator>
return *this;
}
//! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
//!
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
//! before the function.
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
//! is false and (allocation throws or value_type's move constructor throws)
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Linear.
//! <b>Complexity</b>: Constant if allocator_traits_type::
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
deque& operator= (BOOST_RV_REF(deque) x)
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment)
{
if (&x != this){
allocator_type &this_alloc = this->alloc();
allocator_type &x_alloc = x.alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
this->swap_members(x);
//Move allocator if needed
container_detail::bool_<allocator_traits_type::
propagate_on_container_move_assignment::value> flag;
container_detail::move_alloc(this_alloc, x_alloc, flag);
container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
}
//If unequal allocators, then do a one by one move
else{
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
BOOST_ASSERT(this != &x);
allocator_type &this_alloc = this->alloc();
allocator_type &x_alloc = x.alloc();
const bool propagate_alloc = allocator_traits_type::
propagate_on_container_move_assignment::value;
container_detail::bool_<propagate_alloc> flag;
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
//Resources can be transferred if both allocators are
//going to be equal after this function (either propagated or already equal)
if(propagate_alloc || allocators_equal){
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
//Move allocator if needed
container_detail::move_alloc(this_alloc, x_alloc, flag);
container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
//Nothrow swap
this->swap_members(x);
}
//Else do a one by one move
else{
this->assign( boost::make_move_iterator(x.begin())
, boost::make_move_iterator(x.end()));
}
return *this;
}