Add partial specialization of _Iter_sink for ostreambuf_iterator
that inherits _Streambuf_sink, replacing per-character sputc with
bulk sputn and zero-copy put-area writes.
libstdc++-v3/ChangeLog:
* include/std/format (_Iter_sink): Add partial specialization
for ostreambuf_iterator.
Signed-off-by: Anlai Lu <[email protected]>
---
libstdc++-v3/include/std/format | 38 +++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index a449efd45..3ed91a9ce 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3899,6 +3899,44 @@ namespace __format
}
};
+ // Specialization for ostreambuf_iterator that inherits _Streambuf_sink
+ // for bulk sputn writes instead of per-character sputc.
+ template<typename _CharT, typename _Traits>
+ class _Iter_sink<_CharT, ostreambuf_iterator<_CharT, _Traits>>
+ : public _Streambuf_sink<_CharT, _Traits>
+ {
+ using _Base = _Streambuf_sink<_CharT, _Traits>;
+ ostreambuf_iterator<_CharT, _Traits> _M_out;
+
+ void
+ _M_overflow() override
+ {
+ _Base::_M_overflow();
+ if (this->_M_has_failed()) [[unlikely]]
+ _M_out._M_set_failed();
+ }
+
+ public:
+ explicit
+ _Iter_sink(ostreambuf_iterator<_CharT, _Traits> __out,
+ iter_difference_t<ostreambuf_iterator<_CharT, _Traits>>
+ __max = -1)
+ : _Base(__out._M_get_sbuf(), __max), _M_out(__out)
+ {
+ if (__out.failed())
+ this->_M_set_failed();
+ }
+
+ using _Base::out;
+
+ format_to_n_result<ostreambuf_iterator<_CharT, _Traits>>
+ _M_finish() &&
+ {
+ _Iter_sink::_M_overflow();
+ return {_M_out, this->_M_total_chars()};
+ }
+ };
+
// Used for contiguous iterators.
// No buffer is used, characters are written straight to the iterator.
// We do not know the size of the output range, so the span size just grows
--
2.34.1