From patchwork Wed Jan 5 20:58:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Patchwork-Id: 77633 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 5770BB7114 for ; Thu, 6 Jan 2011 07:58:51 +1100 (EST) Received: (qmail 2882 invoked by alias); 5 Jan 2011 20:58:47 -0000 Received: (qmail 2854 invoked by uid 22791); 5 Jan 2011 20:58:44 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from smtp6-g21.free.fr (HELO smtp6-g21.free.fr) (212.27.42.6) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 05 Jan 2011 20:58:37 +0000 Received: from localhost.localdomain (unknown [82.237.250.248]) by smtp6-g21.free.fr (Postfix) with ESMTP id 903EB8234E; Wed, 5 Jan 2011 21:58:28 +0100 (CET) Message-ID: <4D24DB73.1080104@free.fr> Date: Wed, 05 Jan 2011 21:58:27 +0100 From: =?ISO-8859-1?Q?Fran=E7ois_Dumont?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20101213 Mandriva/3.0.11-0.1mdv2010.1 (2010.1) Thunderbird/3.0.11 MIME-Version: 1.0 To: Paolo Carlini CC: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: forward_list debug swap References: <4D223092.8050502@free.fr> <4D223A8F.3030104@oracle.com> In-Reply-To: <4D223A8F.3030104@oracle.com> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This is the patch finally applied. 2011-01-05 François Dumont * 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. I realized that _M_version fields in _Safe_iterator_base and _Safe_sequence_base are useless for a sequence like the forward_list. I will consider this optimization for a future (binary incompatible) evolution of the debug mode. Regards On 01/03/2011 10:07 PM, Paolo Carlini wrote: > Ok, but please properly format the code: no overlong lines, newline > after the return type of the function and after the double colon for > member functions. > > Paolo. > > Index: src/debug.cc =================================================================== --- src/debug.cc (revision 168527) +++ src/debug.cc (working copy) @@ -257,11 +257,7 @@ _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: include/debug/safe_base.h =================================================================== --- include/debug/safe_base.h (revision 168527) +++ include/debug/safe_base.h (working copy) @@ -146,6 +146,16 @@ /** 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: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 168527) +++ include/debug/forward_list (working copy) @@ -600,9 +600,81 @@ && __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 + 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(__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 + 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 bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) Index: testsuite/23_containers/forward_list/debug/swap.cc =================================================================== --- testsuite/23_containers/forward_list/debug/swap.cc (revision 168527) +++ testsuite/23_containers/forward_list/debug/swap.cc (working copy) @@ -54,10 +54,8 @@ // 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 @@ 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] );