2005-11-23 Paolo Carlini PR libstdc++/24975 (basic_string) * include/bits/basic_string.h (_Rep::_S_empty_rep): Avoid strict-aliasing warnings. 2005-11-22 Paolo Carlini 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(&_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 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 _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 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator @@ -928,6 +976,54 @@ namespace std } } +#if __GNUC__ >= 4 + template + 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 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator @@ -974,6 +1070,54 @@ namespace std } } +#if __GNUC__ >= 4 + template + 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 template @@ -1008,6 +1152,20 @@ namespace std --_M_impl._M_node_count; } +#if __GNUC__ >= 4 + template + 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 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type @@ -1082,6 +1240,20 @@ namespace std while (__first != __last) erase(__first++); } +#if __GNUC__ >= 4 + template + 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 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 } /**