commit 2de95f71039003d692934065799fd3fc66155d2f Author: Jonathan Wakely Date: Wed Jun 17 16:48:59 2015 +0100 * 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. diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index d611ade..57c2d7b 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())) @@ -435,13 +435,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @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 1e1a02e..472020c 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 d22c22f..2b42a3f 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 295c4a5..ab7ed04 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)