From fec5515c55f85143077806bf01650c23b08d3751 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Fri, 2 Sep 2022 17:27:19 -0700 Subject: [PATCH] num_format_facet -> format_facet --- include/fmt/core.h | 2 +- include/fmt/format-inl.h | 10 +++++----- include/fmt/format.h | 35 +++++++++++++---------------------- test/format-test.cc | 31 +++++++++++++++++++++---------- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 9dfcd2d6..a4b200d7 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -332,7 +332,7 @@ struct monostate { #ifdef FMT_DOC # define FMT_ENABLE_IF(...) #else -# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 +# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0 #endif FMT_BEGIN_DETAIL_NAMESPACE diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 6fbdb52a..0591e5af 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -29,7 +29,7 @@ #include "format.h" FMT_BEGIN_NAMESPACE -template typename Locale::id num_format_facet::id; +template typename Locale::id format_facet::id; namespace detail { @@ -118,15 +118,15 @@ template FMT_FUNC Char decimal_point_impl(locale_ref) { } #endif -FMT_FUNC auto write_int(appender out, loc_value value, +FMT_FUNC auto write_int(appender out, basic_format_arg value, const format_specs& specs, locale_ref loc) -> bool { #ifndef FMT_STATIC_THOUSANDS_SEPARATOR auto locale = loc.get(); // We cannot use the num_put facet because it may produce output in // a wrong encoding. - if (!std::has_facet>(locale)) return {}; - std::use_facet>(locale).put(out, value, specs, - locale); + if (!std::has_facet>(locale)) return {}; + std::use_facet>(locale).put(out, value, specs, + locale); return true; #endif return false; diff --git a/include/fmt/format.h b/include/fmt/format.h index a1b98c7f..dc5108f9 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -985,27 +985,20 @@ constexpr auto compile_string_to_view(detail::std_string_view s) } } // namespace detail_exported -// A value to localize. -struct loc_value { - union { - unsigned long long ulong_long_value; - }; -}; - -// A locale facet that formats numeric values in UTF-8. -// It is parameterized on the locale to avoid heavy include. -template class num_format_facet : public Locale::facet { +// 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 { public: static FMT_API typename Locale::id id; - void put(appender out, loc_value val, const format_specs& specs, - Locale& loc) const { + void put(appender out, basic_format_arg val, + const format_specs& specs, Locale& loc) const { do_put(out, val, specs, loc); } protected: - virtual void do_put(appender out, loc_value val, const format_specs& specs, - Locale& loc) const = 0; + virtual void do_put(appender out, basic_format_arg val, + const format_specs& specs, Locale& loc) const = 0; }; FMT_BEGIN_DETAIL_NAMESPACE @@ -2037,23 +2030,21 @@ auto write_int(OutputIt out, UInt value, unsigned prefix, }); } -FMT_API auto write_int(appender out, loc_value value, const format_specs& specs, - locale_ref loc) -> bool; +FMT_API auto write_int(appender out, basic_format_arg value, + const format_specs& specs, locale_ref loc) -> bool; template -inline auto write_int(OutputIt, loc_value, const basic_format_specs&, - locale_ref) -> bool { +inline auto write_int(OutputIt, basic_format_arg>, + const basic_format_specs&, locale_ref) -> bool { return false; } template auto write_int(OutputIt& out, UInt value, unsigned prefix, const basic_format_specs& specs, locale_ref loc) -> bool { - auto result = false; auto buf = memory_buffer(); - if (sizeof(value) <= sizeof(unsigned long long)) - result = write_int(appender(buf), {static_cast(value)}, + auto written = write_int(appender(buf), make_arg>(value), specs, loc); - if (!result) { + if (!written) { auto grouping = digit_grouping(loc); out = write_int(out, value, prefix, specs, grouping); return true; diff --git a/test/format-test.cc b/test/format-test.cc index b028aefd..08dadfe3 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2312,25 +2312,36 @@ TEST(format_int_test, format_int) { EXPECT_EQ(os.str(), fmt::format_int(max_value()).str()); } -#ifdef FMT_STATIC_THOUSANDS_SEPARATOR +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR # include -class num_format : public fmt::num_format_facet { +class format_facet : public fmt::format_facet { protected: - void do_put(fmt::appender out, fmt::loc_value, const fmt::format_specs&, - std::locale&) const override; + struct int_formatter { + fmt::appender out; + + template ::value)> + void operator()(T value) { + fmt::format_to(out, "[{}]", value); + } + template ::value)> + void operator()(T) {} + }; + + void do_put(fmt::appender out, fmt::basic_format_arg arg, + const fmt::format_specs&, std::locale&) const override; }; -void num_format::do_put(fmt::appender out, fmt::loc_value value, - const fmt::format_specs&, std::locale&) const { - fmt::format_to(out, "[{}]", value.ulong_long_value); +void format_facet::do_put(fmt::appender out, + fmt::basic_format_arg arg, + const fmt::format_specs&, std::locale&) const { + visit_format_arg(int_formatter{out}, arg); } -TEST(format_test, num_format) { - auto loc = std::locale(std::locale(), new num_format()); +TEST(format_test, format_facet) { + auto loc = std::locale(std::locale(), new format_facet()); EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]"); - EXPECT_EQ(fmt::format(loc, "{:L}", -42), "[-42]"); } #endif // FMT_STATIC_THOUSANDS_SEPARATOR