This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] libstdc++: istreambuf_iterator proxy


On 06/10/2017 20:00, Petr Ovtchenkov wrote:
On Fri, 6 Oct 2017 18:01:36 +0200
François Dumont <frs.dumont@gmail.com> wrote:

...
The test itself simulate "stop and go" istream usage.
stringstream is convenient for behaviuor illustration, but in "real life"
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 become
almost useless structure for practice.
Why not creating a new istreambuf_iterator each time you need to check
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

   - not directly follow from standard, just follow from (IMO wrong)
     implementations; and this is a balk for useful usage of istreambuf_iterator;
   - 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).

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 different
behaviour between debug/non-debug (like _M_sbuf->sgetc()).

The first patch fixed the impact of the Debug mode on the istreambuf_iterator state. This kind of difference is classical with Debug mode, this mode usually introduces additional calls to some operators or in this case to sgetc.

We have no choice here as otherwise we wouldn't detect that the iterator is an eof one. I might propose another patch after this one that could allow to limit the check to _M_sbuf not being null.

    - 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 possible.
I agree that we need to fix this last point too.

Consider this code:

    std::istringstream inf("abc");
    std::istreambuf_iterator<char> j(inf), eof;
    std::istreambuf_iterator<char> i = j++;

    assert( *i == 'a' );

At this point it looks like i is pointing to 'a' but then when you do:

std::string str(i, eof);

you have:
assert( str == "ac" );
No. I mean that in last (my) suggestion ([PATCH])

    std::istreambuf_iterator<char> i = j++;

is impossible ("impossible" is in aggree with standard).
So test test01() in 2.cc isn't correct.

It is correct as this constructor:
+      /// Construct start of streambuf iterator.
+      istreambuf_iterator(const proxy& __prx) _GLIBCXX_USE_NOEXCEPT
+      : _M_sbuf(__prx._M_sbuf)
+      { }

is defined by the Standard. This is why the llvm test is fine too.

What is illegal is rather something like:
++(j++);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]