On Tue, Jun 30, 2026 Tomasz Kaminski wrote:
>
> This !ok() checks are already handled by internal debug mode ...
>
> Passing a format string should not be necessary, for all formatter
> specializations, the "{}" is already equivalent to the output of
> the operator<< ...
>
> This should not be needed, simple "{}" should work.
>
> Did you run into any problems with the above?
Thanks for the detailed review -- the suggestions were very helpful.
On the ok() point: the commit message was poorly worded. What I meant
was that by switching to _S_empty_fs(), the operator<< implementations
become trivial one-liners that no longer need to manually handle ok() /
substr() / c_encoding() branches. I have reworded the commit message
in v3 to avoid the ambiguity.
On dropping the format string parameter: I tested _S_empty_fs() across
C, en_US, de_DE, fr_FR, and zh_CN locales, including subsecond precision
where the locale determines the decimal separator. You were right, it
works for all types. I had not fully thought through the mechanism at
first, but I understand it now.
The new __chrono_write is just:
template<typename _CharT, typename _Traits, typename _Arg,
typename... _OptLocale>
__chrono_write(basic_ostream<_CharT, _Traits>& __os,
const _Arg& __arg, const _OptLocale&... __loc)
{
static_assert(sizeof...(_OptLocale) <= 1);
using _Fmt = __format::__formatter_chrono<_CharT>;
...
auto __res = std::format_to_n(__buf, __bufsize, __loc...,
_Fmt::_S_empty_fs(), __arg);
...
}
No format string parameter, no __empty_fmt, and using std::format_to_n
instead of __do_vformat_to_n.
I also went through the remaining operator<< overloads that were still
using basic_stringstream and converted them to __chrono_write as well.
These were missed in v2 because I was narrowly focused on the existing
std::format / std::vformat call sites and did not do a comprehensive
sweep at the time.
I have posted a v3 with these changes:
[PATCH v3 0/2] libstdc++: Optimize chrono ostream insertion
via __chrono_write
Thanks again for the _S_empty_fs() suggestion in v1 -- it turned out
to be the key that made all of these simplifications possible.