PR libstdc++/29385 (2nd part, based on an idea by Ion Gaztanaga)

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.

From-SVN: r119221
This commit is contained in:
Paolo Carlini 2006-11-26 10:04:25 +00:00 committed by Paolo Carlini
parent 95c8e17296
commit 639b490be5
6 changed files with 585 additions and 23 deletions

View 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)

View 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
@ -954,6 +959,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return iterator(const_cast<_Link_type>(__y));
}
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
@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}