From f8542cd9888b0f07e40500ad5813d3b8ad4d9c68 Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Sun, 10 Oct 2021 21:43:55 +0500 Subject: [PATCH] Unified formatters for std::chrono::time_point and std::tm --- include/fmt/chrono.h | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index a738aedb..7abdc6a3 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1694,17 +1694,13 @@ template struct formatter, Char> : formatter { FMT_CONSTEXPR formatter() { - this->specs = {default_specs, sizeof(default_specs) / sizeof(Char)}; + this->do_parse(default_specs, + default_specs + (sizeof(default_specs) / sizeof(Char))); } template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto begin = ctx.begin(); - auto end = ctx.end(); - if (begin != end && *begin == ':') ++begin; - end = detail::parse_chrono_format(begin, end, detail::tm_format_checker()); - if (end != begin) this->specs = {begin, detail::to_unsigned(end - begin)}; - return end; + return this->do_parse(ctx.begin(), ctx.end(), true); } template @@ -1714,7 +1710,8 @@ struct formatter, return formatter::format(time, ctx); } - static constexpr Char default_specs[] = {'%', 'F', ' ', '%', 'T'}; + // '}' - for detail::parse_chrono_format. + static constexpr Char default_specs[] = {'%', 'F', ' ', '%', 'T', '}'}; }; template @@ -1730,17 +1727,17 @@ template struct formatter { hh_mm_ss, }; spec spec_ = spec::unknown; - - public: basic_string_view specs; - template - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto begin = ctx.begin(); - auto end = ctx.end(); + protected: + template + FMT_CONSTEXPR auto do_parse(It begin, It end, bool with_default = false) + -> It { if (begin != end && *begin == ':') ++begin; end = detail::parse_chrono_format(begin, end, detail::tm_format_checker()); - specs = {begin, detail::to_unsigned(end - begin)}; + if (!with_default || end != begin) { + specs = {begin, detail::to_unsigned(end - begin)}; + } // basic_string_view<>::compare isn't constexpr before C++17 if (specs.size() == 2 && specs[0] == Char('%')) { if (specs[1] == Char('F')) @@ -1751,12 +1748,17 @@ template struct formatter { return end; } + public: + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return this->do_parse(ctx.begin(), ctx.end()); + } + template auto format(const std::tm& tm, FormatContext& ctx) const -> decltype(ctx.out()) { detail::tm_formatter f(ctx, ctx.out(), tm); - if (spec_ == spec::year_month_day) { f.on_iso_date(); return f.out; @@ -1764,7 +1766,6 @@ template struct formatter { f.on_iso_time(); return f.out; } - detail::parse_chrono_format(specs.begin(), specs.end(), f); return f.out; }