From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 117440 invoked by alias); 15 Oct 2019 20:20:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 117424 invoked by uid 89); 15 Oct 2019 20:20:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy=nach X-HELO: mail-wm1-f67.google.com Received: from mail-wm1-f67.google.com (HELO mail-wm1-f67.google.com) (209.85.128.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 15 Oct 2019 20:20:35 +0000 Received: by mail-wm1-f67.google.com with SMTP id p7so413603wmp.4; Tue, 15 Oct 2019 13:20:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:references:message-id:date:user-agent:mime-version :in-reply-to:content-language; bh=IYVDxWycjHI5WUD9L4orA+RG0KP8+DkCXPgDSWpg5II=; b=kpmda+0AjE8xFrgNvBK+jRFdCd1WrK8BYcpOiDalWRIKJ+8A6tNLhRa8IZRsIlSbKk 28vLidKS1ULI/thrFzilLq2ermP+92IxwBV+IiygKixLS3aLQtd8lpbB/gItXmS9q6DM yOGqHOiOrSAOtAqIPBnQ2nf+8WUCOaL5ahD/Cwi2SlblXDctlzne1gjHHQkzVQVG51oq PGMoK6sNyONBCNADlZ6rWjy1ObtG2hbgAShItJCJbwwzI6OqEpdYbAns8bnxYt0CgJaP HrYkqVVsUXdw+/TM1WFc7e9vlZD5UQQ8AnRtj0U86+Qg3RTDNYM6c94IB3fjnw1Am9ks DdCA== Return-Path: Received: from ?IPv6:2a01:e0a:1dc:b1c0:ed26:858c:8d9b:85b? ([2a01:e0a:1dc:b1c0:ed26:858c:8d9b:85b]) by smtp.googlemail.com with ESMTPSA id n22sm280833wmk.19.2019.10.15.13.20.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Oct 2019 13:20:31 -0700 (PDT) Subject: Re: [PATCH] Implement std::advance for istreambuf_iterator using pubseekoff From: =?UTF-8?Q?Fran=c3=a7ois_Dumont?= To: "libstdc++@gcc.gnu.org" , gcc-patches References: <5531cf67-62b3-a4bc-c611-0fe026b75066@gmail.com> Message-ID: <00a8f27e-cc72-9852-45b3-1a1082d25ea2@gmail.com> Date: Tue, 15 Oct 2019 20:31:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <5531cf67-62b3-a4bc-c611-0fe026b75066@gmail.com> Content-Type: multipart/mixed; boundary="------------FC4438ACDC91CE69C72D666A" X-SW-Source: 2019-10/txt/msg01132.txt.bz2 This is a multi-part message in MIME format. --------------FC4438ACDC91CE69C72D666A Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-length: 892 Here is an update to set _M_sbuf to null if the user advance too much. Note that in this case the streambuf remains un-modified which is different from the current implementation. I think it is another enhancement. I also change the Debug assertion message for something more dedicated to std::advance algo. François On 10/14/19 10:12 PM, François Dumont wrote: > The same way I proposed to review std::copy overload for > istreambuf_iterator we can implement std::advance using pubseekoff. > > It is both a cleaner implementation and avoids yet another friend > declaration. > > >     * include/std/streambuf >     (advance(istreambuf_iterator<>&, _Distance)): Remove friend > declaration. >     * include/bits/streambuf_iterator.h (__copy_move_a2): Re-implement > using >     streambuf pubseekoff. > > Tested under Linux x86_64. > > Ok to commit ? > > François > --------------FC4438ACDC91CE69C72D666A Content-Type: text/x-patch; name="istreambuf_ite_advance.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="istreambuf_ite_advance.patch" Content-length: 4445 diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 134b3486b9a..17dd3972d45 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -431,37 +431,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_assert(__n > 0); __glibcxx_requires_cond(!__i._M_at_eof(), - _M_message(__gnu_debug::__msg_inc_istreambuf) - ._M_iterator(__i)); - - typedef istreambuf_iterator<_CharT> __is_iterator_type; - typedef typename __is_iterator_type::traits_type traits_type; - typedef typename __is_iterator_type::streambuf_type streambuf_type; - typedef typename traits_type::int_type int_type; - const int_type __eof = traits_type::eof(); - - streambuf_type* __sb = __i._M_sbuf; - while (__n > 0) - { - streamsize __size = __sb->egptr() - __sb->gptr(); - if (__size > __n) + _M_message(__gnu_debug::__msg_advance_oob) + ._M_iterator(__i) + ._M_integer(__n)); + + typedef basic_streambuf<_CharT> __streambuf_t; + typedef typename __streambuf_t::pos_type __pos_t; + __pos_t __cur_pos + = __i._M_sbuf->pubseekoff(0, ios_base::cur, ios_base::in); + __pos_t __new_pos + = __i._M_sbuf->pubseekoff(__n, ios_base::cur, ios_base::in); + __i._M_c = char_traits<_CharT>::eof(); + + if (__new_pos - __cur_pos != __n) { - __sb->__safe_gbump(__n); - break; - } - - __sb->__safe_gbump(__size); - __n -= __size; - if (traits_type::eq_int_type(__sb->underflow(), __eof)) - { - __glibcxx_requires_cond(__n == 0, - _M_message(__gnu_debug::__msg_inc_istreambuf) - ._M_iterator(__i)); - break; - } + __i._M_sbuf = 0; + __glibcxx_requires_cond(!__i._M_at_eof(), + _M_message(__gnu_debug::__msg_advance_oob) + ._M_iterator(__i) + ._M_integer(__n)); } - - __i._M_c = __eof; } // @} group iterators diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index 3442f19bd78..ef03da39bc2 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -155,11 +155,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); - template - friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, - void>::__type - advance(istreambuf_iterator<_CharT2>&, _Distance); - template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc new file mode 100644 index 00000000000..8763e7fa78e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2017-2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// Debug mode would detect the invalid std::advance call. +// { dg-require-normal-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + istringstream iss1(data1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( beg1 != end1 ); + + advance(beg1, sizeof(data1)); + + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} --------------FC4438ACDC91CE69C72D666A--