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 d0a38f25..dcd1e486 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2473,3 +2473,29 @@ TEST(FormatTest, FormatUTF8Precision) { EXPECT_EQ(result.size(), 5); EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); } + +struct lazy_optional { + bool engaged; + std::string value; +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter : formatter { + template + auto format(const lazy_optional& opt, Context& ctx) { + if (opt.engaged) { + auto out = format_to(ctx.out(), "Some("); + out = format_to(out, "{}", opt.value); + *out = ')'; + return ++out; + } else { + return format_to(ctx.out(), "None()"); + } + } +}; +FMT_END_NAMESPACE + +TEST(FormatTest, BackInsertSlicing) { + EXPECT_EQ(fmt::format("{}", lazy_optional{false, ""}), "None()"); + EXPECT_EQ(fmt::format("{}", lazy_optional{true, "X"}), "Some(X)"); +}