diff options
| author | Eric Fiselier <eric@efcs.ca> | 2018-06-05 22:32:52 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2018-06-05 22:32:52 +0000 |
| commit | 8cef7fd75ac3cbeb8efb767e5ba2dcdb76bf4454 (patch) | |
| tree | 1ba50be1285e73602ab0fd69f0c89eef23062683 /libcxx/include/vector | |
| parent | a79b6b3ef0d814080680a84202570acf4425ee12 (diff) | |
| download | bcm5719-llvm-8cef7fd75ac3cbeb8efb767e5ba2dcdb76bf4454.tar.gz bcm5719-llvm-8cef7fd75ac3cbeb8efb767e5ba2dcdb76bf4454.zip | |
Fix PR37694 - std::vector doesn't correctly move construct allocators.
C++2a[container.requirements.general]p8 states that when move constructing
a container, the allocator is move constructed. Vector previously copy
constructed these allocators. This patch fixes that bug.
Additionally it cleans up some unnecessary allocator conversions
when copy constructing containers. Libc++ uses
__internal_allocator_traits::select_on_copy_construction to select
the correct allocator during copy construction, but it unnecessarily
converted the resulting allocator to the user specified allocator
type and back. After this patch list and forward_list no longer
do that.
Technically we're supposed to be using allocator_traits<allocator_type>::select_on_copy_construction,
but that should seemingly be addressed as a separate patch, if at all.
llvm-svn: 334053
Diffstat (limited to 'libcxx/include/vector')
| -rw-r--r-- | libcxx/include/vector | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/libcxx/include/vector b/libcxx/include/vector index 9e399bdd1f4..74c423ef224 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -355,6 +355,9 @@ protected: __vector_base() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a); +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY __vector_base(allocator_type&& __a) _NOEXCEPT; +#endif ~__vector_base(); _LIBCPP_INLINE_VISIBILITY @@ -438,6 +441,15 @@ __vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a) { } +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +__vector_base<_Tp, _Allocator>::__vector_base(allocator_type&& __a) _NOEXCEPT + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr, std::move(__a)) {} +#endif + template <class _Tp, class _Allocator> __vector_base<_Tp, _Allocator>::~__vector_base() { @@ -2863,17 +2875,15 @@ vector<bool, _Allocator>::operator=(const vector& __v) #ifndef _LIBCPP_CXX03_LANG template <class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -vector<bool, _Allocator>::vector(vector&& __v) +inline _LIBCPP_INLINE_VISIBILITY vector<bool, _Allocator>::vector(vector&& __v) #if _LIBCPP_STD_VER > 14 - _NOEXCEPT + _NOEXCEPT #else - _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) + _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) #endif : __begin_(__v.__begin_), __size_(__v.__size_), - __cap_alloc_(__v.__cap_alloc_) -{ + __cap_alloc_(std::move(__v.__cap_alloc_)) { __v.__begin_ = nullptr; __v.__size_ = 0; __v.__cap() = 0; |

