2005-11-23 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/24975 (basic_string)
* include/bits/basic_string.h (_Rep::_S_empty_rep): Avoid
strict-aliasing warnings.
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.
--- libstdc++-v3/include/bits/basic_string.h.jj 2007-02-23 21:29:15.000000000 +0100
+++ libstdc++-v3/include/bits/basic_string.h 2007-07-19 12:11:40.000000000 +0200
@@ -175,7 +175,16 @@ namespace std
static _Rep&
_S_empty_rep()
- { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
+ {
+#if __GNUC__ >= 4
+ // Work around type-punning warning in g++4. _S_empty_rep_storage
+ // is never modified, so type-punning is ok.
+ void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
+ return *reinterpret_cast<_Rep*>(__p);
+#else
+ return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage);
+#endif
+ }
bool
_M_is_leaked() const
--- libstdc++-v3/include/bits/stl_tree.h.jj 2007-02-23 21:29:15.000000000 +0100
+++ libstdc++-v3/include/bits/stl_tree.h 2007-07-19 13:18:28.000000000 +0200
@@ -532,6 +532,12 @@ namespace std
iterator
_M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
+#if __GNUC__ >= 4
+ const_iterator
+ _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y,
+ const value_type& __v);
+#endif
+
_Link_type
_M_copy(_Const_Link_type __x, _Link_type __p);
@@ -631,9 +637,19 @@ namespace std
iterator
insert_unique(iterator __position, const value_type& __x);
+#if __GNUC__ >= 4
+ const_iterator
+ insert_unique(const_iterator __position, const value_type& __x);
+#endif
+
iterator
insert_equal(iterator __position, const value_type& __x);
+#if __GNUC__ >= 4
+ const_iterator
+ insert_equal(const_iterator __position, const value_type& __x);
+#endif
+
template<typename _InputIterator>
void
insert_unique(_InputIterator __first, _InputIterator __last);
@@ -645,12 +661,22 @@ namespace std
void
erase(iterator __position);
+#if __GNUC__ >= 4
+ void
+ erase(const_iterator __position);
+#endif
+
size_type
erase(const key_type& __x);
void
erase(iterator __first, iterator __last);
+#if __GNUC__ >= 4
+ void
+ erase(const_iterator __first, const_iterator __last);
+#endif
+
void
erase(const key_type* __first, const key_type* __last);
@@ -793,6 +819,28 @@ namespace std
return iterator(__z);
}
+#if __GNUC__ >= 4
+ 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)
+ {
+ _Link_type __z = _M_create_node(__v);
+ bool __insert_left;
+
+ __insert_left = __x != 0 || __p == _M_end()
+ || _M_impl._M_key_compare(_KeyOfValue()(__v),
+ _S_key(__p));
+
+ _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);
+ }
+#endif
+
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
@@ -928,6 +976,54 @@ namespace std
}
}
+#if __GNUC__ >= 4
+ 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)
+ {
+ if (__position._M_node == _M_leftmost())
+ {
+ // begin()
+ if (size() > 0
+ && _M_impl._M_key_compare(_KeyOfValue()(__v),
+ _S_key(__position._M_node)))
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // First argument just needs to be non-null.
+ else
+ return const_iterator(insert_unique(__v).first);
+ }
+ else if (__position._M_node == _M_end())
+ {
+ // end()
+ if (_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
+ {
+ const_iterator __before = __position;
+ --__before;
+ if (_M_impl._M_key_compare(_S_key(__before._M_node),
+ _KeyOfValue()(__v))
+ && _M_impl._M_key_compare(_KeyOfValue()(__v),
+ _S_key(__position._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);
+ // First argument just needs to be non-null.
+ }
+ else
+ return const_iterator(insert_unique(__v).first);
+ }
+ }
+#endif
+
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator
@@ -974,6 +1070,54 @@ namespace std
}
}
+#if __GNUC__ >= 4
+ 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)
+ {
+ if (__position._M_node == _M_leftmost())
+ {
+ // begin()
+ if (size() > 0
+ && !_M_impl._M_key_compare(_S_key(__position._M_node),
+ _KeyOfValue()(__v)))
+ return _M_insert(__position._M_node, __position._M_node, __v);
+ // first argument just needs to be non-null
+ else
+ return const_iterator(insert_equal(__v));
+ }
+ else if (__position._M_node == _M_end())
+ {
+ // end()
+ if (!_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
+ {
+ const_iterator __before = __position;
+ --__before;
+ if (!_M_impl._M_key_compare(_KeyOfValue()(__v),
+ _S_key(__before._M_node))
+ && !_M_impl._M_key_compare(_S_key(__position._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);
+ // First argument just needs to be non-null.
+ }
+ else
+ return const_iterator(insert_equal(__v));
+ }
+ }
+#endif
+
template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>
@@ -1008,6 +1152,20 @@ namespace std
--_M_impl._M_node_count;
}
+#if __GNUC__ >= 4
+ 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;
+ }
+#endif
+
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type
@@ -1082,6 +1240,20 @@ namespace std
while (__first != __last) erase(__first++);
}
+#if __GNUC__ >= 4
+ 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++);
+ }
+#endif
+
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
--- libstdc++-v3/include/bits/stl_multiset.h.jj 2007-02-23 21:29:15.000000000 +0100
+++ libstdc++-v3/include/bits/stl_multiset.h 2007-07-19 12:30:47.000000000 +0200
@@ -328,8 +328,12 @@ namespace _GLIBCXX_STD
iterator
insert(iterator __position, const value_type& __x)
{
+#if __GNUC__ >= 4
+ return _M_t.insert_equal(__position, __x);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
return _M_t.insert_equal((_Rep_iterator&)__position, __x);
+#endif
}
/**
@@ -358,8 +362,12 @@ namespace _GLIBCXX_STD
void
erase(iterator __position)
{
+#if __GNUC__ >= 4
+ _M_t.erase(__position);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__position);
+#endif
}
/**
@@ -391,8 +399,12 @@ namespace _GLIBCXX_STD
void
erase(iterator __first, iterator __last)
{
+#if __GNUC__ >= 4
+ _M_t.erase(__first, __last);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+#endif
}
/**
--- libstdc++-v3/include/bits/stl_set.h.jj 2007-02-23 21:29:15.000000000 +0100
+++ libstdc++-v3/include/bits/stl_set.h 2007-07-19 12:23:57.000000000 +0200
@@ -337,8 +337,12 @@ namespace _GLIBCXX_STD
iterator
insert(iterator __position, const value_type& __x)
{
+#if __GNUC__ >= 4
+ return _M_t.insert_unique(__position, __x);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
return _M_t.insert_unique((_Rep_iterator&)__position, __x);
+#endif
}
/**
@@ -366,8 +370,12 @@ namespace _GLIBCXX_STD
void
erase(iterator __position)
{
+#if __GNUC__ >= 4
+ _M_t.erase(__position);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__position);
+#endif
}
/**
@@ -398,8 +406,12 @@ namespace _GLIBCXX_STD
void
erase(iterator __first, iterator __last)
{
+#if __GNUC__ >= 4
+ _M_t.erase(__first, __last);
+#else
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
+#endif
}
/**