From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 48712 invoked by alias); 6 Oct 2017 18:00:56 -0000 Mailing-List: contact libstdc++-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libstdc++-owner@gcc.gnu.org Received: (qmail 48581 invoked by uid 89); 6 Oct 2017 18:00:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL,BAYES_00,KAM_INFOUSMEBIZ,KAM_LAZY_DOMAIN_SECURITY,KAM_WEIRDTRICK1,RDNS_DYNAMIC autolearn=no version=3.3.2 spammy=expectations, H*M:info, life, advised X-Spam-User: qpsmtpd, 2 recipients X-HELO: void-ptr.info Received: from pppoe.185.44.68.223.lanport.ru (HELO void-ptr.info) (185.44.68.223) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Oct 2017 18:00:53 +0000 Received: from ptr by void-ptr.info with local (Exim 4.72) (envelope-from ) id 1e0WvZ-0006aR-SC; Fri, 06 Oct 2017 21:00:49 +0300 Date: Fri, 06 Oct 2017 18:00:00 -0000 From: Petr Ovtchenkov To: =?utf-8?Q?Fran=C3=A7ois?= Dumont Cc: libstdc++@gcc.gnu.org, gcc-patches Subject: Re: [PATCH] libstdc++: istreambuf_iterator proxy (was: keep attached streambuf) Message-ID: <20171006210049.2c2aea89@void-ptr.info> In-Reply-To: <41ed5a91-9b23-97a4-ab38-4728091279d7@gmail.com> References: <20170928103425.GG4582@redhat.com> <20170928150643.2f667ec9@void-ptr.info> <20170928123806.GN4582@redhat.com> <20171003233927.6b5a151c@void-ptr.info> <41ed5a91-9b23-97a4-ab38-4728091279d7@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2017-10/txt/msg00030.txt.bz2 On Fri, 6 Oct 2017 18:01:36 +0200 Fran=C3=A7ois Dumont wrote: > ... > >>> The test itself simulate "stop and go" istream usage. > >>> stringstream is convenient for behaviuor illustration, but in "real l= ife" > >>> I can assume socket or tty on this place. > >> At the very minimum we should have a comment in the test explaining > >> how it relies on non-standard, non-portable behaviour. > >> > >> But I'd prefer to avoid introducing more divergence from other > >> implementations. > > Standard itself say nothting about "stop and go" scenario. > > At least I don't see any words pro or contra. > > But current implementation block usage of istreambuf_iterator > > with underlying streams like socket or tty, so istreambuf_iterator beco= me > > almost useless structure for practice. > Why not creating a new istreambuf_iterator each time you need to check=20 > that streambuf is not in eof anymore ? It's strange question. Because EOL (end-of-life) for istreambuf_iterator object after EOF of associated streambuf=20 - not directly follow from standard, just follow from (IMO wrong) implementations; and this is a balk for useful usage of istreambuf_iter= ator; - violate expectations from point of view of C++ objects life cycle; - require destruction and construction of istreambuf_iterator object after check for equality with istreambuf_iterator() (strange trick). >=20 > > We have three issues with istreambuf_iterator: > > - debug-dependent behaviour > Fixed. + __glibcxx_requires_cond(_M_sbuf, _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); vs + __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); and + __glibcxx_requires_cond(_M_sbuf + && !traits_type::eq_int_type(_M_c,traits_type::eof()), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); vs + __glibcxx_requires_cond(_M_sbuf && !_S_is_eof(_M_sbuf->sgetc()), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); I'm insist on the first variant. It free from code that may lead to differe= nt behaviour between debug/non-debug (like _M_sbuf->sgetc()). > > - EOL of istreambuf_iterator when it reach EOF (but this not mean > > EOL of associated streambuf) > Controversial. > > - postfix increment operator return istreambuf_iterator, but here > > expected restricted type, that accept only dereference, if it poss= ible. > I agree that we need to fix this last point too. >=20 > Consider this code: >=20 > =C2=A0 std::istringstream inf("abc"); > =C2=A0 std::istreambuf_iterator j(inf), eof; > =C2=A0 std::istreambuf_iterator i =3D j++; >=20 > =C2=A0 assert( *i =3D=3D 'a' ); >=20 > At this point it looks like i is pointing to 'a' but then when you do: >=20 > std::string str(i, eof); >=20 > you have: > assert( str =3D=3D "ac" ); No. I mean that in last (my) suggestion ([PATCH]) std::istreambuf_iterator i =3D j++; is impossible ("impossible" is in aggree with standard). So test test01() in 2.cc isn't correct. >=20 > We jump other the 'b'. >=20 > We could improve the situation by adding a debug assertion that _M_c is=20 > eof when pre-increment is being used or by changing semantic of=20 > pre-increment to only call sbumpc if _M_c is eof. But then we would need= =20 > to consider _M_c in find overload and in some other places in the lib I=20 > think. >=20 > Rather than going through this complicated path I agree with Petr that=20 > we need to simply implement the solution advised by the Standard with=20 > the nested proxy type. >=20 > This is what I have done in the attached patch in a naive way. Do we=20 > need to have abi compatibility here ? If so I'll rework it. >=20 > This patch will make libstdc++ pass the llvm test. I even duplicate it=20 > on our side with a small refinement to check for the return value of the= =20 > proxy::operator*(). >=20 > Fran=C3=A7ois >=20 -- - ptr