summaryrefslogtreecommitdiffstats
path: root/libcxx/include/forward_list
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/forward_list
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/forward_list')
-rw-r--r--libcxx/include/forward_list19
1 files changed, 11 insertions, 8 deletions
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index c98ddc00a03..571afdc925b 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -457,6 +457,10 @@ protected:
typedef typename allocator_traits<__begin_node_allocator>::pointer
__begin_node_pointer;
+ static_assert((!is_same<allocator_type, __node_allocator>::value),
+ "internal allocator type must differ from user-specified "
+ "type; otherwise overload resolution breaks");
+
__compressed_pair<__begin_node, __node_allocator> __before_begin_;
_LIBCPP_INLINE_VISIBILITY
@@ -481,9 +485,11 @@ protected:
_NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
: __before_begin_(__begin_node()) {}
_LIBCPP_INLINE_VISIBILITY
- __forward_list_base(const allocator_type& __a)
+ explicit __forward_list_base(const allocator_type& __a)
: __before_begin_(__begin_node(), __node_allocator(__a)) {}
-
+ _LIBCPP_INLINE_VISIBILITY
+ explicit __forward_list_base(const __node_allocator& __a)
+ : __before_begin_(__begin_node(), __a) {}
#ifndef _LIBCPP_CXX03_LANG
public:
_LIBCPP_INLINE_VISIBILITY
@@ -954,12 +960,9 @@ forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
template <class _Tp, class _Alloc>
forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
- : base(allocator_type(
- __node_traits::select_on_container_copy_construction(__x.__alloc())
- )
- )
-{
- insert_after(cbefore_begin(), __x.begin(), __x.end());
+ : base(
+ __node_traits::select_on_container_copy_construction(__x.__alloc())) {
+ insert_after(cbefore_begin(), __x.begin(), __x.end());
}
template <class _Tp, class _Alloc>
OpenPOWER on IntegriCloud