From bff4d18efba37c0ffd44f036a7adaff1064c840f Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sun, 30 Aug 2020 21:48:49 +0200 Subject: [PATCH] Add color format_to overloads * Fix variable size basic_memory_buffer colorization * Fix an unused arguments warning on GCC that blocks the CI otherwise * Ref #1842 * Ref #1593 --- include/fmt/color.h | 39 ++++++++++++++++++++++++++++++++++++--- test/color-test.cc | 13 +++++++++++++ test/gtest-extra.h | 8 +++++++- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/include/fmt/color.h b/include/fmt/color.h index f1b1f753f84a..bcc56b9879fb 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -463,16 +463,16 @@ template <> inline void reset_color(FILE* stream) FMT_NOEXCEPT { } template -inline void reset_color(basic_memory_buffer& buffer) FMT_NOEXCEPT { +inline void reset_color(buffer& buffer) FMT_NOEXCEPT { const char* begin = data::reset_color; const char* end = begin + sizeof(data::reset_color) - 1; buffer.append(begin, end); } template -void vformat_to(basic_memory_buffer& buf, const text_style& ts, +void vformat_to(buffer& buf, const text_style& ts, basic_string_view format_str, - basic_format_args> args) { + basic_format_args>> args) { bool has_style = false; if (ts.has_emphasis()) { has_style = true; @@ -563,6 +563,39 @@ inline std::basic_string format(const text_style& ts, const S& format_str, fmt::make_args_checked(format_str, args...)); } +/** Formats a string with the given text_style and writes the output to ``out``. + */ +template ::value)> +OutputIt vformat_to( + OutputIt out, const text_style& ts, basic_string_view format_str, + basic_format_args>> args) { + decltype(detail::get_buffer(out)) buf(detail::get_buffer_init(out)); + detail::vformat_to(buf, ts, format_str, args); + return detail::get_iterator(buf); +} + +/** + \rst + Formats arguments with the given text_style, writes the result to the output + iterator ``out`` and returns the iterator past the end of the output range. + + **Example**:: + + std::vector out; + fmt::format_to(std::back_inserter(out), + fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); + \endrst +*/ +template ::value&& + detail::is_string::value)> +inline OutputIt format_to(OutputIt out, const text_style& ts, + const S& format_str, Args&&... args) { + return vformat_to(out, ts, to_string_view(format_str), + fmt::make_args_checked(format_str, args...)); +} + FMT_END_NAMESPACE #endif // FMT_COLOR_H_ diff --git a/test/color-test.cc b/test/color-test.cc index 454a0660d4cf..66b8eab04028 100644 --- a/test/color-test.cc +++ b/test/color-test.cc @@ -7,6 +7,10 @@ #include "fmt/color.h" +#include +#include +#include + #include "gtest-extra.h" TEST(ColorsTest, ColorsPrint) { @@ -84,3 +88,12 @@ TEST(ColorsTest, Format) { EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "{}", "foo"), "\x1b[31mfoo\x1b[0m"); } + +TEST(ColorsTest, FormatToOutAcceptsTextStyle) { + fmt::text_style const ts = fg(fmt::rgb(255, 20, 30)); + std::string out; + fmt::format_to(std::back_inserter(out), ts, "rgb(255,20,30){}{}{}", 1, 2, 3); + + EXPECT_EQ(fmt::to_string(out), + "\x1b[38;2;255;020;030mrgb(255,20,30)123\x1b[0m"); +} diff --git a/test/gtest-extra.h b/test/gtest-extra.h index 3ed8052b3fcb..01c70ddbf06d 100644 --- a/test/gtest-extra.h +++ b/test/gtest-extra.h @@ -145,7 +145,13 @@ std::string read(fmt::file& f, size_t count); read(file, fmt::string_view(expected_content).size())) #else -# define EXPECT_WRITE(file, statement, expected_output) SUCCEED() +# define EXPECT_WRITE(file, statement, expected_output) \ + do { \ + (void)(file); \ + (void)(statement); \ + (void)(expected_output); \ + SUCCEED(); \ + } while (false) #endif // FMT_USE_FCNTL template struct ScopedMock : testing::StrictMock {