From 94ceb38a0943c50ea9939050a7f4e8e4c9da43d2 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 11 Sep 2022 09:33:31 -0700 Subject: [PATCH] Improve locale API --- include/fmt/format-inl.h | 10 ++++----- include/fmt/format.h | 48 ++++++++++++++++++++++------------------ include/fmt/xchar.h | 5 ++--- test/format-test.cc | 7 +++--- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 8721888d7dac..2d3a4d61dfe0 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -116,7 +116,7 @@ template FMT_FUNC Char decimal_point_impl(locale_ref) { } #endif -FMT_FUNC auto write_loc(appender out, basic_format_arg value, +FMT_FUNC auto write_loc(appender out, loc_value value, const format_specs& specs, locale_ref loc) -> bool { #ifndef FMT_STATIC_THOUSANDS_SEPARATOR auto locale = loc.get(); @@ -142,11 +142,9 @@ template format_facet::format_facet(Locale& loc) { template <> FMT_API FMT_FUNC auto format_facet::do_put( - appender out, basic_format_arg val, - const format_specs& specs) const -> bool { - return visit_format_arg( - detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_}, - val); + appender out, loc_value val, const format_specs& specs) const -> bool { + return val.visit( + detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_}); } #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index 7516825d43a0..c62c883f2ec4 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1001,6 +1001,22 @@ constexpr auto compile_string_to_view(detail::std_string_view s) } } // namespace detail_exported +class loc_value { + private: + basic_format_arg value_; + + public: + template ::value)> + loc_value(T value) : value_(detail::make_arg(value)) {} + + template ::value)> + loc_value(T) {} + + template auto visit(Visitor&& vis) -> decltype(vis(0)) { + return visit_format_arg(vis, value_); + } +}; + // A locale facet that formats values in UTF-8. // It is parameterized on the locale to avoid the heavy include. template class format_facet : public Locale::facet { @@ -1010,7 +1026,7 @@ template class format_facet : public Locale::facet { std::string decimal_point_; protected: - virtual auto do_put(appender out, basic_format_arg val, + virtual auto do_put(appender out, loc_value val, const format_specs& specs) const -> bool; public: @@ -1024,8 +1040,8 @@ template class format_facet : public Locale::facet { grouping_(g.begin(), g.end()), decimal_point_(decimal_point) {} - auto put(appender out, basic_format_arg val, - const format_specs& specs) const -> bool { + auto put(appender out, loc_value val, const format_specs& specs) const + -> bool { return do_put(out, val, specs); } }; @@ -2053,22 +2069,12 @@ auto write_int(OutputIt out, UInt value, unsigned prefix, }); } -template ::value)> -auto make_loc_value(T value) -> basic_format_arg { - return make_arg(value); -} -template ::value)> -auto make_loc_value(T) -> basic_format_arg { - return {}; -} - // Writes a localized value. -FMT_API auto write_loc(appender out, basic_format_arg value, - const format_specs& specs, locale_ref loc) -> bool; - +FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs, + locale_ref loc) -> bool; template -inline auto write_loc(OutputIt, basic_format_arg, - const basic_format_specs&, locale_ref) -> bool { +inline auto write_loc(OutputIt, loc_value, const basic_format_specs&, + locale_ref) -> bool { return false; } @@ -2190,8 +2196,7 @@ template & specs, locale_ref loc) -> OutputIt { - if (specs.localized && write_loc(out, make_loc_value(value), specs, loc)) - return out; + if (specs.localized && write_loc(out, value, specs, loc)) return out; return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs, loc); } @@ -2203,8 +2208,7 @@ template & specs, locale_ref loc) -> OutputIt { - if (specs.localized && write_loc(out, make_loc_value(value), specs, loc)) - return out; + if (specs.localized && write_loc(out, value, specs, loc)) return out; return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } @@ -3311,7 +3315,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value, basic_format_specs specs, locale_ref loc = {}) -> OutputIt { if (const_check(!is_supported_floating_point(value))) return out; - return specs.localized && write_loc(out, make_loc_value(value), specs, loc) + return specs.localized && write_loc(out, value, specs, loc) ? out : write_float(out, value, specs, loc); } diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 5fc1a269255f..40afbb43d8c6 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -23,7 +23,7 @@ template using is_exotic_char = bool_constant::value>; template -auto write_loc(OutputIt out, basic_format_arg val, +auto write_loc(OutputIt out, loc_value value, const basic_format_specs& specs, locale_ref loc) -> bool { #ifndef FMT_STATIC_THOUSANDS_SEPARATOR @@ -32,8 +32,7 @@ auto write_loc(OutputIt out, basic_format_arg val, auto separator = std::wstring(); auto grouping = numpunct.grouping(); if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep()); - return visit_format_arg( - loc_writer{out, specs, separator, grouping, {}}, val); + return value.visit(loc_writer{out, specs, separator, grouping, {}}); #endif return false; } diff --git a/test/format-test.cc b/test/format-test.cc index 15c3f9f21536..27a21303c6a6 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2335,14 +2335,13 @@ class format_facet : public fmt::format_facet { } }; - auto do_put(fmt::appender out, fmt::basic_format_arg arg, + auto do_put(fmt::appender out, fmt::loc_value val, const fmt::format_specs&) const -> bool override; }; -auto format_facet::do_put(fmt::appender out, - fmt::basic_format_arg arg, +auto format_facet::do_put(fmt::appender out, fmt::loc_value val, const fmt::format_specs&) const -> bool { - return visit_format_arg(int_formatter{out}, arg); + return val.visit(int_formatter{out}); } TEST(format_test, format_facet) {