diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 9ffcc836..80b44a42 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -17,7 +17,6 @@ #include // std::memmove #include #include -#include #ifndef FMT_STATIC_THOUSANDS_SEPARATOR # include @@ -119,20 +118,18 @@ template FMT_FUNC Char decimal_point_impl(locale_ref) { } #endif -FMT_FUNC auto write_int(unsigned long long value, const format_specs& specs, - locale_ref loc) -> std::string { +FMT_FUNC auto write_int(appender out, unsigned long long 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 {}; - auto&& buf = std::basic_stringbuf(); - auto out = std::ostreambuf_iterator(&buf); std::use_facet>(locale).put(out, value, specs, locale); - return buf.str(); + return true; #endif - return {}; + return false; } } // namespace detail diff --git a/include/fmt/format.h b/include/fmt/format.h index d31d1242..a792f31d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2014,33 +2014,35 @@ auto write_int(OutputIt out, UInt value, unsigned prefix, }); } -FMT_API auto write_int(unsigned long long value, const format_specs& specs, - locale_ref loc) -> std::string; -template -inline auto write_int(unsigned long long, const basic_format_specs&, - locale_ref) -> std::string { - return {}; +FMT_API auto write_int(appender out, unsigned long long value, + const format_specs& specs, locale_ref loc) -> bool; +template +inline auto write_int(OutputIt, unsigned long long, + 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 str = std::string(); + auto result = false; + auto buf = memory_buffer(); if (sizeof(value) <= sizeof(unsigned long long)) - str = write_int(static_cast(value), specs, loc); - if (str.empty()) { + result = write_int(appender(buf), static_cast(value), + specs, loc); + if (!result) { auto grouping = digit_grouping(loc); out = write_int(out, value, prefix, specs, grouping); return true; } - size_t size = to_unsigned((prefix != 0 ? 1 : 0) + str.size()); + size_t size = to_unsigned((prefix != 0 ? 1 : 0) + buf.size()); out = write_padded( out, specs, size, size, [&](reserve_iterator it) { if (prefix != 0) { char sign = static_cast(prefix); *it++ = static_cast(sign); } - return copy_str(str.data(), str.data() + str.size(), it); + return copy_str(buf.data(), buf.data() + buf.size(), it); }); return true; } @@ -4180,17 +4182,14 @@ template class num_format_facet : public Locale::facet { public: static FMT_API typename Locale::id id; - using iter_type = std::ostreambuf_iterator; - - auto put(iter_type out, unsigned long long val, const format_specs& specs, - Locale& loc) const -> iter_type { - return do_put(out, val, specs, loc); + void put(appender out, unsigned long long val, const format_specs& specs, + Locale& loc) const { + do_put(out, val, specs, loc); } protected: - virtual auto do_put(iter_type out, unsigned long long val, - const format_specs& specs, Locale& loc) const - -> iter_type = 0; + virtual void do_put(appender out, unsigned long long val, + const format_specs& specs, Locale& loc) const = 0; }; #if FMT_USE_USER_DEFINED_LITERALS diff --git a/test/xchar-test.cc b/test/xchar-test.cc index e1958315..91300da1 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -522,20 +522,18 @@ TEST(locale_test, sign) { class num_format : public fmt::num_format_facet { protected: - iter_type do_put(iter_type out, unsigned long long, const fmt::format_specs&, - std::locale&) const override; + void do_put(fmt::appender out, unsigned long long, const fmt::format_specs&, + std::locale&) const override; }; -num_format::iter_type num_format::do_put(iter_type out, unsigned long long, - const fmt::format_specs&, - std::locale&) const { - const char s[] = "foo"; - return std::copy_n(s, sizeof(s) - 1, out); +void num_format::do_put(fmt::appender out, unsigned long long value, + const fmt::format_specs&, std::locale&) const { + fmt::format_to(out, "[{}]", value); } TEST(locale_test, num_format) { auto loc = std::locale(std::locale(), new num_format()); - EXPECT_EQ(fmt::format(loc, "{:L}", 42), "foo"); + EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]"); } #endif // FMT_STATIC_THOUSANDS_SEPARATOR