Skip to content

iostreams

Malachi edited this page Oct 18, 2023 · 11 revisions

Streambufs

Generally speaking these eschew virtual functions and furthermore deviate from stock std streambufs in the following ways:

  • direct buffer access is public, so eback, pbase, gptr etc are fully accessible
  • overflow and underflow also public accessible, to facilitate easier non blocking behavior
    • remember underflow grabs any next buffer sequence if need be but does not advance character forward like uflow does
  • peek and friends operate slightly differently to be more non-blocking friendly (more on this later)
  • input and output streambufs are fully decoupled so you only incur overhead for the variety you use
  • TBase style hierarchy so that you may combine input and output together to form a more traditional streambuf if desired

In the following ways, it's congruent, if not identical:

  • in_avail operates in the dumb way described in std:
    • -1 for definitely no characters available
    • 0 for maybe/maybe not
    • > 0 if definitely that # is available
    • note that our in_avail() is quite serious when it returns -1 , possibly more so than std. One gets the impression std you might later call in_avail() after it returns -1 and it might give you > 0. Not so with ours

Streambuf impl

To compensate for lack of virtual functions, streambufs use an impl paradigm. More on this later

Provided streambufs

out_span_streambuf

in_span_streambuf

out_stringbuf

in_stringbuf

IOS

ostream and istream accept a directly embedded templatized streambuf rather than a pointer (though being template driven, a reference is viable also)

ostream

operator << has some implementation. More on this later

istream

operator >> is very unimplemented. PR anyone?

Experimental non-blocking

Experimenting with streambuf whose calls take a bool blocking flag, defaulting to true. This affords us the possibility to technically be API compatible with extensions that are familiar. The downside is the calls for nonblocking are a little ugly, i.e.:

rdbuf()->sbump(false);

At the istream and ostream level though it's theoretically possible (and fitting with their architecture) to hide all that with a blocking flag tracked at the instance level.

Iterators

istreambuf_iterator

We deviate slightly from std flavor in support of non-blocking behavior. We return int_type from char traits rather than CharT. This is to facilitate returning eof. Thought process is: end iterator marks just what it always does, while eof means no data at the moment.