diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a5f63837cb6..53a7387150f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,31 @@ +2009-11-13 Paolo Carlini + + * include/bits/forward_list.h (forward_list<>::erase_after): + Change signature per N2988, return void; simplify. + (_Fwd_list_base<>::_M_erase_after): Likewise return void. + (forward_list<>::~forward_list): Do not call _M_erase_after + unnecessarily, the base class destructor already does it. + (forward_list<>::splice_after(const_iterator position, + forward_list&&, const_iterator i): Check position != i and + position != ++i. + * include/bits/forward_list.tcc (_Fwd_list_base<>:: + _M_erase_after(typename _Node_base::_Pointer): Simplify. + (_Fwd_list_base<>::_M_erase_after(typename _Node_base::_Pointer, + typename _Node_base::_Pointer): Fix (remove the correct range + of element) and simplify (update __pos->_M_next at the end). + * testsuite/23_containers/forward_list/modifiers/3.cc: Adjust + and extend. + * testsuite/23_containers/forward_list/ext_pointer/ + modifiers/3.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + assign_neg.cc: Tweak dg-error line numbers. + * testsuite/23_containers/forward_list/requirements/dr438/ + insert_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_2_neg.cc: Likewise. + 2009-11-13 Paolo Carlini * include/std/algorithm: Include , per UK-300. diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 0ec5a1141a9..409c93e031c 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -350,10 +350,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _M_put_node(typename _Node::_Pointer __p) { _M_get_Node_allocator().deallocate(__p, 1); } - typename _Node_base::_Pointer + void _M_erase_after(typename _Node_base::_Pointer __pos); - typename _Node_base::_Pointer + void _M_erase_after(typename _Node_base::_Pointer __pos, typename _Node_base::_Pointer __last); }; @@ -529,7 +529,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @brief The forward_list dtor. */ ~forward_list() - { _M_erase_after(&this->_M_impl._M_head, 0); } + { } /** * @brief The %forward_list assignment operator. @@ -871,7 +871,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) insert_after(const_iterator __pos, size_type __n, const _Tp& __val) { forward_list __tmp(__n, __val, this->get_allocator()); - this->splice_after(__pos, std::move(__tmp)); + splice_after(__pos, std::move(__tmp)); } /** @@ -893,7 +893,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _InputIterator __first, _InputIterator __last) { forward_list __tmp(__first, __last, this->get_allocator()); - this->splice_after(__pos, std::move(__tmp)); + splice_after(__pos, std::move(__tmp)); } /** @@ -913,14 +913,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) { forward_list __tmp(__il, this->get_allocator()); - this->splice_after(__pos, std::move(__tmp)); + splice_after(__pos, std::move(__tmp)); } /** * @brief Removes the element pointed to by the iterator following * @c pos. - * @param pos Iterator pointing to element to be erased. - * @return An iterator pointing to the next element (or end()). + * @param pos Iterator pointing before element to be erased. * * This function will erase the element at the given position and * thus shorten the %forward_list by one. @@ -932,14 +931,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ - iterator + void erase_after(const_iterator __pos) { _Node_base* __tmp = __const_pointer_cast<_Node_base*>(__pos._M_node); - if (__tmp) - return iterator(this->_M_erase_after(__tmp)); - else - return end(); + this->_M_erase_after(__tmp); } /** @@ -948,8 +944,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * erased. * @param last Iterator pointing to one past the last element to be * erased. - * @return An iterator pointing to the element pointed to by @a last - * prior to erasing (or end()). * * This function will erase the elements in the range @a * (pos,last) and shorten the %forward_list accordingly. @@ -961,11 +955,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ - iterator - erase_after(const_iterator __pos, iterator __last) + void + erase_after(const_iterator __pos, const_iterator __last) { - _Node_base* __tmp = __const_pointer_cast<_Node_base*>(__pos._M_node); - return iterator(this->_M_erase_after(__tmp, &*__last._M_node)); + _Node_base* __tmpp = __const_pointer_cast<_Node_base*>(__pos._M_node); + _Node_base* __tmpl = __const_pointer_cast<_Node_base*>(__last._M_node); + this->_M_erase_after(__tmpp, __tmpl); } /** @@ -1044,7 +1039,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @brief Insert element from another %forward_list. * @param pos Iterator referencing the element to insert after. * @param list Source list. - * @param it Iterator referencing the element before the element + * @param i Iterator referencing the element before the element * to move. * * Removes the element in list @a list referenced by @a i and @@ -1052,10 +1047,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ void splice_after(const_iterator __pos, forward_list&& __list, - const_iterator __it) + const_iterator __i) { - this->splice_after(__pos, std::forward(__list), - __it, __it._M_next()); + const_iterator __j = __i; + ++__j; + if (__pos == __i || __pos == __j) + return; + + splice_after(__pos, std::move(__list), __i, __j); } /** diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index 13573699061..1575cabf1f2 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -113,42 +113,34 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } template - typename _Fwd_list_base<_Tp, _Alloc>::_Node_base::_Pointer + void _Fwd_list_base<_Tp, _Alloc>:: _M_erase_after(typename _Node_base::_Pointer __pos) { - typename _Node::_Pointer __curr + typename _Node::_Pointer __curr = __static_pointer_cast(__pos->_M_next); - if (__curr) - { - typename _Node_base::_Pointer __next = __curr->_M_next; - __pos->_M_next = __next; - _M_get_Node_allocator().destroy(__curr); - _M_put_node(__curr); - } - return __pos; + __pos->_M_next = __curr->_M_next; + _M_get_Node_allocator().destroy(__curr); + _M_put_node(__curr); } template - typename _Fwd_list_base<_Tp, _Alloc>::_Node_base::_Pointer + void _Fwd_list_base<_Tp, _Alloc>:: _M_erase_after(typename _Node_base::_Pointer __pos, typename _Node_base::_Pointer __last) { typename _Node::_Pointer __curr = __static_pointer_cast(__pos->_M_next); - while (__curr) + while (__curr != __last) { typename _Node::_Pointer __temp = __curr; __curr = __static_pointer_cast (__curr->_M_next); _M_get_Node_allocator().destroy(__temp); _M_put_node(__temp); - __pos->_M_next = __curr; - if (__temp == __last) - break; } - return __pos; + __pos->_M_next = __last; } // Called by the range constructor to implement [23.1.1]/9 diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/modifiers/3.cc b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/modifiers/3.cc index e27c3d78983..5b43bbb95f9 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/modifiers/3.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/ext_pointer/modifiers/3.cc @@ -43,10 +43,7 @@ test01() ++pos; VERIFY(*pos == 1); - std::forward_list >::iterator - next = fl.erase_after(pos); - - VERIFY(*next == 1); + fl.erase_after(pos); VERIFY(*pos == 1); ++pos; @@ -78,14 +75,20 @@ test02() ++stop; VERIFY(*stop == 4); - std::forward_list >::iterator - next = fl.erase_after(pos, stop); - - VERIFY(*next == 1); + fl.erase_after(pos, stop); VERIFY(*pos == 1); ++pos; - VERIFY(*pos == 5); + VERIFY(*pos == 4); + VERIFY(std::distance(fl.begin(), fl.end()) == 8); + + fl.erase_after(pos, fl.end()); + VERIFY(++pos == fl.end()); + VERIFY(std::distance(fl.begin(), fl.end()) == 3); + + fl.erase_after(fl.before_begin(), pos); + VERIFY(std::distance(fl.begin(), fl.end()) == 0); + VERIFY(fl.empty()); } int diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/3.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/3.cc index f15fae1d21b..69163e06e8d 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/3.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/3.cc @@ -37,8 +37,7 @@ test01() ++pos; VERIFY(*pos == 1); - std::forward_list::iterator next = fl.erase_after(pos); - VERIFY(*next == 1); + fl.erase_after(pos); VERIFY(*pos == 1); ++pos; @@ -65,12 +64,20 @@ test02() ++stop; VERIFY(*stop == 4); - std::forward_list::iterator next = fl.erase_after(pos, stop); - VERIFY(*next == 1); + fl.erase_after(pos, stop); VERIFY(*pos == 1); ++pos; - VERIFY(*pos == 5); + VERIFY(*pos == 4); + VERIFY(std::distance(fl.begin(), fl.end()) == 8); + + fl.erase_after(pos, fl.end()); + VERIFY(++pos == fl.end()); + VERIFY(std::distance(fl.begin(), fl.end()) == 3); + + fl.erase_after(fl.before_begin(), pos); + VERIFY(std::distance(fl.begin(), fl.end()) == 0); + VERIFY(fl.empty()); } int diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc index 5062ddfa234..0d167718278 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1198 } +// { dg-error "no matching" "" { target *-*-* } 1197 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc index 6347d964a46..d72b9fa4c9d 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1198 } +// { dg-error "no matching" "" { target *-*-* } 1197 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc index af668527dfb..f0481a3f453 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1198 } +// { dg-error "no matching" "" { target *-*-* } 1197 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc index bc8a62d54ab..c4a84ff38da 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1198 } +// { dg-error "no matching" "" { target *-*-* } 1197 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation