This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] libstdc++/20787 (DR 130)


Hi,

a few days ago I noticed that the relevant DR in the meanwhile has been
moved to [DR] status and decided to reconsider implementing its
resolution. Indeed, apparently there is a very large consensus (see also
Effective STL, outside the LWG references proper, f.i.) that changing
the associative containers consistently with all the other containers is
a good thing. The only minor disadvantage seems that a single
erase(iterator) becomes computationally a little more expensive, due to
the additional iterator increment (however, this is not the case for
erase(iterator, iterator), because its internal loop can now make use of
the erase(iterator) return value, i.e., the very same idiom used in
list::erase).

Anyone disagreeing with adding the below to mainline?!?

Tested x86-linux.

Paolo.

//////////////////
2005-09-03  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/20787 (DR 130 [DR])
	* include/bits/stl_tree.h (_Rb_tree<>::erase(iterator),
	_Rb_tree<>::erase(iterator, iterator)): Adjust to return
	an iterator, as per the resolution of DR 130.
	* include/bits/stl_map.h (map<>::erase(iterator),
	map<>::erase(iterator, iterator)): Update consistently.
	* include/bits/stl_multimap.h (multimap<>::erase(iterator),
	multimap<>::erase(iterator, iterator)): Likewise.
	* include/bits/stl_multiset.h (multiset<>::erase(iterator),
	multiset<>::erase(iterator, iterator)): Likewise.
	* include/bits/stl_set.h (set<>::erase(iterator),
	set<>::erase(iterator, iterator)): Likewise.
	* docs/html/ext/howto.html: Add an entry for DR 130.
	* testsuite/23_containers/map/erase/1.cc: New.
	* testsuite/23_containers/multimap/erase/1.cc: Likewise.
	* testsuite/23_containers/multiset/erase/1.cc: Likewise.
	* testsuite/23_containers/set/erase/1.cc: Likewise.
diff -urN libstdc++-v3-orig/docs/html/ext/howto.html libstdc++-v3/docs/html/ext/howto.html
--- libstdc++-v3-orig/docs/html/ext/howto.html	2005-08-29 18:11:19.000000000 +0200
+++ libstdc++-v3/docs/html/ext/howto.html	2005-09-02 14:12:16.000000000 +0200
@@ -337,6 +337,15 @@
     <dd>These functions set <code>failbit</code> on error now.
     </dd>
 
+    <dt><a href="lwg-defects.html#130">130</a>:
+        <em>Return type of container::erase(iterator) differs for
+	    associative containers</em>
+    </dt>
+    <dd>Adjust the <code>erase(iterator)</code> and the
+        <code>erase(iterator, iterator)</code> overloads to
+        return an <code>iterator</code>.
+    </dd>
+
     <dt><a href="lwg-defects.html#136">136</a>:
         <em>seekp, seekg setting wrong streams?</em>
     </dt>
diff -urN libstdc++-v3-orig/include/bits/stl_map.h libstdc++-v3/include/bits/stl_map.h
--- libstdc++-v3-orig/include/bits/stl_map.h	2005-08-29 18:50:52.000000000 +0200
+++ libstdc++-v3/include/bits/stl_map.h	2005-09-02 11:26:38.000000000 +0200
@@ -432,18 +432,22 @@
         insert(_InputIterator __first, _InputIterator __last)
         { _M_t.insert_unique(__first, __last); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases an element from a %map.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return  An iterator pointing to the next element (or end()).
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %map.  Note that this function only erases the element, and
        *  that if the element is itself a pointer, the pointed-to memory is not
        *  touched in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __position)
-      { _M_t.erase(__position); }
+      { return _M_t.erase(__position); }
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -460,20 +464,25 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases a [first,last) range of elements from a %map.
        *  @param  first  Iterator pointing to the start of the range to be
        *                 erased.
        *  @param  last  Iterator pointing to the end of the range to be erased.
+       *  @return  An iterator pointing to the element pointed to by @a last
+       *           prior to erasing (or end()).
        *
        *  This function erases a sequence of elements from a %map.
        *  Note that this function only erases the element, and that if
        *  the element is itself a pointer, the pointed-to memory is not touched
        *  in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __first, iterator __last)
-      { _M_t.erase(__first, __last); }
+      { return _M_t.erase(__first, __last); }
 
       /**
        *  @brief  Swaps data with another %map.
diff -urN libstdc++-v3-orig/include/bits/stl_multimap.h libstdc++-v3/include/bits/stl_multimap.h
--- libstdc++-v3-orig/include/bits/stl_multimap.h	2005-08-17 04:13:01.000000000 +0200
+++ libstdc++-v3/include/bits/stl_multimap.h	2005-09-02 11:28:43.000000000 +0200
@@ -391,9 +391,13 @@
         insert(_InputIterator __first, _InputIterator __last)
         { _M_t.insert_equal(__first, __last); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases an element from a %multimap.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return  An iterator pointing to the next element (or end()).
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %multimap.  Note that this function only erases the element,
@@ -401,9 +405,9 @@
        *  not touched in any way.  Managing the pointer is the user's
        *  responsibilty.
        */
-      void
+      iterator
       erase(iterator __position)
-      { _M_t.erase(__position); }
+      { return _M_t.erase(__position); }
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -420,20 +424,25 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases a [first,last) range of elements from a %multimap.
        *  @param  first  Iterator pointing to the start of the range to be
        *                 erased.
        *  @param  last  Iterator pointing to the end of the range to be erased.
+       *  @return  An iterator pointing to the element pointed to by @a last
+       *           prior to erasing (or end()).
        *
        *  This function erases a sequence of elements from a %multimap.
        *  Note that this function only erases the elements, and that if
        *  the elements themselves are pointers, the pointed-to memory is not
        *  touched in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __first, iterator __last)
-      { _M_t.erase(__first, __last); }
+      { return _M_t.erase(__first, __last); }
 
       /**
        *  @brief  Swaps data with another %multimap.
diff -urN libstdc++-v3-orig/include/bits/stl_multiset.h libstdc++-v3/include/bits/stl_multiset.h
--- libstdc++-v3-orig/include/bits/stl_multiset.h	2005-08-17 04:13:01.000000000 +0200
+++ libstdc++-v3/include/bits/stl_multiset.h	2005-09-02 11:29:25.000000000 +0200
@@ -349,9 +349,13 @@
         insert(_InputIterator __first, _InputIterator __last)
         { _M_t.insert_equal(__first, __last); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases an element from a %multiset.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return  An iterator pointing to the next element (or end()).
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %multiset.  Note that this function only erases the element,
@@ -359,11 +363,11 @@
        *  not touched in any way.  Managing the pointer is the user's
        *  responsibilty.
        */
-      void
+      iterator
       erase(iterator __position)
       {
 	typedef typename _Rep_type::iterator _Rep_iterator;
-	_M_t.erase((_Rep_iterator&)__position);
+	return _M_t.erase((_Rep_iterator&)__position);
       }
 
       /**
@@ -381,22 +385,27 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases a [first,last) range of elements from a %multiset.
        *  @param  first  Iterator pointing to the start of the range to be
        *                 erased.
        *  @param  last  Iterator pointing to the end of the range to be erased.
+       *  @return  An iterator pointing to the element pointed to by @a last
+       *           prior to erasing (or end()).
        *
        *  This function erases a sequence of elements from a %multiset.
        *  Note that this function only erases the elements, and that if
        *  the elements themselves are pointers, the pointed-to memory is not
        *  touched in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __first, iterator __last)
       {
 	typedef typename _Rep_type::iterator _Rep_iterator;
-	_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+	return _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
       }
 
       /**
diff -urN libstdc++-v3-orig/include/bits/stl_set.h libstdc++-v3/include/bits/stl_set.h
--- libstdc++-v3-orig/include/bits/stl_set.h	2005-08-17 04:13:02.000000000 +0200
+++ libstdc++-v3/include/bits/stl_set.h	2005-09-02 11:27:52.000000000 +0200
@@ -360,21 +360,25 @@
       void
       insert(_InputIterator __first, _InputIterator __last)
       { _M_t.insert_unique(__first, __last); }
-
+      
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases an element from a %set.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return  An iterator pointing to the next element (or end()).
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %set.  Note that this function only erases the element, and
        *  that if the element is itself a pointer, the pointed-to memory is not
        *  touched in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __position)
       {
 	typedef typename _Rep_type::iterator _Rep_iterator;
-	_M_t.erase((_Rep_iterator&)__position);
+	return _M_t.erase((_Rep_iterator&)__position);
       }
 
       /**
@@ -391,22 +395,27 @@
       size_type
       erase(const key_type& __x) { return _M_t.erase(__x); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Return type of container::erase(iterator) differs for
+      //         associative containers.
       /**
        *  @brief Erases a [first,last) range of elements from a %set.
        *  @param  first  Iterator pointing to the start of the range to be
        *                 erased.
        *  @param  last  Iterator pointing to the end of the range to be erased.
+       *  @return  An iterator pointing to the element pointed to by @a last
+       *           prior to erasing (or end()).
        *
        *  This function erases a sequence of elements from a %set.
        *  Note that this function only erases the element, and that if
        *  the element is itself a pointer, the pointed-to memory is not touched
        *  in any way.  Managing the pointer is the user's responsibilty.
        */
-      void
+      iterator
       erase(iterator __first, iterator __last)
       {
 	typedef typename _Rep_type::iterator _Rep_iterator;
-	_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+	return _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
       }
 
       /**
diff -urN libstdc++-v3-orig/include/bits/stl_tree.h libstdc++-v3/include/bits/stl_tree.h
--- libstdc++-v3-orig/include/bits/stl_tree.h	2005-08-17 04:13:02.000000000 +0200
+++ libstdc++-v3/include/bits/stl_tree.h	2005-09-02 11:32:49.000000000 +0200
@@ -648,13 +648,13 @@
       void
       insert_equal(_InputIterator __first, _InputIterator __last);
 
-      void
+      iterator
       erase(iterator __position);
 
       size_type
       erase(const key_type& __x);
 
-      void
+      iterator
       erase(iterator __first, iterator __last);
 
       void
@@ -1022,16 +1022,20 @@
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
-    inline void
+    inline
+    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     erase(iterator __position)
     {
+      iterator __ret = __position;
+      ++__ret;
       _Link_type __y =
 	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
 				(__position._M_node,
 				 this->_M_impl._M_header));
       destroy_node(__y);
       --_M_impl._M_node_count;
+      return __ret;
     }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -1100,7 +1104,7 @@
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
-    void
+    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     erase(iterator __first, iterator __last)
     {
@@ -1108,7 +1112,8 @@
 	clear();
       else
 	while (__first != __last)
-	  erase(__first++);
+	  __first = erase(__first);
+      return __last;
     }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
diff -urN libstdc++-v3-orig/testsuite/23_containers/map/erase/1.cc libstdc++-v3/testsuite/23_containers/map/erase/1.cc
--- libstdc++-v3-orig/testsuite/23_containers/map/erase/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/23_containers/map/erase/1.cc	2005-09-02 13:23:31.000000000 +0200
@@ -0,0 +1,100 @@
+// 2005-09-02  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2005 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+// libstdc++/20787 (DR 130)
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  typedef map<int, int> Map;
+  Map m0;
+  Map::iterator iter0;
+  pair<Map::iterator, bool> p1, p2, p3;
+  typedef Map::value_type mp;
+
+  p1 = m0.insert(mp(0, 1));
+  VERIFY( p1.second == true );
+  iter0 = m0.erase(p1.first);
+  VERIFY( m0.empty() );
+  VERIFY( iter0 == m0.end() );
+
+  p1 = m0.insert(mp(1, 2));
+  VERIFY( p1.second == true );
+  p2 = m0.insert(mp(2, 3));
+  VERIFY( p2.second == true );
+  iter0 = m0.erase(p1.first);
+  VERIFY( iter0 == p2.first );
+  VERIFY( iter0 == m0.find(2) );
+  VERIFY( (*iter0).second == 3 );
+  iter0 = m0.erase(p2.first);
+  VERIFY( m0.empty() );
+  VERIFY( iter0 == m0.end() );
+
+  p1 = m0.insert(mp(3, 4));
+  VERIFY( p1.second == true );
+  p2 = m0.insert(mp(4, 5));
+  VERIFY( p2.second == true );
+  iter0 = m0.erase(p1.first, m0.end());
+  VERIFY( m0.empty() );
+  VERIFY( iter0 == m0.end() );
+
+  p1 = m0.insert(mp(1, 2));
+  VERIFY( p1.second == true );
+  p2 = m0.insert(mp(2, 3));
+  VERIFY( p2.second == true );
+  p3 = m0.insert(mp(3, 4));
+  VERIFY( p3.second == true );
+  iter0 = m0.erase(p1.first, p3.first);
+  VERIFY( iter0 == p3.first );
+  VERIFY( iter0 == m0.find(3) );
+  VERIFY( (*iter0).second == 4 );
+  VERIFY( m0.size() == 1 );
+  
+  p1 = m0.insert(mp(4, 5));
+  VERIFY( p1.second == true );
+  p2 = m0.insert(mp(5, 6));
+  VERIFY( p2.second == true );
+  p3 = m0.insert(mp(6, 7));
+  VERIFY( p3.second == true );
+  iter0 = m0.erase(p2.first, p3.first);
+  VERIFY( iter0 == p3.first );
+  VERIFY( iter0 == m0.find(6) );
+  VERIFY( (*iter0).second == 7 );
+  VERIFY( m0.size() == 3 );
+}
+
+int main ()
+{
+  test01();
+  return 0;
+}
diff -urN libstdc++-v3-orig/testsuite/23_containers/multimap/erase/1.cc libstdc++-v3/testsuite/23_containers/multimap/erase/1.cc
--- libstdc++-v3-orig/testsuite/23_containers/multimap/erase/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/23_containers/multimap/erase/1.cc	2005-09-02 13:24:21.000000000 +0200
@@ -0,0 +1,88 @@
+// 2005-09-02  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2005 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+// libstdc++/20787 (DR 130)
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+  
+  typedef multimap<int, int> Multimap;
+  Multimap mm0;
+  Multimap::iterator iter0, iter1, iter2, iter3;
+  typedef Multimap::value_type mmp;
+
+  iter1 = mm0.insert(mmp(0, 1));
+  iter0 = mm0.erase(iter1);
+  VERIFY( mm0.empty() );
+  VERIFY( iter0 == mm0.end() );
+
+  iter1 = mm0.insert(mmp(1, 2));
+  iter2 = mm0.insert(mmp(2, 3));
+  iter0 = mm0.erase(iter1);
+  VERIFY( iter0 == iter2 );
+  VERIFY( iter0 == mm0.find(2) );
+  VERIFY( (*iter0).second == 3 );
+  iter0 = mm0.erase(iter2);
+  VERIFY( mm0.empty() );
+  VERIFY( iter0 == mm0.end() );
+
+  iter1 = mm0.insert(mmp(3, 4));
+  iter2 = mm0.insert(mmp(4, 5));
+  iter0 = mm0.erase(iter1, mm0.end());
+  VERIFY( mm0.empty() );
+  VERIFY( iter0 == mm0.end() );
+
+  iter1 = mm0.insert(mmp(1, 2));
+  iter2 = mm0.insert(mmp(2, 3));
+  iter3 = mm0.insert(mmp(3, 4));
+  iter0 = mm0.erase(iter1, iter3);
+  VERIFY( iter0 == iter3 );
+  VERIFY( iter0 == mm0.find(3) );
+  VERIFY( (*iter0).second == 4 );
+  VERIFY( mm0.size() == 1 );
+  
+  iter1 = mm0.insert(mmp(4, 5));
+  iter2 = mm0.insert(mmp(5, 6));
+  iter3 = mm0.insert(mmp(6, 7));
+  iter0 = mm0.erase(iter2, iter3);
+  VERIFY( iter0 == iter3 );
+  VERIFY( iter0 == mm0.find(6) );
+  VERIFY( (*iter0).second == 7 );
+  VERIFY( mm0.size() == 3 );
+}
+
+int main ()
+{
+  test01();
+  return 0;
+}
diff -urN libstdc++-v3-orig/testsuite/23_containers/multiset/erase/1.cc libstdc++-v3/testsuite/23_containers/multiset/erase/1.cc
--- libstdc++-v3-orig/testsuite/23_containers/multiset/erase/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/23_containers/multiset/erase/1.cc	2005-09-02 13:22:47.000000000 +0200
@@ -0,0 +1,84 @@
+// 2005-09-02  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2005 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+// libstdc++/20787 (DR 130)
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  typedef multiset<int> Multiset;
+  Multiset s0;
+  Multiset::iterator iter0, iter1, iter2, iter3;
+
+  iter1 = s0.insert(0);
+  iter0 = s0.erase(iter1);
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  iter1 = s0.insert(1);
+  iter2 = s0.insert(2);
+  iter0 = s0.erase(iter1);
+  VERIFY( iter0 == iter2 );
+  VERIFY( iter0 == s0.find(2) );
+  iter0 = s0.erase(iter2);
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  iter1 = s0.insert(3);
+  iter2 = s0.insert(4);
+  iter0 = s0.erase(iter1, s0.end());
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  iter1 = s0.insert(1);
+  iter2 = s0.insert(2);
+  iter3 = s0.insert(3);
+  iter0 = s0.erase(iter1, iter3);
+  VERIFY( iter0 == iter3 );
+  VERIFY( iter0 == s0.find(3) );
+  VERIFY( s0.size() == 1 );
+  
+  iter1 = s0.insert(4);
+  iter2 = s0.insert(5);
+  iter3 = s0.insert(6);
+  iter0 = s0.erase(iter2, iter3);
+  VERIFY( iter0 == iter3 );
+  VERIFY( iter0 == s0.find(6) );
+  VERIFY( s0.size() == 3 );
+}
+
+int main ()
+{
+  test01();
+  return 0;
+}
diff -urN libstdc++-v3-orig/testsuite/23_containers/set/erase/1.cc libstdc++-v3/testsuite/23_containers/set/erase/1.cc
--- libstdc++-v3-orig/testsuite/23_containers/set/erase/1.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/23_containers/set/erase/1.cc	2005-09-02 13:21:54.000000000 +0200
@@ -0,0 +1,96 @@
+// 2005-09-02  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2005 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction.  Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License.  This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+// libstdc++/20787 (DR 130)
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  typedef set<int> Set;
+  Set s0;
+  Set::iterator iter0;
+  pair<Set::iterator, bool> p1, p2, p3;
+
+  p1 = s0.insert(0);
+  VERIFY( p1.second == true );
+  iter0 = s0.erase(p1.first);
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  p1 = s0.insert(1);
+  VERIFY( p1.second == true );
+  p2 = s0.insert(2);
+  VERIFY( p2.second == true );
+  iter0 = s0.erase(p1.first);
+  VERIFY( iter0 == p2.first );
+  VERIFY( iter0 == s0.find(2) );
+  iter0 = s0.erase(p2.first);
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  p1 = s0.insert(3);
+  VERIFY( p1.second == true );
+  p2 = s0.insert(4);
+  VERIFY( p2.second == true );
+  iter0 = s0.erase(p1.first, s0.end());
+  VERIFY( s0.empty() );
+  VERIFY( iter0 == s0.end() );
+
+  p1 = s0.insert(1);
+  VERIFY( p1.second == true );
+  p2 = s0.insert(2);
+  VERIFY( p2.second == true );
+  p3 = s0.insert(3);
+  VERIFY( p3.second == true );
+  iter0 = s0.erase(p1.first, p3.first);
+  VERIFY( iter0 == p3.first );
+  VERIFY( iter0 == s0.find(3) );
+  VERIFY( s0.size() == 1 );
+  
+  p1 = s0.insert(4);
+  VERIFY( p1.second == true );
+  p2 = s0.insert(5);
+  VERIFY( p2.second == true );
+  p3 = s0.insert(6);
+  VERIFY( p3.second == true );
+  iter0 = s0.erase(p2.first, p3.first);
+  VERIFY( iter0 == p3.first );
+  VERIFY( iter0 == s0.find(6) );
+  VERIFY( s0.size() == 3 );
+}
+
+int main ()
+{
+  test01();
+  return 0;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]