Skip to content

Commit

Permalink
Fixing buffer_appender's ++ slicing (#1822)
Browse files Browse the repository at this point in the history
* Fixing buffer_appender's ++ slicing.

* This test requires C++14.

* Removing string_view dependency.

* Simplifying test case.

* Adding message to static_assert
  • Loading branch information
brevzin authored Aug 18, 2020
1 parent 951e0d2 commit 6be6544
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
18 changes: 15 additions & 3 deletions include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,11 +845,23 @@ template <typename T = char> class counting_buffer : public buffer<T> {
// It is used to reduce symbol sizes for the common case.
template <typename T>
class buffer_appender : public std::back_insert_iterator<buffer<T>> {
using base = std::back_insert_iterator<buffer<T>>;
public:
explicit buffer_appender(buffer<T>& buf)
: std::back_insert_iterator<buffer<T>>(buf) {}
buffer_appender(std::back_insert_iterator<buffer<T>> it)
: std::back_insert_iterator<buffer<T>>(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.
Expand Down
24 changes: 24 additions & 0 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<check_back_appender> {
template <typename ParseContext>
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}

template <typename Context>
auto format(check_back_appender, Context& ctx) -> decltype(ctx.out()) {
auto out = ctx.out();
static_assert(std::is_same<decltype(++out), decltype(out)&>::value,
"needs to satisfy weakly_incrementable");
*out = 'y';
return ++out;
}
};
FMT_END_NAMESPACE

TEST(FormatTest, BackInsertSlicing) {
EXPECT_EQ(fmt::format("{}", check_back_appender{}), "y");
}

0 comments on commit 6be6544

Please sign in to comment.