From cdc9c4f8a5a042b14e33069794c6280e876c19e8 Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Sat, 13 Nov 2021 22:45:25 +0500 Subject: [PATCH 1/3] Reuse tm_writer in weekday formatter --- include/fmt/chrono.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index c74207b3cf0e..47ea3dbb72da 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1663,8 +1663,10 @@ template struct formatter { auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); time.tm_wday = static_cast(wd.c_encoding()); - return detail::write( - ctx.out(), time, detail::get_locale(localized, ctx.locale()), 'a'); + detail::get_locale loc(localized, ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_abbr_weekday(); + return w.out(); } }; From aac81a2660a0d764ac926f72d6e53f311559389d Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Sat, 13 Nov 2021 22:46:16 +0500 Subject: [PATCH 2/3] Reuse tm_writer in chrono_formatter --- include/fmt/chrono.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 47ea3dbb72da..fa1d4d525a35 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1412,6 +1412,7 @@ struct chrono_formatter { bool negative; using char_type = typename FormatContext::char_type; + using tm_writer_type = tm_writer; chrono_formatter(FormatContext& ctx, OutputIt o, std::chrono::duration d) @@ -1493,10 +1494,13 @@ struct chrono_formatter { void write_pinf() { std::copy_n("inf", 3, out); } void write_ninf() { std::copy_n("-inf", 4, out); } - void format_localized(const tm& time, char format, char modifier = 0) { + template + void format_tm(const tm& time, Callback cb, Args... args) { if (isnan(val)) return write_nan(); - out = detail::write( - out, time, get_locale(localized, context.locale()), format, modifier); + get_locale loc(localized, context.locale()); + auto w = tm_writer_type(loc, out, time); + (w.*cb)(args...); + out = w.out(); } void on_text(const char_type* begin, const char_type* end) { @@ -1537,7 +1541,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour(), 24); - format_localized(time, 'H', 'O'); + format_tm(time, &tm_writer_type::on_24_hour, ns); } void on_12_hour(numeric_system ns) { @@ -1546,7 +1550,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour12(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour12(), 12); - format_localized(time, 'I', 'O'); + format_tm(time, &tm_writer_type::on_12_hour, ns); } void on_minute(numeric_system ns) { @@ -1555,7 +1559,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(minute(), 2); auto time = tm(); time.tm_min = to_nonnegative_int(minute(), 60); - format_localized(time, 'M', 'O'); + format_tm(time, &tm_writer_type::on_minute, ns); } void on_second(numeric_system ns) { @@ -1580,12 +1584,12 @@ struct chrono_formatter { } auto time = tm(); time.tm_sec = to_nonnegative_int(second(), 60); - format_localized(time, 'S', 'O'); + format_tm(time, &tm_writer_type::on_second, ns); } void on_12_hour_time() { if (handle_nan_inf()) return; - format_localized(time(), 'r'); + format_tm(time(), &tm_writer_type::on_12_hour_time); } void on_24_hour_time() { @@ -1609,7 +1613,7 @@ struct chrono_formatter { void on_am_pm() { if (handle_nan_inf()) return; - format_localized(time(), 'p'); + format_tm(time(), &tm_writer_type::on_am_pm); } void on_duration_value() { From 13705c06c6e18032dcbbd28705d6d67bc227413e Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Sat, 13 Nov 2021 22:51:13 +0500 Subject: [PATCH 3/3] Simplify std::tm formatter --- include/fmt/chrono.h | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index fa1d4d525a35..b6a9a7907af6 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1847,18 +1847,6 @@ template struct formatter { return end; } - template - It do_format(It out, const std::tm& tm, const std::locale& loc) const { - auto w = detail::tm_writer(loc, out, tm); - if (spec_ == spec::year_month_day) - w.on_iso_date(); - else if (spec_ == spec::hh_mm_ss) - w.on_iso_time(); - else - detail::parse_chrono_format(specs.begin(), specs.end(), w); - return w.out(); - } - public: template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { @@ -1868,9 +1856,16 @@ template struct formatter { template auto format(const std::tm& tm, FormatContext& ctx) const -> decltype(ctx.out()) { - const auto loc = ctx.locale(); - return this->do_format(ctx.out(), tm, - detail::get_locale(static_cast(loc), loc)); + const auto loc_ref = ctx.locale(); + detail::get_locale loc(static_cast(loc_ref), loc_ref); + auto w = detail::tm_writer(loc, ctx.out(), tm); + if (spec_ == spec::year_month_day) + w.on_iso_date(); + else if (spec_ == spec::hh_mm_ss) + w.on_iso_time(); + else + detail::parse_chrono_format(specs.begin(), specs.end(), w); + return w.out(); } };