re PR libstdc++/22102 ([DR233] Implement resolution of DR 233)

2005-06-27  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/22102
	* include/bits/stl_tree.h (insert_unique(iterator, const _Val&),
	insert_equal((iterator, const _Val&)): Reimplement to check both
	before and after, as per the algorithm "ignore hint if wrong" of
	ISO paper N1780.

From-SVN: r101355
This commit is contained in:
Paolo Carlini 2005-06-27 16:35:49 +00:00 committed by Paolo Carlini
parent fd1e17264b
commit ec5537cc33
2 changed files with 65 additions and 18 deletions

View File

@ -1,3 +1,11 @@
2005-06-27 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/22102
* include/bits/stl_tree.h (insert_unique(iterator, const _Val&),
insert_equal((iterator, const _Val&)): Reimplement to check both
before and after, as per the algorithm "ignore hint if wrong" of
ISO paper N1780.
2005-06-27 Benjamin Kosnik <bkoz@redhat.com> 2005-06-27 Benjamin Kosnik <bkoz@redhat.com>
Ami Tavory <pbassoc@gmail.com> Ami Tavory <pbassoc@gmail.com>

View File

@ -893,8 +893,8 @@ namespace std
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
insert_unique(iterator __position, const _Val& __v) insert_unique(iterator __position, const _Val& __v)
{ {
if (__position._M_node == _M_end() // end()
|| __position._M_node == _M_rightmost()) if (__position._M_node == _M_end())
{ {
if (size() > 0 if (size() > 0
&& _M_impl._M_key_compare(_S_key(_M_rightmost()), && _M_impl._M_key_compare(_S_key(_M_rightmost()),
@ -903,24 +903,45 @@ namespace std
else else
return insert_unique(__v).first; return insert_unique(__v).first;
} }
else else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__position._M_node)))
{ {
// First, try before...
iterator __before = __position;
if (__position._M_node == _M_leftmost()) // begin()
return _M_insert(_M_leftmost(), _M_leftmost(), __v);
else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
_KeyOfValue()(__v)))
{
if (_S_right(__before._M_node) == 0)
return _M_insert(0, __before._M_node, __v);
else
return _M_insert(__position._M_node,
__position._M_node, __v);
}
else
return insert_unique(__v).first;
}
else if (_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// ... then try after.
iterator __after = __position; iterator __after = __position;
++__after; if (__position._M_node == _M_rightmost())
if (_M_impl._M_key_compare(_S_key(__position._M_node), return _M_insert(0, _M_rightmost(), __v);
_KeyOfValue()(__v)) else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
&& _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key((++__after)._M_node)))
_S_key(__after._M_node)))
{ {
if (_S_right(__position._M_node) == 0) if (_S_right(__position._M_node) == 0)
return _M_insert(0, __position._M_node, __v); return _M_insert(0, __position._M_node, __v);
else else
return _M_insert(__after._M_node, __after._M_node, __v); return _M_insert(__after._M_node, __after._M_node, __v);
// First argument just needs to be non-null.
} }
else else
return insert_unique(__v).first; return insert_unique(__v).first;
} }
else
return __position; // Equivalent keys.
} }
template<typename _Key, typename _Val, typename _KeyOfValue, template<typename _Key, typename _Val, typename _KeyOfValue,
@ -929,8 +950,8 @@ namespace std
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
insert_equal(iterator __position, const _Val& __v) insert_equal(iterator __position, const _Val& __v)
{ {
if (__position._M_node == _M_end() // end()
|| __position._M_node == _M_rightmost()) if (__position._M_node == _M_end())
{ {
if (size() > 0 if (size() > 0
&& !_M_impl._M_key_compare(_KeyOfValue()(__v), && !_M_impl._M_key_compare(_KeyOfValue()(__v),
@ -939,20 +960,38 @@ namespace std
else else
return insert_equal(__v); return insert_equal(__v);
} }
else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// First, try before...
iterator __before = __position;
if (__position._M_node == _M_leftmost()) // begin()
return _M_insert(_M_leftmost(), _M_leftmost(), __v);
else if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key((--__before)._M_node)))
{
if (_S_right(__before._M_node) == 0)
return _M_insert(0, __before._M_node, __v);
else
return _M_insert(__position._M_node,
__position._M_node, __v);
}
else
return insert_equal(__v);
}
else else
{ {
// ... then try after.
iterator __after = __position; iterator __after = __position;
++__after; if (__position._M_node == _M_rightmost())
if (!_M_impl._M_key_compare(_KeyOfValue()(__v), return _M_insert(0, _M_rightmost(), __v);
_S_key(__position._M_node)) else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
&& !_M_impl._M_key_compare(_S_key(__after._M_node),
_KeyOfValue()(__v))) _KeyOfValue()(__v)))
{ {
if (_S_right(__position._M_node) == 0) if (_S_right(__position._M_node) == 0)
return _M_insert(0, __position._M_node, __v); return _M_insert(0, __position._M_node, __v);
else else
return _M_insert(__after._M_node, __after._M_node, __v); return _M_insert(__after._M_node, __after._M_node, __v);
// First argument just needs to be non-null.
} }
else else
return insert_equal(__v); return insert_equal(__v);