Subject: [Boost-bugs] [Boost C++ Libraries] #9916: Allocator propagation incorrect in the assignment operator of most containers
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-04-16 21:45:27
#9916: Allocator propagation incorrect in the assignment operator of most
containers
--------------------------+------------------------
Reporter: igaztanaga | Owner: igaztanaga
Type: Bugs | Status: new
Milestone: Boost 1.56.0 | Component: container
Version: Boost 1.55.0 | Severity: Problem
Keywords: |
--------------------------+------------------------
When copy or move assigning containers, the allocator is propagated
according to propagate_on_container_copy|move_assignment only if both
allocators compare equal.
This is incorrect as allocators must be propagated independently from
allocator comparison.
For move construct correct logic would be, according to H. Hinnant's
answer in StackOverflow (http://stackoverflow.com/a/12334918):
-----
C& operator=(C&& c)
If alloc_traits::propagate_on_container_move_assignment::value is
true, dumps resources, move assigns allocators, and transfers resources
from c.
If alloc_traits::propagate_on_container_move_assignment::value is
false and get_allocator() == c.get_allocator, dumps resources, and
transfers resources from c.
If alloc_traits::propagate_on_container_move_assignment::value is
false and get_allocator() != c.get_allocator, move assigns each c[i].
Notes:
When alloc_traits::propagate_on_container_move_assignment::value is
true the move assignment operator can be specified noexcept because all it
is going to is deallocate current resources and then pilfer resources from
the source. Also in this case, the allocator must also be move assigned,
and that move assignment must be noexcept for the container's move
assignment to be noexcept.
When alloc_traits::propagate_on_container_move_assignment::value is
false, and if the two allocators are equal, then it is going to do the
same thing as #1. However one doesn't know if the allocators are equal
until run time, so you can't base noexcept on this possibility.
When alloc_traits::propagate_on_container_move_assignment::value is
false, and if the two allocators are not equal, then one has to move
assign each individual element. This may involve adding capacity or nodes
to the target, and thus is intrinsically noexcept(false).
-----
For copy assignment the steps would be:
If alloc_traits::propagate_on_container_move_assignment::value is
true, and get_allocator() != c.get_allocator dumps resources, copy assigns
allocators, and assigns from [c.begin(), c.end())
If alloc_traits::propagate_on_container_move_assignment::value is true
and get_allocator() == c.get_allocator, copy assigns allocators, and
assigns from [c.begin(), c.end())
If alloc_traits::propagate_on_container_move_assignment::value is
false assigns from [c.begin(), c.end())
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/9916> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:16 UTC