This v2 addresses all review comments from Tomasz Kaminski on v1:

- Max/counting logic moved entirely from _Streambuf_sink (base) into
  _Iter_sink<ostreambuf_iterator> (specialization).  _Streambuf_sink
  is now a pure I/O layer with no counters, no _M_max, and no _S_failed
  state - failure is tracked solely by ostreambuf_iterator::_M_failed.

- _M_discarding() returns false.
  format_to_n needs the formatter to keep producing output so we can
  count the total hypothetical output length.

- _M_overflow() is overridden in the _Iter_sink specialization,
  counting all characters and adjusting what is actually
  committed (via _M_put or pbump) to stay within the limit,
  without shrinking the buffer.

- A protected _M_pbump helper in _Streambuf_sink avoids derived
  classes needing direct friendship to basic_streambuf.

The _Streambuf_sink itself is simplified: no _M_bump override, no
_M_commit_put_area, no _M_do_flush.  Put-area writes accumulate
in _M_used() and are committed in _M_overflow via a single pbump.
The _Iter_sink specialization handles all counting and truncation.

Performance (header-overlay A/B, single core, BABA interleave):

  scenario                        16 B    64 B    256 B   1024 B  4096 B
  print(ostream, "{}", x)         0.98x   1.01x   1.02x   1.02x   1.02x
  format_to(back_inserter, ...)   1.02x   0.98x   1.00x   0.93x   0.96x
  format_to(ostreambuf_iter, ...) 1.51x   3.16x  12.59x  51.53x 121.07x
    with width/padding spec       1.08x   1.10x   1.09x   1.08x   1.06x
    multi-arg ("_{}_...")         1.21x   2.18x   2.56x   4.60x  14.38x
    append mode                    -      3.82x  11.38x  32.33x     -
    to filebuf (/dev/null)        1.58x   4.30x  10.36x  19.65x  22.12x
    to streambuf w/o put area       -       -    16.74x  17.12x  17.87x
  format_to_n(ostreambuf_iter,
    max=len/4, ...)                 -     1.40x   4.23x   6.79x     -
    max=len*2, ...)                 -     4.33x  14.26x  52.49x     -

Perf stat for the primary fmt_to path:

  len    instr%  cycles%  b_IPC  a_IPC
  16     77.2%    63.1%   2.21   2.70
  64     39.5%    31.5%   1.61   2.01
  256    14.6%     7.9%   1.36   2.52
  1024    4.1%     1.8%   1.34   3.08
  4096    1.8%     0.8%   1.33   2.86

Anlai Lu (3):
  libstdc++: Add tests for format_to with ostreambuf_iterator
  libstdc++: Add _Streambuf_sink for direct streambuf formatting
  libstdc++: Specialize _Iter_sink for ostreambuf_iterator

 .../include/bits/streambuf_iterator.h         |   7 +
 libstdc++-v3/include/std/format               | 184 ++++++++++++++++
 libstdc++-v3/include/std/streambuf            |   4 +
 .../format/functions/format_to_ostreambuf.cc  | 244 ++++++++++++++++++
 4 files changed, 439 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/std/format/functions/format_to_ostreambuf.cc

--
2.34.1

Reply via email to