This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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: [RFC] Strive to prefer sbumpc() to snextc()?!?


Paolo Carlini wrote:
> Now, my question is: shall we actually strive to avoid snextc()??

It is currently possible to implement an unbuffered streambuf for input
by overloading uflow() and underflow(), but not pbackfail(), so I don't
think that using sungetc() or sputbackc() is a good idea.

The best solution may be to use neither sbumpc() nor snextc(), but
instead access the buffer directly, similar to what is already done
in __copy_streambufs:

      while (!_Traits::eq_int_type(__c, _Traits::eof()))
        {
          const size_t __n = __sbin->egptr() - __sbin->gptr();
          if (__n > 1)
            {
              const char_type* p = traits_type::find(__sbin->gptr(),
                __n, __delim);
              if (p)
                 __n = p - __sbin->gptr();
              __str.append(__sbin->gptr(), __n);
              __sbin->gbump(__n);

In most cases, this should cause only a single call to append.

The same trick can be used in istream::sentry and ws to find the next
non-whitespace (using ctype::scan_not instead of traits::find), and in
operator>>(istream, string) to find the next whitespace (using
ctype::scan_is). Using scan_not and scan_is would also avoid a virtual
function call to ctype::do_is for each character when char_type isn't
char.

It may even be possible to avoid duplicating the loop, by wrapping it
in a template function that takes two function objects; one for deciding
when to stop, and the other for writing the characters to their
destination.

Regards,
Petur


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