From f641fc53ae4acf699ff915725194f56b3c9de2b5 Mon Sep 17 00:00:00 2001 From: Vladislav Shchapov Date: Mon, 20 Feb 2023 20:23:51 +0500 Subject: [PATCH] Reduce the memory allocations Signed-off-by: Vladislav Shchapov --- include/fmt/core.h | 9 ++++++++- include/fmt/format-inl.h | 20 ++++++++++++++++---- include/fmt/ostream.h | 32 ++++++++++++++++++++++++-------- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 6c9d968b..4cc179b5 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -2776,8 +2776,13 @@ template void vformat_to(buffer& buf, basic_string_view fmt, typename vformat_args::type args, locale_ref loc = {}); +FMT_API void vprint(std::FILE* f, string_view format_str, format_args args, + string_view suffix); +FMT_API void vprint_mojibake(std::FILE*, string_view, format_args, string_view); FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); #ifndef _WIN32 +inline void vprint_mojibake(std::FILE*, string_view, format_args, string_view) { +} inline void vprint_mojibake(std::FILE*, string_view, format_args) {} #endif FMT_END_DETAIL_NAMESPACE @@ -3021,7 +3026,9 @@ FMT_INLINE void print(std::FILE* f, format_string fmt, T&&... args) { */ template FMT_INLINE void println(std::FILE* f, format_string fmt, T&&... args) { - return fmt::print(f, "{}\n", fmt::format(fmt, std::forward(args)...)); + const auto& vargs = fmt::make_format_args(args...); + return detail::is_utf8() ? detail::vprint(f, fmt, vargs, {"\n", 1}) + : detail::vprint_mojibake(f, fmt, vargs, {"\n", 1}); } /** diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 3b00bd67..1fba6504 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1482,23 +1482,35 @@ FMT_FUNC void print(std::FILE* f, string_view text) { #endif detail::fwrite_fully(text.data(), 1, text.size(), f); } + +FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args, + string_view suffix) { + memory_buffer buffer; + detail::vformat_to(buffer, format_str, args); + buffer.append(suffix); + detail::print(f, {buffer.data(), buffer.size()}); +} + } // namespace detail FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { - memory_buffer buffer; - detail::vformat_to(buffer, format_str, args); - detail::print(f, {buffer.data(), buffer.size()}); + detail::vprint(f, format_str, args, {}); } #ifdef _WIN32 // Print assuming legacy (non-Unicode) encoding. FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str, - format_args args) { + format_args args, string_view suffix) { memory_buffer buffer; detail::vformat_to(buffer, format_str, basic_format_args>(args)); + buffer.append(suffix); fwrite_fully(buffer.data(), 1, buffer.size(), f); } +FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str, + format_args args) { + vprint_mojibake(f, format_str, args, {}); +} #endif FMT_FUNC void vprint(string_view format_str, format_args args) { diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index d3bb432c..b1a48e0d 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -188,9 +188,22 @@ struct fallback_formatter::value>> }; inline void vprint_directly(std::ostream& os, string_view format_str, - format_args args) { + format_args args, string_view suffix) { auto buffer = memory_buffer(); detail::vformat_to(buffer, format_str, args); + buffer.append(suffix); + detail::write_buffer(os, buffer); +} + +template +void vprint(std::basic_ostream& os, + basic_string_view> format_str, + basic_format_args>> args, + basic_string_view> suffix) { + auto buffer = basic_memory_buffer(); + detail::vformat_to(buffer, format_str, args); + buffer.append(suffix); + if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return; detail::write_buffer(os, buffer); } @@ -200,10 +213,7 @@ FMT_MODULE_EXPORT template void vprint(std::basic_ostream& os, basic_string_view> format_str, basic_format_args>> args) { - auto buffer = basic_memory_buffer(); - detail::vformat_to(buffer, format_str, args); - if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return; - detail::write_buffer(os, buffer); + detail::vprint(os, format_str, args, {}); } /** @@ -221,7 +231,7 @@ void print(std::ostream& os, format_string fmt, T&&... args) { if (detail::is_utf8()) vprint(os, fmt, vargs); else - detail::vprint_directly(os, fmt, vargs); + detail::vprint_directly(os, fmt, vargs, {}); } FMT_MODULE_EXPORT @@ -234,7 +244,11 @@ void print(std::wostream& os, FMT_MODULE_EXPORT template void println(std::ostream& os, format_string fmt, T&&... args) { - print(os, "{}\n", fmt::format(fmt, std::forward(args)...)); + const auto& vargs = fmt::make_format_args(args...); + if (detail::is_utf8()) + detail::vprint(os, fmt, vargs, {"\n", 1}); + else + detail::vprint_directly(os, fmt, vargs, {"\n", 1}); } FMT_MODULE_EXPORT @@ -242,7 +256,9 @@ template void println(std::wostream& os, basic_format_string...> fmt, Args&&... args) { - print(os, L"{}\n", fmt::format(fmt, std::forward(args)...)); + detail::vprint(os, fmt, + fmt::make_format_args>(args...), + {L"\n", 1}); } FMT_END_NAMESPACE