aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-03-19 19:38:15 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2025-03-21 10:28:11 +0000
commit3c7f2fd8c4b330029c935f2785a5da9395355d7d (patch)
treead86c64bb3d3347a191a86c9ed98da870d5ac306
parent3e1d760bf49d0e9a89dcfa0450a6d1ae5ceb756e (diff)
downloadgcc-3c7f2fd8c4b330029c935f2785a5da9395355d7d.zip
gcc-3c7f2fd8c4b330029c935f2785a5da9395355d7d.tar.gz
gcc-3c7f2fd8c4b330029c935f2785a5da9395355d7d.tar.bz2
libstdc++: Use formatting locale for std::time_put formats
When using std::time_put to format a chrono value, we should imbue the formatting locale into the stream. This ensures that when std::time_put::do_put uses a ctype or __timepunct facet from the locale, it gets the correct facets. libstdc++-v3/ChangeLog: * include/bits/chrono_io.h (__formatter_chrono::_M_locale_fmt): Imbue locale into ostringstream. * testsuite/std/time/format/localized.cc: Check that correct locale is used for call to time_put::put. Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h1
-rw-r--r--libstdc++-v3/testsuite/std/time/format/localized.cc33
2 files changed, 34 insertions, 0 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index c16b555..55ebd4e 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1697,6 +1697,7 @@ namespace __format
char __fmt, char __mod) const
{
basic_ostringstream<_CharT> __os;
+ __os.imbue(__loc);
const auto& __tp = use_facet<time_put<_CharT>>(__loc);
__tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
if (__os)
diff --git a/libstdc++-v3/testsuite/std/time/format/localized.cc b/libstdc++-v3/testsuite/std/time/format/localized.cc
index 393d0d2..7fde97f 100644
--- a/libstdc++-v3/testsuite/std/time/format/localized.cc
+++ b/libstdc++-v3/testsuite/std/time/format/localized.cc
@@ -13,6 +13,7 @@
#include <chrono>
#include <format>
+#include <locale>
#include <stdio.h>
#include <testsuite_hooks.h>
@@ -81,10 +82,42 @@ test_en()
}
}
+void
+test_locale_imbued()
+{
+ // Custom time_put facet which returns %b string for %Om.
+ // The %b string will come from io.getloc() which should be
+ // the formatting locale using by std::format.
+ struct TimePut : 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
+ {
+ if (format == 'm' && modifier == 'O')
+ format = 'b';
+ return std::time_put<char>::do_put(out, io, fill, t, format, 0);
+ }
+ };
+
+ auto m = std::chrono::March;
+
+ std::locale fr(ISO_8859(1,fr_FR));
+ std::locale fr2(fr, new TimePut);
+ auto s1 = std::format(fr2, "{:L%Om}", m); // should be %b in fr_FR locale
+ VERIFY( s1 == std::format(fr, "{:L}", m) );
+
+ std::locale es(ISO_8859(1,es_ES));
+ std::locale es2(es, new TimePut);
+ auto s2 = std::format(es2, "{:L%Om}", m); // should be %b in es_ES locale
+ VERIFY( s2 == std::format(es, "{:L}", m) );
+}
+
int main()
{
test_ru();
test_es();
test_fr();
test_en();
+ test_locale_imbued();
}