This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] libstdc++/20787 (DR 130)
- From: Paolo Carlini <pcarlini at suse dot de>
- To: Paolo Carlini <pcarlini at suse dot de>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 02 Sep 2005 16:06:28 +0200
- Subject: Re: [Patch] libstdc++/20787 (DR 130)
- References: <431845BB.9010408@suse.de> <431846D6.2000007@suse.de>
Paolo Carlini wrote:
>Humpf! Forgot the debug-mode counterparts, but should be completely
>straightforward.
>
>
Like this...
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.
* include/debug/map.h (map<>::erase(iterator),
map<>::erase(iterator, iterator)): Likewise.
* include/debug/multimap.h (multimap<>::erase(iterator),
multimap<>::erase(iterator, iterator)): Likewise.
* include/debug/multiset.h (multiset<>::erase(iterator),
multiset<>::erase(iterator, iterator)): Likewise.
* include/debug/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/include/debug/map.h libstdc++-v3/include/debug/map.h
--- libstdc++-v3-orig/include/debug/map.h 2005-08-29 18:11:18.000000000 +0200
+++ libstdc++-v3/include/debug/map.h 2005-09-02 15:09:38.000000000 +0200
@@ -171,12 +171,15 @@
_Base::insert(__first, __last);
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __position)
{
__glibcxx_check_erase(__position);
__position._M_invalidate();
- _Base::erase(__position.base());
+ return iterator(_Base::erase(__position.base()), this);
}
size_type
@@ -193,14 +196,18 @@
}
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
while (__first != __last)
- this->erase(__first++);
+ __first = this->erase(__first);
+ return __last;
}
void
diff -urN libstdc++-v3-orig/include/debug/multimap.h libstdc++-v3/include/debug/multimap.h
--- libstdc++-v3-orig/include/debug/multimap.h 2005-08-17 04:13:15.000000000 +0200
+++ libstdc++-v3/include/debug/multimap.h 2005-09-02 15:10:30.000000000 +0200
@@ -157,12 +157,15 @@
_Base::insert(__first, __last);
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __position)
{
__glibcxx_check_erase(__position);
__position._M_invalidate();
- _Base::erase(__position.base());
+ return iterator(_Base::erase(__position.base()), this);
}
size_type
@@ -180,14 +183,18 @@
return __count;
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
while (__first != __last)
- this->erase(__first++);
+ __first = this->erase(__first);
+ return __last;
}
void
diff -urN libstdc++-v3-orig/include/debug/multiset.h libstdc++-v3/include/debug/multiset.h
--- libstdc++-v3-orig/include/debug/multiset.h 2005-08-17 04:13:15.000000000 +0200
+++ libstdc++-v3/include/debug/multiset.h 2005-09-02 15:17:08.000000000 +0200
@@ -148,19 +148,22 @@
}
template<typename _InputIterator>
- void
- insert(_InputIterator __first, _InputIterator __last)
- {
- __glibcxx_check_valid_range(__first, __last);
- _Base::insert(__first, __last);
- }
+ void
+ insert(_InputIterator __first, _InputIterator __last)
+ {
+ __glibcxx_check_valid_range(__first, __last);
+ _Base::insert(__first, __last);
+ }
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __position)
{
__glibcxx_check_erase(__position);
__position._M_invalidate();
- _Base::erase(__position.base());
+ return iterator(_Base::erase(__position.base()), this);
}
size_type
@@ -177,15 +180,19 @@
}
return __count;
}
-
- void
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 151. can't currently clear() empty container
__glibcxx_check_erase_range(__first, __last);
while (__first != __last)
- this->erase(__first++);
+ __first = this->erase(__first);
+ return __last;
}
void
diff -urN libstdc++-v3-orig/include/debug/set.h libstdc++-v3/include/debug/set.h
--- libstdc++-v3-orig/include/debug/set.h 2005-08-17 04:13:15.000000000 +0200
+++ libstdc++-v3/include/debug/set.h 2005-09-02 15:10:00.000000000 +0200
@@ -160,12 +160,15 @@
_Base::insert(__first, __last);
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __position)
{
__glibcxx_check_erase(__position);
__position._M_invalidate();
- _Base::erase(__position.base());
+ return iterator(_Base::erase(__position.base()), this);
}
size_type
@@ -182,7 +185,10 @@
}
}
- void
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 130. Return type of container::erase(iterator) differs for
+ // associative containers.
+ iterator
erase(iterator __first, iterator __last)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -190,7 +196,8 @@
__glibcxx_check_erase_range(__first, __last);
while (__first != __last)
- this->erase(__first++);
+ __first = this->erase(__first);
+ return __last;
}
void
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;
+}