From 6be65446682d687fb99943240735c14587fa9043 Mon Sep 17 00:00:00 2001 From: Barry Revzin Date: Tue, 18 Aug 2020 14:37:56 -0500 Subject: [PATCH] Fixing buffer_appender's ++ slicing (#1822) * Fixing buffer_appender's ++ slicing. * This test requires C++14. * Removing string_view dependency. * Simplifying test case. * Adding message to static_assert --- include/fmt/core.h | 18 +++++++++++++++--- test/format-test.cc | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 2b474e36..2576d056 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -845,11 +845,23 @@ template class counting_buffer : public buffer { // It is used to reduce symbol sizes for the common case. template class buffer_appender : public std::back_insert_iterator> { + using base = std::back_insert_iterator>; public: explicit buffer_appender(buffer& buf) - : std::back_insert_iterator>(buf) {} - buffer_appender(std::back_insert_iterator> it) - : std::back_insert_iterator>(it) {} + : base(buf) {} + buffer_appender(base it) + : base(it) {} + + buffer_appender& operator++() { + base::operator++(); + return *this; + } + + buffer_appender operator++(int) { + buffer_appender tmp = *this; + ++*this; + return tmp; + } }; // Maps an output iterator into a buffer. diff --git a/test/format-test.cc b/test/format-test.cc index 33e620f7..e9666560 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2477,3 +2477,27 @@ TEST(FormatTest, FormatUTF8Precision) { EXPECT_EQ(result.size(), 5); EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); } + +struct check_back_appender {}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter { + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template + auto format(check_back_appender, Context& ctx) -> decltype(ctx.out()) { + auto out = ctx.out(); + static_assert(std::is_same::value, + "needs to satisfy weakly_incrementable"); + *out = 'y'; + return ++out; + } +}; +FMT_END_NAMESPACE + +TEST(FormatTest, BackInsertSlicing) { + EXPECT_EQ(fmt::format("{}", check_back_appender{}), "y"); +}