re PR libstdc++/24975 (Aliasing problems inside libstdc++)

2005-11-22  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/24975
	* include/bits/stl_set.h (insert(iterator, const value_type&),
	erase(iterator), erase(iterator, iterator)): Don't break aliasing
	rules casting to _Rep_iterator&, forward to _Rb_tree facilities.
	* include/bits/stl_multiset.h (insert(iterator, const value_type&),
	erase(iterator), erase(iterator, iterator)): Likewise.
	* include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr,
	_Const_Base_ptr, const value_type&), insert_unique(const_iterator,
	const value_type&), insert_equal(const_iterator, const value_type&),
	erase(const_iterator), erase(const_iterator, const_iterator)): New,
	_Rb_tree<>::const_iterator counterparts of existing facilities.

From-SVN: r107362
This commit is contained in:
Paolo Carlini 2005-11-22 14:53:03 +00:00 committed by Paolo Carlini
parent d66437c5fe
commit d5e07b79f4
4 changed files with 205 additions and 35 deletions

View File

@ -1,3 +1,17 @@
2005-11-22 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/24975
* include/bits/stl_set.h (insert(iterator, const value_type&),
erase(iterator), erase(iterator, iterator)): Don't break aliasing
rules casting to _Rep_iterator&, forward to _Rb_tree facilities.
* include/bits/stl_multiset.h (insert(iterator, const value_type&),
erase(iterator), erase(iterator, iterator)): Likewise.
* include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr,
_Const_Base_ptr, const value_type&), insert_unique(const_iterator,
const value_type&), insert_equal(const_iterator, const value_type&),
erase(const_iterator), erase(const_iterator, const_iterator)): New,
_Rb_tree<>::const_iterator counterparts of existing facilities.
2005-11-21 Benjamin Kosnik <bkoz@redhat.com>
Ulrich Drepper <drepper@redhat.com>

View File

@ -331,10 +331,7 @@ namespace _GLIBCXX_STD
*/
iterator
insert(iterator __position, const value_type& __x)
{
typedef typename _Rep_type::iterator _Rep_iterator;
return _M_t.insert_equal((_Rep_iterator&)__position, __x);
}
{ return _M_t.insert_equal(__position, __x); }
/**
* @brief A template function that attemps to insert a range of elements.
@ -361,10 +358,7 @@ namespace _GLIBCXX_STD
*/
void
erase(iterator __position)
{
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__position);
}
{ _M_t.erase(__position); }
/**
* @brief Erases elements according to the provided key.
@ -394,10 +388,7 @@ namespace _GLIBCXX_STD
*/
void
erase(iterator __first, iterator __last)
{
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
}
{ _M_t.erase(__first, __last); }
/**
* Erases all elements in a %multiset. Note that this function only

View File

@ -343,10 +343,7 @@ namespace _GLIBCXX_STD
*/
iterator
insert(iterator __position, const value_type& __x)
{
typedef typename _Rep_type::iterator _Rep_iterator;
return _M_t.insert_unique((_Rep_iterator&)__position, __x);
}
{ return _M_t.insert_unique(__position, __x); }
/**
* @brief A template function that attemps to insert a range of elements.
@ -357,9 +354,9 @@ namespace _GLIBCXX_STD
* Complexity similar to that of the range constructor.
*/
template<class _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t.insert_unique(__first, __last); }
void
insert(_InputIterator __first, _InputIterator __last)
{ _M_t.insert_unique(__first, __last); }
/**
* @brief Erases an element from a %set.
@ -372,10 +369,7 @@ namespace _GLIBCXX_STD
*/
void
erase(iterator __position)
{
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__position);
}
{ _M_t.erase(__position); }
/**
* @brief Erases elements according to the provided key.
@ -389,7 +383,8 @@ namespace _GLIBCXX_STD
* in any way. Managing the pointer is the user's responsibilty.
*/
size_type
erase(const key_type& __x) { return _M_t.erase(__x); }
erase(const key_type& __x)
{ return _M_t.erase(__x); }
/**
* @brief Erases a [first,last) range of elements from a %set.
@ -404,10 +399,7 @@ namespace _GLIBCXX_STD
*/
void
erase(iterator __first, iterator __last)
{
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
}
{ _M_t.erase(__first, __last); }
/**
* Erases all elements in a %set. Note that this function only erases

View File

@ -539,6 +539,10 @@ namespace std
iterator
_M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
const_iterator
_M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y,
const value_type& __v);
_Link_type
_M_copy(_Const_Link_type __x, _Link_type __p);
@ -647,9 +651,15 @@ namespace std
iterator
insert_unique(iterator __position, const value_type& __x);
const_iterator
insert_unique(const_iterator __position, const value_type& __x);
iterator
insert_equal(iterator __position, const value_type& __x);
const_iterator
insert_equal(const_iterator __position, const value_type& __x);
template<typename _InputIterator>
void
insert_unique(_InputIterator __first, _InputIterator __last);
@ -661,12 +671,18 @@ namespace std
void
erase(iterator __position);
void
erase(const_iterator __position);
size_type
erase(const key_type& __x);
void
erase(iterator __first, iterator __last);
void
erase(const_iterator __first, const_iterator __last);
void
erase(const key_type* __first, const key_type* __last);
@ -808,6 +824,25 @@ namespace std
return iterator(__z);
}
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>::
_M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v)
{
bool __insert_left = (__x != 0 || __p == _M_end()
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__p)));
_Link_type __z = _M_create_node(__v);
_Rb_tree_insert_and_rebalance(__insert_left, __z,
const_cast<_Base_ptr>(__p),
this->_M_impl._M_header);
++_M_impl._M_node_count;
return const_iterator(__z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
@ -954,6 +989,63 @@ namespace std
return __position; // Equivalent keys.
}
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>::
insert_unique(const_iterator __position, const _Val& __v)
{
// end()
if (__position._M_node == _M_end())
{
if (size() > 0
&& _M_impl._M_key_compare(_S_key(_M_rightmost()),
_KeyOfValue()(__v)))
return _M_insert(0, _M_rightmost(), __v);
else
return const_iterator(insert_unique(__v).first);
}
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__position._M_node)))
{
// First, try before...
const_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 const_iterator(insert_unique(__v).first);
}
else if (_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// ... then try after.
const_iterator __after = __position;
if (__position._M_node == _M_rightmost())
return _M_insert(0, _M_rightmost(), __v);
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key((++__after)._M_node)))
{
if (_S_right(__position._M_node) == 0)
return _M_insert(0, __position._M_node, __v);
else
return _M_insert(__after._M_node, __after._M_node, __v);
}
else
return const_iterator(insert_unique(__v).first);
}
else
return __position; // Equivalent keys.
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
@ -1008,6 +1100,60 @@ namespace std
}
}
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>::
insert_equal(const_iterator __position, const _Val& __v)
{
// end()
if (__position._M_node == _M_end())
{
if (size() > 0
&& !_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(_M_rightmost())))
return _M_insert(0, _M_rightmost(), __v);
else
return const_iterator(insert_equal(__v));
}
else if (!_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// First, try before...
const_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 const_iterator(insert_equal(__v));
}
else
{
// ... then try after.
const_iterator __after = __position;
if (__position._M_node == _M_rightmost())
return _M_insert(0, _M_rightmost(), __v);
else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node),
_KeyOfValue()(__v)))
{
if (_S_right(__position._M_node) == 0)
return _M_insert(0, __position._M_node, __v);
else
return _M_insert(__after._M_node, __after._M_node, __v);
}
else
return const_iterator(insert_equal(__v));
}
}
template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>
@ -1022,13 +1168,13 @@ namespace std
template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>
void
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
insert_unique(_II __first, _II __last)
{
for (; __first != __last; ++__first)
insert_unique(end(), *__first);
}
void
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
insert_unique(_II __first, _II __last)
{
for (; __first != __last; ++__first)
insert_unique(end(), *__first);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
@ -1044,6 +1190,20 @@ namespace std
--_M_impl._M_node_count;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const_iterator __position)
{
_Link_type __y =
static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
(const_cast<_Base_ptr>(__position._M_node),
this->_M_impl._M_header));
destroy_node(__y);
--_M_impl._M_node_count;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
@ -1121,6 +1281,19 @@ namespace std
erase(__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const_iterator __first, const_iterator __last)
{
if (__first == begin() && __last == end())
clear();
else
while (__first != __last)
erase(__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void