mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-20 22:10:03 +08:00
[libc++] Revert "Make vector
unconditionally move elements when exceptions are disabled."
This reverts r370502, which broke the use case of a copy-only T (with a deleted move constructor) when exceptions are disabled. Until we figure out the right behavior, I'm reverting the commit. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@371068 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1609,16 +1609,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
__construct_forward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
|
__construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
|
||||||
{
|
{
|
||||||
for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
|
for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
|
||||||
construct(__a, _VSTD::__to_raw_pointer(__begin2),
|
construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));
|
||||||
#ifdef _LIBCPP_NO_EXCEPTIONS
|
|
||||||
_VSTD::move(*__begin1)
|
|
||||||
#else
|
|
||||||
_VSTD::move_if_noexcept(*__begin1)
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
@@ -1631,7 +1625,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
|
|||||||
is_trivially_move_constructible<_Tp>::value,
|
is_trivially_move_constructible<_Tp>::value,
|
||||||
void
|
void
|
||||||
>::type
|
>::type
|
||||||
__construct_forward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
|
__construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
|
||||||
{
|
{
|
||||||
ptrdiff_t _Np = __end1 - __begin1;
|
ptrdiff_t _Np = __end1 - __begin1;
|
||||||
if (_Np > 0)
|
if (_Np > 0)
|
||||||
@@ -1678,18 +1672,12 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
__construct_backward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)
|
__construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)
|
||||||
{
|
{
|
||||||
while (__end1 != __begin1)
|
while (__end1 != __begin1)
|
||||||
{
|
{
|
||||||
construct(__a, _VSTD::__to_raw_pointer(__end2 - 1),
|
construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1));
|
||||||
#ifdef _LIBCPP_NO_EXCEPTIONS
|
--__end2;
|
||||||
_VSTD::move(*--__end1)
|
|
||||||
#else
|
|
||||||
_VSTD::move_if_noexcept(*--__end1)
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
--__end2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1703,7 +1691,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
|
|||||||
is_trivially_move_constructible<_Tp>::value,
|
is_trivially_move_constructible<_Tp>::value,
|
||||||
void
|
void
|
||||||
>::type
|
>::type
|
||||||
__construct_backward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)
|
__construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)
|
||||||
{
|
{
|
||||||
ptrdiff_t _Np = __end1 - __begin1;
|
ptrdiff_t _Np = __end1 - __begin1;
|
||||||
__end2 -= _Np;
|
__end2 -= _Np;
|
||||||
|
@@ -948,8 +948,7 @@ void
|
|||||||
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
|
vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
|
||||||
{
|
{
|
||||||
__annotate_delete();
|
__annotate_delete();
|
||||||
__alloc_traits::__construct_backward_with_exception_guarantees(
|
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
|
||||||
this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
|
|
||||||
_VSTD::swap(this->__begin_, __v.__begin_);
|
_VSTD::swap(this->__begin_, __v.__begin_);
|
||||||
_VSTD::swap(this->__end_, __v.__end_);
|
_VSTD::swap(this->__end_, __v.__end_);
|
||||||
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
||||||
@@ -964,10 +963,8 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a
|
|||||||
{
|
{
|
||||||
__annotate_delete();
|
__annotate_delete();
|
||||||
pointer __r = __v.__begin_;
|
pointer __r = __v.__begin_;
|
||||||
__alloc_traits::__construct_backward_with_exception_guarantees(
|
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
|
||||||
this->__alloc(), this->__begin_, __p, __v.__begin_);
|
__alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
|
||||||
__alloc_traits::__construct_forward_with_exception_guarantees(
|
|
||||||
this->__alloc(), __p, this->__end_, __v.__end_);
|
|
||||||
_VSTD::swap(this->__begin_, __v.__begin_);
|
_VSTD::swap(this->__begin_, __v.__begin_);
|
||||||
_VSTD::swap(this->__end_, __v.__end_);
|
_VSTD::swap(this->__end_, __v.__end_);
|
||||||
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
_VSTD::swap(this->__end_cap(), __v.__end_cap());
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
// RUN: %build -fno-exceptions
|
|
||||||
// RUN: %run
|
|
||||||
|
|
||||||
// UNSUPPORTED: c++98, c++03
|
|
||||||
|
|
||||||
// <vector>
|
|
||||||
|
|
||||||
// Test that vector always moves elements when exceptions are disabled.
|
|
||||||
// vector is allowed to move or copy elements while resizing, so long as
|
|
||||||
// it still provides the strong exception safety guarantee.
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "test_macros.h"
|
|
||||||
|
|
||||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
|
||||||
#error exceptions should be disabled.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool allow_moves = false;
|
|
||||||
|
|
||||||
class A {
|
|
||||||
public:
|
|
||||||
A() {}
|
|
||||||
A(A&&) { assert(allow_moves); }
|
|
||||||
explicit A(int) {}
|
|
||||||
A(A const&) { assert(false); }
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int, char**) {
|
|
||||||
std::vector<A> v;
|
|
||||||
|
|
||||||
// Create a vector containing some number of elements that will
|
|
||||||
// have to be moved when it is resized.
|
|
||||||
v.reserve(10);
|
|
||||||
size_t old_cap = v.capacity();
|
|
||||||
for (int i = 0; i < v.capacity(); ++i) {
|
|
||||||
v.emplace_back(42);
|
|
||||||
}
|
|
||||||
assert(v.capacity() == old_cap);
|
|
||||||
assert(v.size() == v.capacity());
|
|
||||||
|
|
||||||
// The next emplace back should resize.
|
|
||||||
allow_moves = true;
|
|
||||||
v.emplace_back(42);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Reference in New Issue
Block a user