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:
parent
d66437c5fe
commit
d5e07b79f4
4 changed files with 205 additions and 35 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue