diff --git a/format-test.cc b/format-test.cc index db74c619..e18e4aeb 100644 --- a/format-test.cc +++ b/format-test.cc @@ -376,6 +376,36 @@ TEST(WriterTest, MoveCtor) { EXPECT_EQ(s + '*', w2.str()); } +void CheckMoveAssignWriter(const std::string &str, Writer &w) { + Writer w2; + w2 = std::move(w); + // Move shouldn't destroy the inline content of the first writer. + EXPECT_EQ(str, w.str()); + EXPECT_EQ(str, w2.str()); +} + +TEST(WriterTest, MoveAssignment) { + Writer w; + w << "test"; + CheckMoveAssignWriter("test", w); + // This fills the inline buffer, but doesn't cause dynamic allocation. + std::string s; + for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i) + s += '*'; + w.Clear(); + w << s; + CheckMoveAssignWriter(s, w); + const char *inline_buffer_ptr = w.data(); + // Adding one more character causes the content to move from the inline to + // a dynamically allocated buffer. + w << '*'; + Writer w2; + w2 = std::move(w); + // Move should rip the guts of the first writer. + EXPECT_EQ(inline_buffer_ptr, w.data()); + EXPECT_EQ(s + '*', w2.str()); +} + #endif // FMT_USE_RVALUE_REFERENCES TEST(WriterTest, Data) { diff --git a/format.h b/format.h index 09d3cb26..6e0f45e6 100644 --- a/format.h +++ b/format.h @@ -174,18 +174,16 @@ class Array { ~Array() { Free(); } #if FMT_USE_RVALUE_REFERENCES - Array(Array &&other) { Move(other); } - Array& operator=(Array&& other) { + Array& operator=(Array &&other) { assert(this != &other); Free(); Move(other); return *this; } - #endif // Returns the size of this array. @@ -922,6 +920,12 @@ class BasicWriter { #if FMT_USE_RVALUE_REFERENCES BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {} + + BasicWriter& operator=(BasicWriter &&other) { + assert(this != &other); + buffer_ = std::move(other.buffer_); + return *this; + } #endif /**