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]

Implementation of DR 130.


Greetings,

I implemented a solution to DR 130 - associative containers should have erase (iterator amd iterator range) return iterators to the next element just like a real container.

I added a return of iterator from the base _Rb_tree and used it in map, set, multimap, and multiset.

It bootstraps and regtests clean on x86_64-linux-unknown.

Thanks, Ed

Attachment: CL_DR130
Description: video/flv

Index: include/bits/stl_map.h
===================================================================
--- include/bits/stl_map.h	(revision 150706)
+++ include/bits/stl_map.h	(working copy)
@@ -552,9 +552,15 @@
         insert(_InputIterator __first, _InputIterator __last)
         { _M_t._M_insert_unique(__first, __last); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @brief Erases an element from a %map.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return An iterator pointing to the element immediately following
+       *          @a position prior to the element being erased. If no such 
+       *          element exists, end() is returned.
        *
        *  This function erases an element, pointed to by the given
        *  iterator, from a %map.  Note that this function only erases
@@ -562,9 +568,24 @@
        *  the pointed-to memory is not touched in any way.  Managing
        *  the pointer is the user's responsibility.
        */
+      iterator
+      erase(iterator __position)
+      { return _M_t.erase(__position); }
+#else
+      /**
+       *  @brief Erases an element from a %map.
+       *  @param  position  An iterator pointing to the element to be erased.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __position)
       { _M_t.erase(__position); }
+#endif
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -581,20 +602,40 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @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 The iterator @a last.
        *
        *  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 responsibility.
        */
+      iterator
+      erase(iterator __first, iterator __last)
+      { return _M_t.erase(__first, __last); }
+#else
+      /**
+       *  @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.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __first, iterator __last)
       { _M_t.erase(__first, __last); }
+#endif
 
       /**
        *  @brief  Swaps data with another %map.
Index: include/bits/stl_set.h
===================================================================
--- include/bits/stl_set.h	(revision 150706)
+++ include/bits/stl_set.h	(working copy)
@@ -458,18 +458,38 @@
       { this->insert(__l.begin(), __l.end()); }
 #endif
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @brief Erases an element from a %set.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return An iterator pointing to the element immediately following
+       *          @a position prior to the element being erased. If no such 
+       *          element exists, end() is returned.
        *
        *  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 responsibility.
        */
+      iterator
+      erase(iterator __position)
+      { return _M_t.erase(__position); }
+#else
+      /**
+       *  @brief Erases an element from a %set.
+       *  @param  position  An iterator pointing to the element to be erased.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __position)
       { _M_t.erase(__position); }
+#endif
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -486,20 +506,40 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @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 The iterator @a last.
        *
        *  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 responsibility.
        */
+      iterator
+      erase(iterator __first, iterator __last)
+      { return _M_t.erase(__first, __last); }
+#else
+      /**
+       *  @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.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __first, iterator __last)
       { _M_t.erase(__first, __last); }
+#endif
 
       /**
        *  Erases all elements in a %set.  Note that this function only erases
Index: include/bits/stl_multimap.h
===================================================================
--- include/bits/stl_multimap.h	(revision 150706)
+++ include/bits/stl_multimap.h	(working copy)
@@ -488,9 +488,15 @@
       { this->insert(__l.begin(), __l.end()); }
 #endif
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @brief Erases an element from a %multimap.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return An iterator pointing to the element immediately following
+       *          @a position prior to the element being erased. If no such 
+       *          element exists, end() is returned.
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %multimap.  Note that this function only erases the element,
@@ -498,9 +504,24 @@
        *  not touched in any way.  Managing the pointer is the user's
        *  responsibility.
        */
+      iterator
+      erase(iterator __position)
+      { return _M_t.erase(__position); }
+#else
+      /**
+       *  @brief Erases an element from a %multimap.
+       *  @param  position  An iterator pointing to the element to be erased.
+       *
+       *  This function erases an element, pointed to by the given iterator,
+       *  from a %multimap.  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
+       *  responsibility.
+       */
       void
       erase(iterator __position)
       { _M_t.erase(__position); }
+#endif
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -517,20 +538,42 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @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 The iterator @a last.
        *
        *  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 responsibility.
        */
+      iterator
+      erase(iterator __first, iterator __last)
+      { return _M_t.erase(__first, __last); }
+#else
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
+      /**
+       *  @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.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __first, iterator __last)
       { _M_t.erase(__first, __last); }
+#endif
 
       /**
        *  @brief  Swaps data with another %multimap.
Index: include/bits/stl_multiset.h
===================================================================
--- include/bits/stl_multiset.h	(revision 150706)
+++ include/bits/stl_multiset.h	(working copy)
@@ -445,9 +445,15 @@
       { this->insert(__l.begin(), __l.end()); }
 #endif
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @brief Erases an element from a %multiset.
        *  @param  position  An iterator pointing to the element to be erased.
+       *  @return An iterator pointing to the element immediately following
+       *          @a position prior to the element being erased. If no such 
+       *          element exists, end() is returned.
        *
        *  This function erases an element, pointed to by the given iterator,
        *  from a %multiset.  Note that this function only erases the element,
@@ -455,9 +461,24 @@
        *  not touched in any way.  Managing the pointer is the user's
        *  responsibility.
        */
+      iterator
+      erase(iterator __position)
+      { return _M_t.erase(__position); }
+#else
+      /**
+       *  @brief Erases an element from a %multiset.
+       *  @param  position  An iterator pointing to the element to be erased.
+       *
+       *  This function erases an element, pointed to by the given iterator,
+       *  from a %multiset.  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
+       *  responsibility.
+       */
       void
       erase(iterator __position)
       { _M_t.erase(__position); }
+#endif
 
       /**
        *  @brief Erases elements according to the provided key.
@@ -474,20 +495,40 @@
       erase(const key_type& __x)
       { return _M_t.erase(__x); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
       /**
        *  @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 The iterator @a last.
        *
        *  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 responsibility.
        */
+      iterator
+      erase(iterator __first, iterator __last)
+      { return _M_t.erase(__first, __last); }
+#else
+      /**
+       *  @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.
+       *
+       *  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 responsibility.
+       */
       void
       erase(iterator __first, iterator __last)
       { _M_t.erase(__first, __last); }
+#endif
 
       /**
        *  Erases all elements in a %multiset.  Note that this function only
Index: include/bits/stl_tree.h
===================================================================
--- include/bits/stl_tree.h	(revision 150706)
+++ include/bits/stl_tree.h	(working copy)
@@ -698,21 +698,43 @@
         void
         _M_insert_equal(_InputIterator __first, _InputIterator __last);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
+      iterator
+      erase(iterator __position);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
+      const_iterator
+      erase(const_iterator __position);
+#else
       void
       erase(iterator __position);
 
       void
       erase(const_iterator __position);
-
+#endif
       size_type
       erase(const key_type& __x);
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
+      iterator
+      erase(iterator __first, iterator __last);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 130. Associative erase should return an iterator.
+      const_iterator
+      erase(const_iterator __first, const_iterator __last);
+#else
       void
       erase(iterator __first, iterator __last);
 
       void
       erase(const_iterator __first, const_iterator __last);
-
+#endif
       void
       erase(const key_type* __first, const key_type* __last);
 
@@ -1327,8 +1349,47 @@
 	  _M_insert_equal_(end(), *__first);
       }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // DR 130. Associative erase should return an iterator.
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
+    inline typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    erase(iterator __position)
+    {
+      iterator __result = __position;
+      ++__result;
+      _Link_type __y =
+	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
+				(__position._M_node,
+				 this->_M_impl._M_header));
+      _M_destroy_node(__y);
+      --_M_impl._M_node_count;
+      return __result;
+    }
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // DR 130. Associative erase should return an iterator.
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
+    inline typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    erase(const_iterator __position)
+    {
+      const_iterator __result = __position;
+      ++__result;
+      _Link_type __y =
+	static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
+				(const_cast<_Base_ptr>(__position._M_node),
+				 this->_M_impl._M_header));
+      _M_destroy_node(__y);
+      --_M_impl._M_node_count;
+      return __result;
+    }
+#else
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
     inline void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     erase(iterator __position)
@@ -1354,6 +1415,7 @@
       _M_destroy_node(__y);
       --_M_impl._M_node_count;
     }
+#endif
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
@@ -1367,8 +1429,51 @@
       return __old_size - size();
     }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // DR 130. Associative erase should return an iterator.
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
+    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    erase(iterator __first, iterator __last)
+    {
+      if (__first == begin() && __last == end())
+        {
+	  clear();
+	  return end();
+        }
+      else
+        {
+	  while (__first != __last)
+	    erase(__first++);
+	  return __last;
+        }
+    }
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // DR 130. Associative erase should return an iterator.
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
+    typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    erase(const_iterator __first, const_iterator __last)
+    {
+      if (__first == begin() && __last == end())
+        {
+	  clear();
+	  return end();
+        }
+      else
+        {
+	  while (__first != __last)
+	    erase(__first++);
+	  return __last;
+        }
+    }
+#else
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
     void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     erase(iterator __first, iterator __last)
@@ -1392,6 +1497,7 @@
 	while (__first != __last)
 	  erase(__first++);
     }
+#endif
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
Index: testsuite/23_containers/multimap/dr130.cc
===================================================================
--- testsuite/23_containers/multimap/dr130.cc	(revision 0)
+++ testsuite/23_containers/multimap/dr130.cc	(revision 0)
@@ -0,0 +1,87 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <vector>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multimap<int, int> mm0;
+  typedef multimap<int, int>::iterator iterator;
+  typedef multimap<int, int>::const_iterator const_iterator;
+  typedef multimap<int, int>::value_type value_type;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for (int i = 1; i <= 4; ++i)
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( mm0.insert( value_type( i, i ) ) );
+
+  iterator pos1 = mm0.erase(irt[1]);
+  VERIFY( pos1 == irt[2] );
+
+  iterator pos2 = mm0.erase(irt[2]);
+  VERIFY( pos2 == irt[3] );
+
+  iterator pos3 = mm0.erase(irt[9]);
+  VERIFY( pos3 == mm0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multimap<int, int> mm0;
+  typedef multimap<int, int>::iterator iterator;
+  typedef multimap<int, int>::const_iterator const_iterator;
+  typedef multimap<int, int>::value_type value_type;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for (int i = 1; i <= 4; ++i)
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( mm0.insert( value_type( i, i ) ) );
+
+  iterator pos1 = mm0.erase(irt[3], irt[6]);
+  VERIFY( pos1 == irt[6] );
+
+  iterator pos2 = mm0.erase(irt[6], ++irt[9]);
+  VERIFY( pos2 == mm0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
Index: testsuite/23_containers/set/dr130.cc
===================================================================
--- testsuite/23_containers/set/dr130.cc	(revision 0)
+++ testsuite/23_containers/set/dr130.cc	(revision 0)
@@ -0,0 +1,75 @@
+// { dg-options "-std=gnu++0x" }
+// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
+//
+// Copyright (C) 2009 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+//  DR 130. Associative erase should return an iterator.
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  set<int> s0;
+  typedef set<int>::iterator iterator;
+  typedef set<int>::const_iterator const_iterator;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = s0.insert(1);
+  insert_return_type irt1 = s0.insert(2);
+  insert_return_type irt2 = s0.insert(3);
+
+  iterator pos1 = s0.erase(irt1.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = s0.erase(irt2.first);
+  VERIFY( pos2 == s0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  set<int> s0;
+  typedef set<int>::iterator iterator;
+  typedef set<int>::const_iterator const_iterator;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = s0.insert(1);
+  insert_return_type irt1 = s0.insert(2);
+  insert_return_type irt2 = s0.insert(3);
+  insert_return_type irt3 = s0.insert(4);
+
+  iterator pos1 = s0.erase(irt0.first, irt2.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = s0.erase(irt2.first, ++irt3.first);
+  VERIFY( pos2 == s0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
Index: testsuite/23_containers/multiset/dr130.cc
===================================================================
--- testsuite/23_containers/multiset/dr130.cc	(revision 0)
+++ testsuite/23_containers/multiset/dr130.cc	(revision 0)
@@ -0,0 +1,85 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <vector>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multiset<int> ms0;
+  typedef multiset<int>::iterator iterator;
+  typedef multiset<int>::const_iterator const_iterator;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for ( int i = 1; i <= 4; ++i )
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( ms0.insert( i ) );
+
+  iterator pos1 = ms0.erase(irt[1]);
+  VERIFY( pos1 == irt[2] );
+
+  iterator pos2 = ms0.erase(irt[2]);
+  VERIFY( pos2 == irt[3] );
+
+  iterator pos3 = ms0.erase(irt[9]);
+  VERIFY( pos3 == ms0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multiset<int> ms0;
+  typedef multiset<int>::iterator iterator;
+  typedef multiset<int>::const_iterator const_iterator;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for ( int i = 1; i <= 4; ++i )
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( ms0.insert( i ) );
+
+  iterator pos1 = ms0.erase(irt[3], irt[6]);
+  VERIFY( pos1 == irt[6] );
+
+  iterator pos2 = ms0.erase(irt[6], ++irt[9]);
+  VERIFY( pos2 == ms0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
Index: testsuite/23_containers/map/dr130.cc
===================================================================
--- testsuite/23_containers/map/dr130.cc	(revision 0)
+++ testsuite/23_containers/map/dr130.cc	(revision 0)
@@ -0,0 +1,77 @@
+// { dg-options "-std=gnu++0x" }
+// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
+//
+// Copyright (C) 2009 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 3, 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+//  DR 130. Associative erase should return an iterator.
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  map<int, int> m0;
+  typedef map<int, int>::iterator iterator;
+  typedef map<int, int>::const_iterator const_iterator;
+  typedef map<int, int>::value_type value_type;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = m0.insert(value_type(1, 1));
+  insert_return_type irt1 = m0.insert(value_type(2, 2));
+  insert_return_type irt2 = m0.insert(value_type(3, 3));
+
+  iterator pos1 = m0.erase(irt1.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = m0.erase(irt2.first);
+  VERIFY( pos2 == m0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  map<int, int> m0;
+  typedef map<int, int>::iterator iterator;
+  typedef map<int, int>::const_iterator const_iterator;
+  typedef map<int, int>::value_type value_type;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = m0.insert(value_type(1, 1));
+  insert_return_type irt1 = m0.insert(value_type(2, 2));
+  insert_return_type irt2 = m0.insert(value_type(3, 3));
+  insert_return_type irt3 = m0.insert(value_type(4, 4));
+
+  iterator pos1 = m0.erase(irt0.first, irt2.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = m0.erase(irt2.first, ++irt3.first);
+  VERIFY( pos2 == m0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}

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