diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 1d75dedde95e..1044afb427c5 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -2042,8 +2042,9 @@ using month = std::chrono::month; using year = std::chrono::year; using year_month_day = std::chrono::year_month_day; #else +class calendar_base {}; // A fallback version of weekday. -class weekday { +class weekday : calendar_base { private: unsigned char value_; @@ -2054,7 +2055,7 @@ class weekday { constexpr auto c_encoding() const noexcept -> unsigned { return value_; } }; -class day { +class day : calendar_base { private: unsigned char value_; @@ -2065,7 +2066,7 @@ class day { constexpr explicit operator unsigned() const noexcept { return value_; } }; -class month { +class month : calendar_base { private: unsigned char value_; @@ -2076,7 +2077,7 @@ class month { constexpr explicit operator unsigned() const noexcept { return value_; } }; -class year { +class year : calendar_base { private: int value_; @@ -2086,7 +2087,7 @@ class year { constexpr explicit operator int() const noexcept { return value_; } }; -class year_month_day { +class year_month_day : calendar_base { private: fmt::year year_; fmt::month month_; @@ -2094,7 +2095,8 @@ class year_month_day { public: year_month_day() = default; - constexpr year_month_day(const year& y, const month& m, const day& d) noexcept + constexpr year_month_day(const fmt::year& y, const fmt::month& m, + const fmt::day& d) noexcept : year_(y), month_(m), day_(d) {} constexpr fmt::year year() const noexcept { return year_; } constexpr fmt::month month() const noexcept { return month_; } @@ -2103,23 +2105,28 @@ class year_month_day { #endif template -struct formatter : formatter { - private: - bool localized{false}; +struct formatter : formatter { + protected: + bool localized_{false}; bool use_tm_formatter_{false}; public: FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) -> decltype(ctx.begin()) { - auto begin = ctx.begin(), end = ctx.end(); - if (begin != end && *begin == 'L') { - ++begin; - localized = true; + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == 'L') { + ++it; + localized_ = true; } - use_tm_formatter_ = !localized && (begin != nullptr); - return use_tm_formatter_ ? formatter::parse(ctx) : begin; + auto empty = (it == end || *it == '}'); + use_tm_formatter_ = !empty && !localized_; + return use_tm_formatter_ ? formatter::parse(ctx) : it; } +}; +template +struct formatter : formatter { + public: template auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); @@ -2127,7 +2134,7 @@ struct formatter : formatter { if (use_tm_formatter_) { return formatter::format(time, ctx); } - detail::get_locale loc(localized, ctx.locale()); + detail::get_locale loc(localized_, ctx.locale()); auto w = detail::tm_writer(loc, ctx.out(), time); w.on_abbr_weekday(); return w.out(); @@ -2135,17 +2142,8 @@ struct formatter : formatter { }; template -struct formatter : formatter { - private: - bool use_tm_formatter_{false}; - +struct formatter : formatter { public: - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - use_tm_formatter_ = ctx.begin() != nullptr; - return formatter::parse(ctx); - } - template auto format(day d, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); @@ -2153,7 +2151,7 @@ struct formatter : formatter { if (use_tm_formatter_) { return formatter::format(time, ctx); } - detail::get_locale loc(false, ctx.locale()); + detail::get_locale loc(localized_, ctx.locale()); auto w = detail::tm_writer(loc, ctx.out(), time); w.on_day_of_month(detail::numeric_system::standard); return w.out(); @@ -2161,23 +2159,8 @@ struct formatter : formatter { }; template -struct formatter : formatter { - private: - bool localized{false}; - bool use_tm_formatter_{false}; - +struct formatter : formatter { public: - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - auto begin = ctx.begin(), end = ctx.end(); - if (begin != end && *begin == 'L') { - ++begin; - localized = true; - } - use_tm_formatter_ = !localized && (begin != nullptr); - return use_tm_formatter_ ? formatter::parse(ctx) : begin; - } - template auto format(month m, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); @@ -2185,7 +2168,7 @@ struct formatter : formatter { if (use_tm_formatter_) { return formatter::format(time, ctx); } - detail::get_locale loc(localized, ctx.locale()); + detail::get_locale loc(localized_, ctx.locale()); auto w = detail::tm_writer(loc, ctx.out(), time); w.on_abbr_month(); return w.out(); @@ -2193,17 +2176,8 @@ struct formatter : formatter { }; template -struct formatter : formatter { - private: - bool use_tm_formatter_{false}; - +struct formatter : formatter { public: - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - use_tm_formatter_ = ctx.begin() != nullptr; - return formatter::parse(ctx); - } - template auto format(year y, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); @@ -2211,7 +2185,7 @@ struct formatter : formatter { if (use_tm_formatter_) { return formatter::format(time, ctx); } - detail::get_locale loc(false, ctx.locale()); + detail::get_locale loc(localized_, ctx.locale()); auto w = detail::tm_writer(loc, ctx.out(), time); w.on_year(detail::numeric_system::standard); return w.out(); @@ -2219,17 +2193,8 @@ struct formatter : formatter { }; template -struct formatter : formatter { - private: - bool use_tm_formatter_{false}; - +struct formatter : formatter { public: - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - use_tm_formatter_ = ctx.begin() != nullptr; - return formatter::parse(ctx); - } - template auto format(year_month_day val, FormatContext& ctx) const -> decltype(ctx.out()) { @@ -2240,7 +2205,7 @@ struct formatter : formatter { if (use_tm_formatter_) { return formatter::format(time, ctx); } - detail::get_locale loc(true, ctx.locale()); + detail::get_locale loc(localized_, ctx.locale()); auto w = detail::tm_writer(loc, ctx.out(), time); w.on_iso_date(); return w.out();