OSDN Git Service

2011-01-05 Fran├žois Dumont <francois.cppdevs@free.fr>
authorfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Jan 2011 20:52:36 +0000 (20:52 +0000)
committerfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Jan 2011 20:52:36 +0000 (20:52 +0000)
        * include/debug/safe_base.h (_Safe_iterator_base::_M_unlink): New.
        * include/src/debug.cc: Use latter
        * include/debug/forward_list (forward_list<>::_M_swap):  Fix to
        correctly handle before_begin iterators.
        * testsuite/23_containers/forward_list/debug/swap.cc: Remove now
        useless _GLIBCXX_DEBUG checks.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168528 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/debug/forward_list
libstdc++-v3/include/debug/safe_base.h
libstdc++-v3/src/debug.cc
libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc

index 2a2307a..3e6e524 100644 (file)
@@ -1,3 +1,12 @@
+2011-01-05  Fran├žois Dumont  <francois.cppdevs@free.fr>
+
+       * include/debug/safe_base.h (_Safe_iterator_base::_M_unlink): New.
+       * include/src/debug.cc: Use latter
+       * include/debug/forward_list (forward_list<>::_M_swap):  Fix to
+       correctly handle before_begin iterators.
+       * testsuite/23_containers/forward_list/debug/swap.cc: Remove now
+       useless _GLIBCXX_DEBUG checks.
+
 2011-01-04  Kai Tietz  <kai.tietz@onevision.com>
 
        PR libstdc++/47145
index 03b661e..09b0b86 100644 (file)
@@ -600,8 +600,80 @@ namespace __debug
                   && __it != this->_M_base().cend();
          });
       }
+      typedef __gnu_debug::_Safe_iterator_base _Safe_iterator_base;
+      static void
+      _M_swap_aux(forward_list& __lhs,
+                 _Safe_iterator_base*& __lhs_iterators,
+                 forward_list& __rhs,
+                 _Safe_iterator_base*& __rhs_iterators);
+      void _M_swap(forward_list& __list);
     };
 
+   template<typename _Tp, typename _Alloc>
+    void
+    forward_list<_Tp, _Alloc>::
+    _M_swap_aux(forward_list<_Tp, _Alloc>& __lhs,
+               __gnu_debug::_Safe_iterator_base*& __lhs_iterators,
+               forward_list<_Tp, _Alloc>& __rhs,
+               __gnu_debug::_Safe_iterator_base*& __rhs_iterators)
+    {
+      using __gnu_debug::_Safe_iterator_base;
+      _Safe_iterator_base* __bbegin_its = 0;
+      _Safe_iterator_base* __last_bbegin = 0;
+      for (_Safe_iterator_base* __iter = __lhs_iterators; __iter;)
+       {
+         // Even iterator are casted to const_iterator, not a problem.
+         const_iterator* __victim = static_cast<const_iterator*>(__iter);
+         __iter = __iter->_M_next;
+         if (__victim->base() == __rhs._M_base().cbefore_begin())
+           {
+             __victim->_M_unlink();
+             if (__lhs_iterators == __victim)
+               __lhs_iterators = __victim->_M_next;
+             if (__bbegin_its)
+               {
+                 __victim->_M_next = __bbegin_its;
+                 __bbegin_its->_M_prior = __victim;
+               }
+             else
+               __last_bbegin = __victim;
+             __bbegin_its = __victim;
+           }
+         else
+           __victim->_M_sequence = &__lhs;
+       }
+
+      if (__bbegin_its)
+       {
+         if (__rhs_iterators)
+           {
+             __rhs_iterators->_M_prior = __last_bbegin;
+             __last_bbegin->_M_next = __rhs_iterators;
+           }
+         __rhs_iterators = __bbegin_its;
+       }
+    }
+
+  /* Special forward_list _M_swap version that do not swap the
+   * before-begin ownership.*/
+  template<typename _Tp, typename _Alloc>
+    void
+    forward_list<_Tp, _Alloc>::
+    _M_swap(forward_list<_Tp, _Alloc>& __list)
+    {
+      __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
+      std::swap(this->_M_iterators, __list._M_iterators);
+      std::swap(this->_M_const_iterators, __list._M_const_iterators);
+      // Useless, always 1 on forward_list
+      //std::swap(this->_M_version, __list._M_version);
+      _Safe_iterator_base* __this_its = this->_M_iterators;
+      _M_swap_aux(__list, __list._M_iterators, *this, this->_M_iterators);
+      _Safe_iterator_base* __this_const_its = this->_M_const_iterators;
+      _M_swap_aux(__list, __list._M_const_iterators, *this, this->_M_const_iterators);
+      _M_swap_aux(*this, __this_its, __list, __list._M_iterators);
+      _M_swap_aux(*this, __this_const_its, __list, __list._M_const_iterators);
+    }
+
   template<typename _Tp, typename _Alloc>
     bool
     operator==(const forward_list<_Tp, _Alloc>& __lx,
index 2ebdd89..1348004 100644 (file)
@@ -146,6 +146,16 @@ namespace __gnu_debug
     /** Reset all member variables */
     void
     _M_reset() throw ();
+
+    /** Unlink itself */
+    void
+    _M_unlink() throw ()
+    {
+      if (_M_prior)
+       _M_prior->_M_next = _M_next;
+      if (_M_next)
+       _M_next->_M_prior = _M_prior;
+    }
   };
 
   /**
index 188495a..9074dfb 100644 (file)
@@ -257,11 +257,7 @@ namespace __gnu_debug
   _M_detach_single(_Safe_iterator_base* __it) throw ()
   {
     // Remove __it from this sequence's list
-    if (__it->_M_prior)
-      __it->_M_prior->_M_next = __it->_M_next;
-    if (__it->_M_next)
-      __it->_M_next->_M_prior = __it->_M_prior;
-       
+    __it->_M_unlink();
     if (_M_const_iterators == __it)
       _M_const_iterators = __it->_M_next;
     if (_M_iterators == __it)
index 0105791..486bfcf 100644 (file)
@@ -54,10 +54,8 @@ test01()
   // before-begin iterator is not transfered:
   // TODO: Validate with LWG group how before begin should be
   // treated.
-#if !_GLIBCXX_DEBUG
   VERIFY( fit == fl1_its[0] );
-#endif
-  // All others are, even paste-the-end one:
+  // All other iterators are, even paste-the-end ones:
   for (size_t i = 1; i != fl2_its.size(); ++i)
   {
     VERIFY( ++fit == fl2_its[i] );
@@ -66,9 +64,7 @@ test01()
   fit = fl2.before_begin();
   // TODO: Validate with LWG group how before begin should be
   // treated.
-#if !_GLIBCXX_DEBUG
   VERIFY( fit == fl2_its[0] );
-#endif
   for (size_t i = 1; i != fl1_its.size(); ++i)
   {
     VERIFY( ++fit == fl1_its[i] );