diff options
author | Eric Fiselier <eric@efcs.ca> | 2019-08-30 19:01:03 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2019-08-30 19:01:03 +0000 |
commit | 2dd37a31ce14720d967cbe87b1b3a058871c9651 (patch) | |
tree | 38b3a13faa9fe90b3447e4a9a98e9e34e4751517 /libcxx/include | |
parent | 7b832322dfe60fbc39d4814c5343cea8c8bb29ee (diff) | |
download | bcm5719-llvm-2dd37a31ce14720d967cbe87b1b3a058871c9651.tar.gz bcm5719-llvm-2dd37a31ce14720d967cbe87b1b3a058871c9651.zip |
Make `vector` unconditionally move elements when exceptions are disabled.
Summary:
`std::vector<T>` is free choose between using copy or move operations when it needs to resize. The standard only candidates that the correct exception safety guarantees are provided. When exceptions are disabled these guarantees are trivially satisfied. Meaning vector is free to optimize it's implementation by moving instead of copying.
This patch makes `std::vector` unconditionally move elements when exceptions are disabled.
This optimization is conforming according to the current standard wording.
There are concerns that moving in `-fno-noexceptions`mode will be a surprise to users. For example, a user may be surprised to find their code is slower with exceptions enabled than it is disabled. I'm sympathetic to this surprised, but I don't think it should block this optimization.
Reviewers: mclow.lists, ldionne, rsmith
Reviewed By: ldionne
Subscribers: zoecarver, christof, dexonsmith, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D62228
llvm-svn: 370502
Diffstat (limited to 'libcxx/include')
-rw-r--r-- | libcxx/include/memory | 26 | ||||
-rw-r--r-- | libcxx/include/vector | 9 |
2 files changed, 25 insertions, 10 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory index 321d5fee12a..ec1f3d91403 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -1609,10 +1609,16 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits _LIBCPP_INLINE_VISIBILITY static void - __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) + __construct_forward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) - construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); + construct(__a, _VSTD::__to_raw_pointer(__begin2), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*__begin1) +#else + _VSTD::move_if_noexcept(*__begin1) +#endif + ); } template <class _Tp> @@ -1625,7 +1631,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_forward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) @@ -1672,12 +1678,18 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits _LIBCPP_INLINE_VISIBILITY static void - __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) + __construct_backward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { while (__end1 != __begin1) { - construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1)); - --__end2; + construct(__a, _VSTD::__to_raw_pointer(__end2 - 1), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*--__end1) +#else + _VSTD::move_if_noexcept(*--__end1) +#endif + ); + --__end2; } } @@ -1691,7 +1703,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) + __construct_backward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { ptrdiff_t _Np = __end1 - __begin1; __end2 -= _Np; diff --git a/libcxx/include/vector b/libcxx/include/vector index 2d83484aa20..a07243a1345 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -948,7 +948,8 @@ void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) { __annotate_delete(); - __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); + __alloc_traits::__construct_backward_with_exception_guarantees( + this->__alloc(), this->__begin_, this->__end_, __v.__begin_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -963,8 +964,10 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a { __annotate_delete(); pointer __r = __v.__begin_; - __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_); - __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_); + __alloc_traits::__construct_backward_with_exception_guarantees( + this->__alloc(), this->__begin_, __p, __v.__begin_); + __alloc_traits::__construct_forward_with_exception_guarantees( + this->__alloc(), __p, this->__end_, __v.__end_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); |