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/forward_list | |
| 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/forward_list')
| -rw-r--r-- | libcxx/include/forward_list | 19 |
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> |

