diff --git a/include/fmt/base.h b/include/fmt/base.h index b47b55537a27..34e8d7145ed1 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -1948,8 +1948,9 @@ constexpr auto make_format_args(T&... args) template (), - unsigned long long DESC = detail::make_descriptor() | - static_cast(detail::has_named_args_bit), + unsigned long long DESC = + detail::make_descriptor() | + static_cast(detail::has_named_args_bit), FMT_ENABLE_IF(NUM_NAMED_ARGS != 0)> constexpr auto make_format_args(T&... args) -> detail::format_arg_store { @@ -2703,9 +2704,9 @@ template void vformat_to(buffer& buf, basic_string_view fmt, typename vformat_args::type args, locale_ref loc = {}); -FMT_API void vprint_mojibake(FILE*, string_view, format_args); +FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool = false); #ifndef _WIN32 -inline void vprint_mojibake(FILE*, string_view, format_args) {} +inline void vprint_mojibake(FILE*, string_view, format_args, bool) {} #endif } // namespace detail @@ -2892,6 +2893,7 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(format_string fmt, FMT_API void vprint(string_view fmt, format_args args); FMT_API void vprint(FILE* f, string_view fmt, format_args args); +FMT_API void vprintln(FILE* f, string_view fmt, format_args args); /** \rst @@ -2933,7 +2935,9 @@ FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { */ template FMT_INLINE void println(FILE* f, format_string fmt, T&&... args) { - return fmt::print(f, "{}\n", fmt::format(fmt, static_cast(args)...)); + const auto& vargs = fmt::make_format_args(args...); + return detail::is_utf8() ? vprintln(f, fmt, vargs) + : detail::vprint_mojibake(f, fmt, vargs, true); } /** diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 00d77d54fe64..48a240c2c5a1 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1448,9 +1448,11 @@ FMT_FUNC bool write_console(int fd, string_view text) { #ifdef _WIN32 // Print assuming legacy (non-Unicode) encoding. -FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args) { +FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args, + bool newline) { auto buffer = memory_buffer(); detail::vformat_to(buffer, fmt, args); + if (newline) buffer.push_back('\n'); fwrite_fully(buffer.data(), buffer.size(), f); } #endif @@ -1473,6 +1475,13 @@ FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) { detail::print(f, {buffer.data(), buffer.size()}); } +FMT_FUNC void vprintln(std::FILE* f, string_view fmt, format_args args) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + buffer.push_back('\n'); + detail::print(f, {buffer.data(), buffer.size()}); +} + FMT_FUNC void vprint(string_view fmt, format_args args) { vprint(stdout, fmt, args); }