Blob Blame History Raw
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
       }
 
       /**