On Wed, 6 May 2026 at 13:45, Tomasz Kamiński <[email protected]> wrote:
>
> We convert all contiguous ranges into span of the possibly-const qualified
> _Tp (__format::__maybe_const<_Tp, _CharT>). The span object is const qualifed,
> to trigger _M_format<const span<T>> specialization, that is already used by
> formatter specialization for ranges.
>
> This conversion is applied regardless if range is sized, and ranges::distance
> to compute the size. Even for user-defined iterators, they will observe range
> being iterated only once.
>
> Finally, using raw pointers to iterate range during formatting guarantees,
> that no stdio lock will be taken. In consequence it would be now possible
> to enable_nonlocking_formatter_optimization for all contiguous ranges.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/format (range_formatter::format): Format all
> contiguous ranges as span<__format::__maybe_const<_Tp, _CharT>>.
> ---
> For the file that formatted vector, array/span (of various sizes), and
> views adapated via them I have seen around 1s reduction. Less that I
> expected, but I think symbol reduction is valuable. And especially the
> fact that such approach could make vector use non-buffered print.
>
> I think we may want to change default enable_nonlocking_formatter_optimization
> to be true for contiguous ranges (we may need to check if there is no
> user-defined specialization formatter - check if one of our nested
> typedefs exits).
> I think that is technically non-coforming, but it is safe, and I doubt
> people will complain that print with vector is faster. Especially that
> for ranges we may need to allocate pretty large string.
>
> Testing on x86_64-linux. *format* test passed in all standard modes.
> OK for trunk when all test passes.
Yes, this is nice.
"usign spoan" -> "using span" in the first line of the commit log.
OK for trunk with that change.
>
> libstdc++-v3/include/std/format | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
> index 4627381fa9e..60adca93b5d 100644
> --- a/libstdc++-v3/include/std/format
> +++ b/libstdc++-v3/include/std/format
> @@ -6175,7 +6175,13 @@ namespace __format
> format(_Rg&& __rg, basic_format_context<_Out, _CharT>& __fc) const
> {
> using _Range = remove_reference_t<_Rg>;
> - if constexpr (__format::__simply_formattable_range<_Range, _CharT>)
> + if constexpr (ranges::contiguous_range<_Rg>)
> + {
> + const span<__format::__maybe_const<_Tp, _CharT>>
> + __spn(ranges::data(__rg), size_t(ranges::distance(__rg)));
> + return _M_format(__spn, __fc);
> + }
> + else if constexpr (__format::__simply_formattable_range<_Range,
> _CharT>)
> return _M_format<const _Range>(__rg, __fc);
> else
> return _M_format(__rg, __fc);
> --
> 2.54.0
>