summaryrefslogtreecommitdiffstats
path: root/libcxx/include/vector
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-06-05 22:32:52 +0000
committerEric Fiselier <eric@efcs.ca>2018-06-05 22:32:52 +0000
commit8cef7fd75ac3cbeb8efb767e5ba2dcdb76bf4454 (patch)
tree1ba50be1285e73602ab0fd69f0c89eef23062683 /libcxx/include/vector
parenta79b6b3ef0d814080680a84202570acf4425ee12 (diff)
downloadbcm5719-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/vector22
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;
OpenPOWER on IntegriCloud