summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-05 20:52:36 +0000
committerfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-05 20:52:36 +0000
commit9de27403457ffe6d85783946fefd79b0cee63c4c (patch)
tree1bbd4deacf934478dc41ff8f89fda6c2024ef42e
parentb978e3c6ddddd482e917f1ed13abe355584a3ad2 (diff)
downloadgcc-9de27403457ffe6d85783946fefd79b0cee63c4c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168528 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/include/debug/forward_list72
-rw-r--r--libstdc++-v3/include/debug/safe_base.h10
-rw-r--r--libstdc++-v3/src/debug.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc6
5 files changed, 93 insertions, 10 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 2a2307aebc4..3e6e524d7d3 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 03b661ec221..09b0b8659f4 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -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,
diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h
index 2ebdd89b58f..1348004cb57 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -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;
+ }
};
/**
diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc
index 188495a3ea8..9074dfb0738 100644
--- a/libstdc++-v3/src/debug.cc
+++ b/libstdc++-v3/src/debug.cc
@@ -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)
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc
index 0105791bedc..486bfcf0724 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/swap.cc
@@ -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] );