OSDN Git Service

2006-11-26 Paolo Carlini <pcarlini@suse.de>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Nov 2006 10:04:25 +0000 (10:04 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Nov 2006 10:04:25 +0000 (10:04 +0000)
PR libstdc++/29385 (2nd part, based on an idea by Ion Gaztanaga)
* include/bits/stl_tree.h (_Rb_tree<>::_M_equal_range): Add.
(equal_range(const key_type&)): Use it.

2006-11-26  Paolo Carlini  <pcarlini@suse.de>

* testsuite/23_containers/multiset/operations/1.cc: New.
* testsuite/23_containers/set/operations/1.cc: Likewise.
* testsuite/23_containers/multimap/operations/1.cc: Likewise.
* testsuite/23_containers/map/operations/1.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119221 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/testsuite/23_containers/map/operations/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/operations/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/operations/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/operations/1.cc [new file with mode: 0644]

index 2566535..db38d1d 100644 (file)
@@ -1,3 +1,16 @@
+2006-11-26  Paolo Carlini  <pcarlini@suse.de>
+
+       PR libstdc++/29385 (2nd part, based on an idea by Ion Gaztanaga)
+       * include/bits/stl_tree.h (_Rb_tree<>::_M_equal_range): Add.
+       (equal_range(const key_type&)): Use it.
+
+2006-11-26  Paolo Carlini  <pcarlini@suse.de>
+
+       * testsuite/23_containers/multiset/operations/1.cc: New.
+       * testsuite/23_containers/set/operations/1.cc: Likewise.
+       * testsuite/23_containers/multimap/operations/1.cc: Likewise.
+       * testsuite/23_containers/map/operations/1.cc: Likewise.
+
 2006-11-25  Paolo Carlini  <pcarlini@suse.de>
 
        PR libstdc++/29385 (partial)
index c4dba4f..a4215af 100644 (file)
@@ -563,6 +563,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y,
                     const _Key& __k) const;
 
+      pair<iterator, iterator>
+      _M_equal_range(const _Key& __k) const;
+
     public:
       // allocation/deallocation
       _Rb_tree()
@@ -731,10 +734,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       { return const_iterator(_M_upper_bound(_M_begin(), _M_end(), __k)); }
 
       pair<iterator, iterator>
-      equal_range(const key_type& __k);
+      equal_range(const key_type& __k)
+      { return pair<iterator, iterator>(_M_equal_range(__k)); }
 
       pair<const_iterator, const_iterator>
-      equal_range(const key_type& __k) const;
+      equal_range(const key_type& __k) const
+      { return pair<const_iterator, const_iterator>(_M_equal_range(__k)); }
 
       // Debugging.
       bool
@@ -956,6 +961,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
+    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
+                          _Compare, _Alloc>::iterator,
+        typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator>
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    _M_equal_range(const _Key& __k) const
+    {
+      _Const_Link_type __x = _M_begin();
+      _Const_Link_type __y = _M_end();
+      while (__x != 0)
+       {
+         if (_M_impl._M_key_compare(_S_key(__x), __k))
+           __x = _S_right(__x);
+         else if (_M_impl._M_key_compare(__k, _S_key(__x)))
+           __y = __x, __x = _S_left(__x);
+         else
+           {
+             _Const_Link_type __xu(__x), __yu(__y);
+             __y = __x, __x = _S_left(__x);
+             __xu = _S_right(__xu);
+             return pair<iterator, iterator>(_M_lower_bound(__x, __y, __k),
+                                             _M_upper_bound(__xu, __yu, __k));   
+           }
+       }
+      return pair<iterator, iterator>(iterator(const_cast<_Link_type>(__y)),
+                                     iterator(const_cast<_Link_type>(__y)));
+    }
+
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
     void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
@@ -1295,27 +1329,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       return __n;
     }
 
-  template<typename _Key, typename _Val, typename _KeyOfValue,
-           typename _Compare, typename _Alloc>
-    inline
-    pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
-                          _Compare, _Alloc>::iterator,
-        typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator>
-    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    equal_range(const _Key& __k)
-    { return pair<iterator, iterator>(lower_bound(__k), upper_bound(__k)); }
-
-  template<typename _Key, typename _Val, typename _KoV,
-           typename _Compare, typename _Alloc>
-    inline
-    pair<typename _Rb_tree<_Key, _Val, _KoV,
-                          _Compare, _Alloc>::const_iterator,
-        typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator>
-    _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
-    equal_range(const _Key& __k) const
-    { return pair<const_iterator, const_iterator>(lower_bound(__k),
-                                                 upper_bound(__k)); }
-
   unsigned int
   _Rb_tree_black_count(const _Rb_tree_node_base* __node,
                        const _Rb_tree_node_base* __root);
diff --git a/libstdc++-v3/testsuite/23_containers/map/operations/1.cc b/libstdc++-v3/testsuite/23_containers/map/operations/1.cc
new file mode 100644 (file)
index 0000000..8f27ab4
--- /dev/null
@@ -0,0 +1,135 @@
+// 2006-11-25  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 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>
+
+// A few tests for equal_range, in the occasion of libstdc++/29385.
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  map<int, int> m0;
+  typedef map<int, int>::iterator iterator;
+  typedef pair<iterator, bool> insert_return_type;
+  pair<iterator, iterator> pp0;
+  typedef map<int, int>::value_type value_type;
+
+  pp0 = m0.equal_range(1);
+  VERIFY( m0.count(1) == 0 );
+  VERIFY( pp0.first == m0.end() );
+  VERIFY( pp0.second == m0.end() );
+
+  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));
+  pp0 = m0.equal_range(2);
+  VERIFY( m0.count(2) == 1 );
+  VERIFY( *pp0.first == value_type(2, 2) );
+  VERIFY( *pp0.second == value_type(3, 3) );
+  VERIFY( pp0.first == irt1.first );
+  VERIFY( --pp0.first == irt0.first );  
+  VERIFY( pp0.second == irt2.first );
+
+  m0.insert(value_type(3, 4));
+  insert_return_type irt3 = m0.insert(value_type(3, 5));
+  insert_return_type irt4 = m0.insert(value_type(4, 6));
+
+  pp0 = m0.equal_range(3);
+  VERIFY( m0.count(3) == 1 );
+  VERIFY( *pp0.first == value_type(3, 3) );
+  VERIFY( *pp0.second == value_type(4, 6) );
+  VERIFY( pp0.first == irt2.first );
+  VERIFY( --pp0.first == irt1.first );  
+  VERIFY( pp0.second == irt4.first );
+
+  insert_return_type irt5 = m0.insert(value_type(0, 7));
+  m0.insert(value_type(1, 8));
+  m0.insert(value_type(1, 9));
+  m0.insert(value_type(1, 10));
+
+  pp0 = m0.equal_range(1);
+  VERIFY( m0.count(1) == 1 );
+  VERIFY( *pp0.first == value_type(1, 1) );
+  VERIFY( *pp0.second == value_type(2, 2) );
+  VERIFY( pp0.first == irt0.first );
+  VERIFY( --pp0.first == irt5.first );  
+  VERIFY( pp0.second == irt1.first );
+
+  insert_return_type irt6 = m0.insert(value_type(5, 11));
+  m0.insert(value_type(5, 12));
+  m0.insert(value_type(5, 13));
+
+  pp0 = m0.equal_range(5);
+  VERIFY( m0.count(5) == 1 );
+  VERIFY( *pp0.first == value_type(5, 11) );
+  VERIFY( pp0.first == irt6.first );
+  VERIFY( --pp0.first == irt4.first );  
+  VERIFY( pp0.second == m0.end() );
+
+  m0.insert(value_type(4, 14));
+  m0.insert(value_type(4, 15));
+  m0.insert(value_type(4, 16));
+
+  pp0 = m0.equal_range(4);
+  VERIFY( m0.count(4) == 1 );  
+  VERIFY( *pp0.first == value_type(4, 6) );
+  VERIFY( *pp0.second == value_type(5, 11) );  
+  VERIFY( pp0.first == irt4.first );
+  VERIFY( --pp0.first == irt3.first );  
+  VERIFY( pp0.second == irt6.first );
+
+  m0.insert(value_type(0, 17));
+  insert_return_type irt7 = m0.insert(value_type(0, 18));
+  m0.insert(value_type(1, 19));
+
+  pp0 = m0.equal_range(0);
+  VERIFY( m0.count(0) == 1 );  
+  VERIFY( *pp0.first == value_type(0, 7) );
+  VERIFY( *pp0.second == value_type(1, 1) );  
+  VERIFY( pp0.first == irt5.first );
+  VERIFY( pp0.first == m0.begin() );
+  VERIFY( pp0.second == irt0.first );
+
+  pp0 = m0.equal_range(1);
+  VERIFY( m0.count(1) == 1 );  
+  VERIFY( *pp0.first == value_type(1, 1) );
+  VERIFY( *pp0.second == value_type(2, 2) );  
+  VERIFY( pp0.first == irt0.first );
+  VERIFY( --pp0.first == irt7.first);
+  VERIFY( pp0.second == irt1.first );
+}
+
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/operations/1.cc b/libstdc++-v3/testsuite/23_containers/multimap/operations/1.cc
new file mode 100644 (file)
index 0000000..8ee2f28
--- /dev/null
@@ -0,0 +1,134 @@
+// 2006-11-25  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 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>
+
+// A few tests for equal_range, in the occasion of libstdc++/29385.
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multimap<int, int> mm0;
+  typedef multimap<int, int>::iterator iterator;
+  pair<iterator, iterator> pp0;
+  typedef multimap<int, int>::value_type value_type;
+
+  pp0 = mm0.equal_range(1);
+  VERIFY( mm0.count(1) == 0 );
+  VERIFY( pp0.first == mm0.end() );
+  VERIFY( pp0.second == mm0.end() );
+
+  iterator iter0 = mm0.insert(value_type(1, 1));
+  iterator iter1 = mm0.insert(value_type(2, 2));
+  iterator iter2 = mm0.insert(value_type(3, 3));
+  pp0 = mm0.equal_range(2);
+  VERIFY( mm0.count(2) == 1 );
+  VERIFY( *pp0.first == value_type(2, 2) );
+  VERIFY( *pp0.second == value_type(3, 3) );
+  VERIFY( pp0.first == iter1 );
+  VERIFY( --pp0.first == iter0 );  
+  VERIFY( pp0.second == iter2 );
+
+  mm0.insert(value_type(3, 4));
+  iterator iter3 = mm0.insert(value_type(3, 5));
+  iterator iter4 = mm0.insert(value_type(4, 6));
+
+  pp0 = mm0.equal_range(3);
+  VERIFY( mm0.count(3) == 3 );
+  VERIFY( *pp0.first == value_type(3, 3) );
+  VERIFY( *pp0.second == value_type(4, 6) );
+  VERIFY( pp0.first == iter2 );
+  VERIFY( --pp0.first == iter1 );  
+  VERIFY( pp0.second == iter4 );
+
+  iterator iter5 = mm0.insert(value_type(0, 7));
+  mm0.insert(value_type(1, 8));
+  mm0.insert(value_type(1, 9));
+  mm0.insert(value_type(1, 10));
+
+  pp0 = mm0.equal_range(1);
+  VERIFY( mm0.count(1) == 4 );
+  VERIFY( *pp0.first == value_type(1, 1) );
+  VERIFY( *pp0.second == value_type(2, 2) );
+  VERIFY( pp0.first == iter0 );
+  VERIFY( --pp0.first == iter5 );  
+  VERIFY( pp0.second == iter1 );
+
+  iterator iter6 = mm0.insert(value_type(5, 11));
+  mm0.insert(value_type(5, 12));
+  mm0.insert(value_type(5, 13));
+
+  pp0 = mm0.equal_range(5);
+  VERIFY( mm0.count(5) == 3 );
+  VERIFY( *pp0.first == value_type(5, 11) );
+  VERIFY( pp0.first == iter6 );
+  VERIFY( --pp0.first == iter4 );  
+  VERIFY( pp0.second == mm0.end() );
+
+  mm0.insert(value_type(4, 14));
+  mm0.insert(value_type(4, 15));
+  mm0.insert(value_type(4, 16));
+
+  pp0 = mm0.equal_range(4);
+  VERIFY( mm0.count(4) == 4 );  
+  VERIFY( *pp0.first == value_type(4, 6) );
+  VERIFY( *pp0.second == value_type(5, 11) );  
+  VERIFY( pp0.first == iter4 );
+  VERIFY( --pp0.first == iter3 );  
+  VERIFY( pp0.second == iter6 );
+
+  mm0.insert(value_type(0, 17));
+  iterator iter7 = mm0.insert(value_type(0, 18));
+  mm0.insert(value_type(1, 19));
+
+  pp0 = mm0.equal_range(0);
+  VERIFY( mm0.count(0) == 3 );  
+  VERIFY( *pp0.first == value_type(0, 7) );
+  VERIFY( *pp0.second == value_type(1, 1) );  
+  VERIFY( pp0.first == iter5 );
+  VERIFY( pp0.first == mm0.begin() );
+  VERIFY( pp0.second == iter0 );
+
+  pp0 = mm0.equal_range(1);
+  VERIFY( mm0.count(1) == 5 );  
+  VERIFY( *pp0.first == value_type(1, 1) );
+  VERIFY( *pp0.second == value_type(2, 2) );  
+  VERIFY( pp0.first == iter0 );
+  VERIFY( --pp0.first == iter7 );
+  VERIFY( pp0.second == iter1 );
+}
+
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/operations/1.cc b/libstdc++-v3/testsuite/23_containers/multiset/operations/1.cc
new file mode 100644 (file)
index 0000000..ffa386c
--- /dev/null
@@ -0,0 +1,133 @@
+// 2006-11-25  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 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>
+
+// A few tests for equal_range, in the occasion of libstdc++/29385.
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multiset<int> ms0;
+  typedef multiset<int>::iterator iterator;
+  pair<iterator, iterator> pp0;
+
+  pp0 = ms0.equal_range(1);
+  VERIFY( ms0.count(1) == 0 );
+  VERIFY( pp0.first == ms0.end() );
+  VERIFY( pp0.second == ms0.end() );
+
+  iterator iter0 = ms0.insert(1);
+  iterator iter1 = ms0.insert(2);
+  iterator iter2 = ms0.insert(3);
+  pp0 = ms0.equal_range(2);
+  VERIFY( ms0.count(2) == 1 );
+  VERIFY( *pp0.first == 2 );
+  VERIFY( *pp0.second == 3 );
+  VERIFY( pp0.first == iter1 );
+  VERIFY( --pp0.first == iter0 );  
+  VERIFY( pp0.second == iter2 );
+
+  ms0.insert(3);
+  iterator iter3 = ms0.insert(3);
+  iterator iter4 = ms0.insert(4);
+  
+  pp0 = ms0.equal_range(3);
+  VERIFY( ms0.count(3) == 3 );
+  VERIFY( *pp0.first == 3 );
+  VERIFY( *pp0.second == 4 );
+  VERIFY( pp0.first == iter2 );
+  VERIFY( --pp0.first == iter1 );  
+  VERIFY( pp0.second == iter4 );
+
+  iterator iter5 = ms0.insert(0);
+  ms0.insert(1);
+  ms0.insert(1);
+  ms0.insert(1);
+
+  pp0 = ms0.equal_range(1);
+  VERIFY( ms0.count(1) == 4 );
+  VERIFY( *pp0.first == 1 );
+  VERIFY( *pp0.second == 2 );
+  VERIFY( pp0.first == iter0 );
+  VERIFY( --pp0.first == iter5 );  
+  VERIFY( pp0.second == iter1 );
+
+  iterator iter6 = ms0.insert(5);
+  ms0.insert(5);
+  ms0.insert(5);
+
+  pp0 = ms0.equal_range(5);
+  VERIFY( ms0.count(5) == 3 );
+  VERIFY( *pp0.first == 5 );
+  VERIFY( pp0.first == iter6 );
+  VERIFY( --pp0.first == iter4 );  
+  VERIFY( pp0.second == ms0.end() );
+
+  ms0.insert(4);
+  ms0.insert(4);
+  ms0.insert(4);
+
+  pp0 = ms0.equal_range(4);
+  VERIFY( ms0.count(4) == 4 );  
+  VERIFY( *pp0.first == 4 );
+  VERIFY( *pp0.second == 5 );  
+  VERIFY( pp0.first == iter4 );
+  VERIFY( --pp0.first == iter3 );  
+  VERIFY( pp0.second == iter6 );
+  
+  ms0.insert(0);
+  iterator iter7 = ms0.insert(0);
+  ms0.insert(1);
+
+  pp0 = ms0.equal_range(0);
+  VERIFY( ms0.count(0) == 3 );  
+  VERIFY( *pp0.first == 0 );
+  VERIFY( *pp0.second == 1 );  
+  VERIFY( pp0.first == iter5 );
+  VERIFY( pp0.first == ms0.begin() );
+  VERIFY( pp0.second == iter0 );
+
+  pp0 = ms0.equal_range(1);
+  VERIFY( ms0.count(1) == 5 );  
+  VERIFY( *pp0.first == 1 );
+  VERIFY( *pp0.second == 2 );  
+  VERIFY( pp0.first == iter0 );
+  VERIFY( --pp0.first == iter7 );
+  VERIFY( pp0.second == iter1 );
+}
+
+main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/operations/1.cc b/libstdc++-v3/testsuite/23_containers/set/operations/1.cc
new file mode 100644 (file)
index 0000000..fcc3113
--- /dev/null
@@ -0,0 +1,134 @@
+// 2006-11-25  Paolo Carlini  <pcarlini@suse.de>
+
+// Copyright (C) 2006 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>
+
+// A few tests for equal_range, in the occasion of libstdc++/29385.
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  set<int> s0;
+  typedef set<int>::iterator iterator;
+  typedef pair<iterator, bool> insert_return_type;
+  pair<iterator, iterator> pp0;
+
+  pp0 = s0.equal_range(1);
+  VERIFY( s0.count(1) == 0 );
+  VERIFY( pp0.first == s0.end() );
+  VERIFY( pp0.second == s0.end() );
+
+  insert_return_type irt0 = s0.insert(1);
+  insert_return_type irt1 = s0.insert(2);
+  insert_return_type irt2 = s0.insert(3);
+  pp0 = s0.equal_range(2);
+  VERIFY( s0.count(2) == 1 );
+  VERIFY( *pp0.first == 2 );
+  VERIFY( *pp0.second == 3 );
+  VERIFY( pp0.first == irt1.first );
+  VERIFY( --pp0.first == irt0.first );
+  VERIFY( pp0.second == irt2.first );
+
+  s0.insert(3);
+  insert_return_type irt3 = s0.insert(3);
+  insert_return_type irt4 = s0.insert(4);
+  
+  pp0 = s0.equal_range(3);
+  VERIFY( s0.count(3) == 1 );
+  VERIFY( *pp0.first == 3 );
+  VERIFY( *pp0.second == 4 );
+  VERIFY( pp0.first == irt2.first );
+  VERIFY( --pp0.first == irt1.first );  
+  VERIFY( pp0.second == irt4.first );
+
+  insert_return_type irt5 = s0.insert(0);
+  s0.insert(1);
+  s0.insert(1);
+  s0.insert(1);
+
+  pp0 = s0.equal_range(1);
+  VERIFY( s0.count(1) == 1 );
+  VERIFY( *pp0.first == 1 );
+  VERIFY( *pp0.second == 2 );
+  VERIFY( pp0.first == irt0.first );
+  VERIFY( --pp0.first == irt5.first );  
+  VERIFY( pp0.second == irt1.first );
+
+  insert_return_type irt6 = s0.insert(5);
+  s0.insert(5);
+  s0.insert(5);
+
+  pp0 = s0.equal_range(5);
+  VERIFY( s0.count(5) == 1 );
+  VERIFY( *pp0.first == 5 );
+  VERIFY( pp0.first == irt6.first );
+  VERIFY( --pp0.first == irt4.first );  
+  VERIFY( pp0.second == s0.end() );
+
+  s0.insert(4);
+  s0.insert(4);
+  s0.insert(4);
+
+  pp0 = s0.equal_range(4);
+  VERIFY( s0.count(4) == 1 );  
+  VERIFY( *pp0.first == 4 );
+  VERIFY( *pp0.second == 5 );  
+  VERIFY( pp0.first == irt4.first );
+  VERIFY( --pp0.first == irt3.first );  
+  VERIFY( pp0.second == irt6.first );
+  
+  s0.insert(0);
+  insert_return_type irt7 = s0.insert(0);
+  s0.insert(1);
+
+  pp0 = s0.equal_range(0);
+  VERIFY( s0.count(0) == 1 );  
+  VERIFY( *pp0.first == 0 );
+  VERIFY( *pp0.second == 1 );  
+  VERIFY( pp0.first == irt5.first );
+  VERIFY( pp0.first == s0.begin() );
+  VERIFY( pp0.second == irt0.first );
+
+  pp0 = s0.equal_range(1);
+  VERIFY( s0.count(1) == 1 );  
+  VERIFY( *pp0.first == 1 );
+  VERIFY( *pp0.second == 2 );  
+  VERIFY( pp0.first == irt0.first );
+  VERIFY( --pp0.first == irt7.first );
+  VERIFY( pp0.second == irt1.first );
+}
+
+main()
+{
+  test01();
+  return 0;
+}