re PR libstdc++/24975 (Aliasing problems inside libstdc++)
authorPaolo Carlini <pcarlini@suse.de>
Tue, 22 Nov 2005 14:53:03 +0000 (14:53 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 22 Nov 2005 14:53:03 +0000 (14:53 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_tree.h

index 96652d2b153d17acaa1f60a3098d1906730fafd7..8517757ea00339efe3d76316ce46028ddd147281 100644 (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>
 
index 196c40205755470928df5834945cd23c2122f367..185f51ce989ffb2b7d2eccea265bb06ae581d1f0 100644 (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
index 2a240e19604ebfb9bfa0d3137b43331ec271b381..1172e509311eece15698cf96aa3d21c792818d3d 100644 (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
index 45d27b50b2aecf15dda9d281920db497ed91f825..13088ca75550d298c9d2992af533fb307b8a867b 100644 (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