On Mon, Jul 6, 2026 at 6:28 AM Anlai Lu <[email protected]> wrote:
> 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)
>
As mentioned, I would try to put handling of the maximim value in this
specialization.
> + : _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()};
>
I think we need to restore the failed state to the iterator. I would do
that via the constructor.
> + }
> + };
> +
> // 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
>
>