https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117214

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |14.3

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Fixed on trunk so far.

This actually reveals a bigger problem, which is that we should really use
_M_locale_fmt for any format that is defined in terms of "the locale's ..."

My current implementation uses __timepunct to get the locale's info like D_FMT
etc., but that's for the C locale. The C++ formatting locale could have a
custom std::time_put that does something different:

#include <locale>
#include <format>
#include <chrono>
#include <iostream>

int main()
{
  struct time_put : std::time_put<char>
  {
    iter_type
    do_put(iter_type out, std::ios_base& io, char_type fill, const tm* t,
        char format, char modifier) const override
    {
      using Base = std::time_put<char>;

      if (format == 'a') // %a %b %e %H:%M:%S %Y
        *out++ = '!';
      return Base::do_put(out, io, fill, t, format, modifier);
    }
  };

  std::locale loc(std::locale::classic(), new time_put);
  std::cout << std::format(loc, "{:L%a}", std::chrono::Monday) << '\n';
}

I think this should print "!Mon" not "Mon".

So we should never use __timepunct directly (unless the formatting locale is
the classic locale, and profiling shows it's faster to format directly instead
of using _M_locale_fmt).

Reply via email to