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