Patchwork [v3] Update forward_list::erase_after to return an iterator

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 17, 2010, 5:35 p.m.
Message ID <4CBB33FA.8040106@oracle.com>
Download mbox | patch
Permalink /patch/68087/
State New
Headers show

Comments

Paolo Carlini - Oct. 17, 2010, 5:35 p.m.
Hi,

tested x86_64-linux (check and check-debug), committed.

Paolo.

//////////////////////
2010-10-17  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/bits/forward_list.h (forward_list<>::erase_after): Return
	an iterator.
	(_M_erase_after): Return _Fwd_list_node_base*.
	* include/bits/forward_list.tcc: Likewise.
	* include/debug/forward_list: Likewise.
	* testsuite/23_containers/forward_list/modifiers/3.cc: Update
	and extend.
	* testsuite/util/exception/safety.h (erase_base<forward_list<>>):
	Adjust.
	* testsuite/23_containers/forward_list/requirements/dr438/
	assign_neg.cc: Adjust dg-error line number.
	* 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.

Patch

Index: include/debug/forward_list
===================================================================
--- include/debug/forward_list	(revision 165577)
+++ include/debug/forward_list	(working copy)
@@ -288,26 +288,27 @@ 
 	return iterator(_Base::insert_after(__pos.base(), __il), this);
       }
 
-      void
+      iterator
       erase_after(const_iterator __pos)
       {
 	__glibcxx_check_erase_after(__pos);
 	const_iterator __victim = __pos;
 	++__victim;
 	__victim._M_invalidate();
-	_Base::erase_after(__pos.base());
+	return iterator(_Base::erase_after(__pos.base()), this);
       }
 
-      void
+      iterator
       erase_after(const_iterator __pos, const_iterator __last)
       {
 	__glibcxx_check_erase_range_after(__pos, __last);
 	for (const_iterator __victim = std::next(__pos); __victim != __last; )
 	  {
-	    const_iterator __old = __victim++;
+	    const_iterator __old = __victim;
+	    ++__victim;
 	    __old._M_invalidate();
 	  }
-	_Base::erase_after(__pos.base(), __last.base());
+	return iterator(_Base::erase_after(__pos.base(), __last.base()), this);
       }
 
       void
Index: include/bits/forward_list.h
===================================================================
--- include/bits/forward_list.h	(revision 165577)
+++ include/bits/forward_list.h	(working copy)
@@ -364,10 +364,10 @@ 
       _M_put_node(_Node* __p)
       { _M_get_Node_allocator().deallocate(__p, 1); }
 
-      void
+      _Fwd_list_node_base*
       _M_erase_after(_Fwd_list_node_base* __pos);
 
-      void
+      _Fwd_list_node_base*
       _M_erase_after(_Fwd_list_node_base* __pos, 
                      _Fwd_list_node_base* __last);
     };
@@ -924,6 +924,8 @@ 
        *  @brief  Removes the element pointed to by the iterator following
        *          @c pos.
        *  @param  pos  Iterator pointing before element to be erased.
+       *  @return  An iterator pointing to the element following the one
+       *           that was erased, or end() if no such element exists.
        *
        *  This function will erase the element at the given position and
        *  thus shorten the %forward_list by one.
@@ -935,9 +937,10 @@ 
        *  is itself a pointer, the pointed-to memory is not touched in
        *  any way.  Managing the pointer is the user's responsibility.
        */
-      void
+      iterator
       erase_after(const_iterator __pos)
-      { this->_M_erase_after(const_cast<_Node_base*>(__pos._M_node)); }
+      { return iterator(this->_M_erase_after(const_cast<_Node_base*>
+					     (__pos._M_node))); }
 
       /**
        *  @brief  Remove a range of elements.
@@ -945,6 +948,7 @@ 
        *               erased.
        *  @param  last  Iterator pointing to one past the last element to be
        *                erased.
+       *  @return  @last.
        *
        *  This function will erase the elements in the range @a
        *  (pos,last) and shorten the %forward_list accordingly.
@@ -956,10 +960,12 @@ 
        *  pointed-to memory is not touched in any way.  Managing the pointer
        *  is the user's responsibility.
        */
-      void
+      iterator
       erase_after(const_iterator __pos, const_iterator __last)
-      { this->_M_erase_after(const_cast<_Node_base*>(__pos._M_node),
-			     const_cast<_Node_base*>(__last._M_node)); }
+      { return iterator(this->_M_erase_after(const_cast<_Node_base*>
+					     (__pos._M_node),
+					     const_cast<_Node_base*>
+					     (__last._M_node))); }
 
       /**
        *  @brief  Swaps data with another %forward_list.
Index: include/bits/forward_list.tcc
===================================================================
--- include/bits/forward_list.tcc	(revision 165577)
+++ include/bits/forward_list.tcc	(working copy)
@@ -63,7 +63,7 @@ 
       }
 
   template<typename _Tp, typename _Alloc>
-    void
+    _Fwd_list_node_base*
     _Fwd_list_base<_Tp, _Alloc>::
     _M_erase_after(_Fwd_list_node_base* __pos)
     {
@@ -71,10 +71,11 @@ 
       __pos->_M_next = __curr->_M_next;
       _M_get_Node_allocator().destroy(__curr);
       _M_put_node(__curr);
+      return __pos->_M_next;
     }
 
   template<typename _Tp, typename _Alloc>
-    void
+    _Fwd_list_node_base*
     _Fwd_list_base<_Tp, _Alloc>::
     _M_erase_after(_Fwd_list_node_base* __pos, 
                    _Fwd_list_node_base* __last)
@@ -88,8 +89,9 @@ 
           _M_put_node(__temp);
         }
       __pos->_M_next = __last;
+      return __last;
     }
-  
+
   // Called by the range constructor to implement [23.1.1]/9
   template<typename _Tp, typename _Alloc>
     template<typename _InputIterator>
Index: testsuite/23_containers/forward_list/modifiers/3.cc
===================================================================
--- testsuite/23_containers/forward_list/modifiers/3.cc	(revision 165577)
+++ testsuite/23_containers/forward_list/modifiers/3.cc	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-options "-std=gnu++0x" }
 
-// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -22,8 +22,6 @@ 
 #include <forward_list>
 #include <testsuite_hooks.h>
 
-bool test __attribute__((unused)) = true;
-
 // This test verifies the following:
 //   cbegin
 //   erase_after one iterator
@@ -31,17 +29,20 @@ 
 void
 test01()
 {
+  bool test __attribute__((unused)) = true;
+
   std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
 
   std::forward_list<int>::const_iterator pos = fl.cbegin();
   ++pos;
-  VERIFY(*pos == 1);
+  VERIFY( *pos == 1 );
 
-  fl.erase_after(pos);
+  std::forward_list<int>::iterator pos2 = fl.erase_after(pos);
 
-  VERIFY(*pos == 1);
+  VERIFY( *pos == 1 );
   ++pos;
-  VERIFY(*pos == 3);
+  VERIFY( *pos == 3 );
+  VERIFY( pos == pos2 );
 }
 
 // This test verifies the following:
@@ -51,33 +52,40 @@ 
 void
 test02()
 {
+  bool test __attribute__((unused)) = true;
+
   std::forward_list<int> fl({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
 
   std::forward_list<int>::const_iterator pos = fl.cbegin();
   ++pos;
-  VERIFY(*pos == 1);
+  VERIFY( *pos == 1 );
 
   std::forward_list<int>::iterator stop = fl.begin();
   ++stop;
   ++stop;
   ++stop;
   ++stop;
-  VERIFY(*stop == 4);
+  VERIFY( *stop == 4 );
 
-  fl.erase_after(pos, stop);
+  std::forward_list<int>::iterator pos2 = fl.erase_after(pos, stop);
 
-  VERIFY(*pos == 1);
+  VERIFY( pos2 == stop );
+  VERIFY( *pos == 1 );
   ++pos;
-  VERIFY(*pos == 4);
-  VERIFY(std::distance(fl.begin(), fl.end()) == 8);
+  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);
+  std::forward_list<int>::iterator pos3
+    = fl.erase_after(pos, fl.end());
+  VERIFY( pos3 == 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());
+  std::forward_list<int>::iterator pos4
+    = fl.erase_after(fl.before_begin(), pos);
+  VERIFY( pos4 == pos );
+  VERIFY( std::distance(fl.begin(), fl.end()) == 0 );
+  VERIFY( fl.empty() );
 }
 
 int
Index: testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc	(revision 165577)
+++ testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1198 }
+// { dg-error "no matching" "" { target *-*-* } 1204 }
 // { dg-excess-errors "" }
 
 // Copyright (C) 2009, 2010 Free Software Foundation
Index: testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc	(revision 165577)
+++ testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1198 }
+// { dg-error "no matching" "" { target *-*-* } 1204 }
 // { dg-excess-errors "" }
 
 // Copyright (C) 2009, 2010 Free Software Foundation
Index: testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc	(revision 165577)
+++ testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1198 }
+// { dg-error "no matching" "" { target *-*-* } 1204 }
 // { dg-excess-errors "" }
 
 // Copyright (C) 2009, 2010 Free Software Foundation
Index: testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
===================================================================
--- testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc	(revision 165577)
+++ testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc	(working copy)
@@ -1,6 +1,6 @@ 
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }
-// { dg-error "no matching" "" { target *-*-* } 1198 }
+// { dg-error "no matching" "" { target *-*-* } 1204 }
 // { dg-excess-errors "" }
 
 // Copyright (C) 2009, 2010 Free Software Foundation
Index: testsuite/util/exception/safety.h
===================================================================
--- testsuite/util/exception/safety.h	(revision 165577)
+++ testsuite/util/exception/safety.h	(working copy)
@@ -265,10 +265,11 @@ 
       {
 	typedef std::forward_list<_Tp1, _Tp2> 		container_type;
 	typedef typename container_type::iterator 	iterator;
-	typedef typename container_type::const_iterator 	const_iterator;
+	typedef typename container_type::const_iterator const_iterator;
 
-	void (container_type::* _F_erase_point)(const_iterator);
-	void (container_type::* _F_erase_range)(const_iterator, const_iterator);
+	iterator (container_type::* _F_erase_point)(const_iterator);
+	iterator (container_type::* _F_erase_range)(const_iterator,
+						    const_iterator);
 
 	erase_base()
 	: _F_erase_point(&container_type::erase_after),