From 21bdef94b1e8c178e932cb5b560726c2c8c00323 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 17 Jun 2015 18:45:45 +0100 Subject: [PATCH] forward_list.h (_Fwd_list_base(const _Node_alloc_type&)): Change parameter to rvalue-reference. * include/bits/forward_list.h (_Fwd_list_base(const _Node_alloc_type&)): Change parameter to rvalue-reference. (_Fwd_list_base(_Fwd_list_base&&, const _Node_alloc_type&)): Likewise. (forward_list(const _Alloc&)): Split default constructor out to separate function. (forward_list(forward_list&&, const _Alloc&)): Move elements if base class didn't do so. (forward_list::_M_move_assign(forward_list&&, true_type)): Replace swap call with two assignments. * include/bits/forward_list.tcc (_Fwd_list_base(_Fwd_list_base&&, const _Node_alloc_type&)): Don't move elements when allocators are not equal. * include/debug/forward_list (forward_list(const allocator_type&)): Split default constructor out to separate function. * include/profile/forward_list (forward_list(const _Alloc&)): Likewise. From-SVN: r224566 --- libstdc++-v3/ChangeLog | 18 ++++++++++++++ libstdc++-v3/include/bits/forward_list.h | 29 ++++++++++++++++------ libstdc++-v3/include/bits/forward_list.tcc | 20 +++------------ libstdc++-v3/include/debug/forward_list | 5 +++- libstdc++-v3/include/profile/forward_list | 5 +++- 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 250728c85eb..ea0a60d4b9e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,23 @@ 2015-06-17 Jonathan Wakely + * include/bits/forward_list.h + (_Fwd_list_base(const _Node_alloc_type&)): Change parameter to + rvalue-reference. + (_Fwd_list_base(_Fwd_list_base&&, const _Node_alloc_type&)): Likewise. + (forward_list(const _Alloc&)): Split default constructor out to + separate function. + (forward_list(forward_list&&, const _Alloc&)): Move elements if base + class didn't do so. + (forward_list::_M_move_assign(forward_list&&, true_type)): Replace + swap call with two assignments. + * include/bits/forward_list.tcc + (_Fwd_list_base(_Fwd_list_base&&, const _Node_alloc_type&)): Don't + move elements when allocators are not equal. + * include/debug/forward_list (forward_list(const allocator_type&)): + Split default constructor out to separate function. + * include/profile/forward_list (forward_list(const _Alloc&)): + Likewise. + * include/bits/forward_list.h (forward_list::_M_get_Node_allocator): Remove unnecessary uses of operator& and static_cast. * include/bits/forward_list.tcc diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index d611aded80e..57c2d7bbfbb 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -314,10 +314,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Fwd_list_base() : _M_impl() { } - _Fwd_list_base(const _Node_alloc_type& __a) - : _M_impl(__a) { } + _Fwd_list_base(_Node_alloc_type&& __a) + : _M_impl(std::move(__a)) { } - _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a); + _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a); _Fwd_list_base(_Fwd_list_base&& __lst) : _M_impl(std::move(__lst._M_get_Node_allocator())) @@ -433,15 +433,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // 23.3.4.2 construct/copy/destroy: + /** + * @brief Creates a %forward_list with no elements. + */ + forward_list() + noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value) + : _Base() + { } + /** * @brief Creates a %forward_list with no elements. * @param __al An allocator object. */ explicit - forward_list(const _Alloc& __al = _Alloc()) + forward_list(const _Alloc& __al) noexcept : _Base(_Node_alloc_type(__al)) { } + /** * @brief Copy constructor with allocator argument. * @param __list Input list to copy. @@ -459,7 +468,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER forward_list(forward_list&& __list, const _Alloc& __al) noexcept(_Node_alloc_traits::_S_always_equal()) : _Base(std::move(__list), _Node_alloc_type(__al)) - { } + { + // If __list is not empty it means its allocator is not equal to __a, + // so we need to move from each element individually. + insert_after(cbefore_begin(), + std::__make_move_if_noexcept_iterator(__list.begin()), + std::__make_move_if_noexcept_iterator(__list.end())); + } /** * @brief Creates a %forward_list with default constructed elements. @@ -1248,8 +1263,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_move_assign(forward_list&& __list, std::true_type) noexcept { clear(); - std::swap(this->_M_impl._M_head._M_next, - __list._M_impl._M_head._M_next); + this->_M_impl._M_head._M_next = __list._M_impl._M_head._M_next; + __list._M_impl._M_head._M_next = nullptr; std::__alloc_on_move(this->_M_get_Node_allocator(), __list._M_get_Node_allocator()); } diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index 1e1a02e1d02..472020c0db5 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -36,28 +36,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template _Fwd_list_base<_Tp, _Alloc>:: - _Fwd_list_base(_Fwd_list_base&& __lst, const _Node_alloc_type& __a) - : _M_impl(__a) + _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a) + : _M_impl(std::move(__a)) { - if (__lst._M_get_Node_allocator() == __a) + if (__lst._M_get_Node_allocator() == _M_get_Node_allocator()) { this->_M_impl._M_head._M_next = __lst._M_impl._M_head._M_next; __lst._M_impl._M_head._M_next = 0; } else - { - this->_M_impl._M_head._M_next = 0; - _Fwd_list_node_base* __to = &this->_M_impl._M_head; - _Node* __curr = static_cast<_Node*>(__lst._M_impl._M_head._M_next); - - while (__curr) - { - __to->_M_next = - _M_create_node(std::move_if_noexcept(*__curr->_M_valptr())); - __to = __to->_M_next; - __curr = static_cast<_Node*>(__curr->_M_next); - } - } + this->_M_impl._M_head._M_next = 0; } template diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index d22c22fae41..2b42a3f8d29 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -204,8 +204,11 @@ namespace __debug typedef typename _Base::const_pointer const_pointer; // 23.2.3.1 construct/copy/destroy: + + forward_list() = default; + explicit - forward_list(const allocator_type& __al = allocator_type()) + forward_list(const allocator_type& __al) noexcept : _Base(__al) { } forward_list(const forward_list& __list, const allocator_type& __al) diff --git a/libstdc++-v3/include/profile/forward_list b/libstdc++-v3/include/profile/forward_list index 295c4a5bde6..ab7ed04b75a 100644 --- a/libstdc++-v3/include/profile/forward_list +++ b/libstdc++-v3/include/profile/forward_list @@ -51,8 +51,11 @@ namespace __profile typedef typename _Base::const_iterator const_iterator; // 23.2.3.1 construct/copy/destroy: + + forward_list() = default; + explicit - forward_list(const _Alloc& __al = _Alloc()) + forward_list(const _Alloc& __al) noexcept : _Base(__al) { } forward_list(const forward_list& __list, const _Alloc& __al) -- 2.30.2