This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: std::vector allocator-extended move constructor
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 15 Nov 2013 12:17:18 +0000
- Subject: Re: std::vector allocator-extended move constructor
- Authentication-results: sourceware.org; auth=none
- References: <CAH6eHdRu84qSkX54PjTuoWAJoNdkfaWjQ9A0wzW2-C7vh0xehw at mail dot gmail dot com>
On 15 November 2013 12:11, Jonathan Wakely wrote:
> I'm finishing allocator support for <map> and <set> and noticed a
> problem in std::vector:
>
> /// Move constructor with alternative allocator
> vector(vector&& __rv, const allocator_type& __m)
> : _Base(std::move(__rv), __m)
> {
> if (__rv.get_allocator() != __m)
> {
> this->_M_impl._M_finish =
> std::__uninitialized_move_a(__rv.begin(), __rv.end(),
> this->_M_impl._M_start,
> _M_get_Tp_allocator());
> __rv.clear();
> }
> }
>
> The good news is that if all instances of the allocator type compare
> equal then the _Base will just move some pointers, so we can have a
> conditional noexcept:
> noexcept(_Alloc_traits::_S_always_equal())
>
> The bad news is that it's not currently exception-safe. I should have
> used __uninitialized_copy_a there. If moving any element throws an
> exception then we leak any already-moved elements.
Correction, we don't leak, as __uninitialized_copy_a will destroy
them, but we do modify the __rv object, so we don't have the strong
guarantee. I'm not sure if that constructor is supposed to provide
the strong guarantee or not.