From 2e526a664a8b2df428e2f1df790d2f3a40c8e80d Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 6 Mar 2019 07:59:23 -0800 Subject: [PATCH] Fix handling of output iterator in ranges --- include/fmt/ranges.h | 51 ++++++++++++++++++++------------------------ test/ranges-test.cc | 15 +++++++++---- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 5145fc06..fd8d0203 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -55,21 +55,22 @@ struct formatting_tuple : formatting_base { namespace internal { template -void copy(const RangeT& range, OutputIterator out) { +OutputIterator copy(const RangeT& range, OutputIterator out) { for (auto it = range.begin(), end = range.end(); it != end; ++it) *out++ = *it; + return out; } template -void copy(const char* str, OutputIterator out) { - const char* p_curr = str; - while (*p_curr) { - *out++ = *p_curr++; - } +OutputIterator copy(const char* str, OutputIterator out) { + while (*str) *out++ = *str++; + return out; } -template void copy(char ch, OutputIterator out) { +template +OutputIterator copy(char ch, OutputIterator out) { *out++ = ch; + return out; } /// Return true value if T has std::string interface, like std::string_view. @@ -211,12 +212,12 @@ struct formatter< if (formatting.add_prepostfix_space) { *out++ = ' '; } - internal::copy(formatting.delimiter, out); + out = internal::copy(formatting.delimiter, out); } - format_to(out, - internal::format_str_quoted( - (formatting.add_delimiter_spaces && i > 0), v), - v); + out = format_to(out, + internal::format_str_quoted( + (formatting.add_delimiter_spaces && i > 0), v), + v); ++i; } @@ -268,30 +269,24 @@ struct formatter typename FormatContext::iterator format(const RangeT& values, FormatContext& ctx) { - auto out = ctx.out(); - internal::copy(formatting.prefix, out); + auto out = internal::copy(formatting.prefix, ctx.out()); std::size_t i = 0; for (auto it = values.begin(), end = values.end(); it != end; ++it) { if (i > 0) { - if (formatting.add_prepostfix_space) { - *out++ = ' '; - } - internal::copy(formatting.delimiter, out); + if (formatting.add_prepostfix_space) *out++ = ' '; + out = internal::copy(formatting.delimiter, out); } - format_to(out, - internal::format_str_quoted( - (formatting.add_delimiter_spaces && i > 0), *it), - *it); + out = format_to(out, + internal::format_str_quoted( + (formatting.add_delimiter_spaces && i > 0), *it), + *it); if (++i > formatting.range_length_limit) { - format_to(out, " ... "); + out = format_to(out, " ... "); break; } } - if (formatting.add_prepostfix_space) { - *out++ = ' '; - } - internal::copy(formatting.postfix, out); - return ctx.out(); + if (formatting.add_prepostfix_space) *out++ = ' '; + return internal::copy(formatting.postfix, out); } }; diff --git a/test/ranges-test.cc b/test/ranges-test.cc index 97359973..b8990717 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -39,14 +39,14 @@ TEST(RangesTest, FormatMap) { } TEST(RangesTest, FormatPair) { - std::pair pa1{42, 3.14159265358979f}; - EXPECT_EQ("(42, 3.14159)", fmt::format("{}", pa1)); + std::pair pa1{42, 1.5f}; + EXPECT_EQ("(42, 1.5)", fmt::format("{}", pa1)); } TEST(RangesTest, FormatTuple) { - std::tuple tu1{42, 3.14159265358979f, + std::tuple tu1{42, 1.5f, "this is tuple", 'i'}; - EXPECT_EQ("(42, 3.14159, \"this is tuple\", 'i')", fmt::format("{}", tu1)); + EXPECT_EQ("(42, 1.5, \"this is tuple\", 'i')", fmt::format("{}", tu1)); } struct my_struct { @@ -80,5 +80,12 @@ TEST(RangesTest, FormatStruct) { EXPECT_EQ("(13, \"my struct\")", fmt::format("{}", mst)); } +TEST(RangesTest, FormatTo) { + char buf[10]; + auto end = fmt::format_to(buf, "{}", std::vector{1, 2, 3}); + *end = '\0'; + EXPECT_STREQ(buf, "{1, 2, 3}"); +} + #endif // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG > // 201402L && _MSC_VER >= 1910)