Commit 26277c8a authored by Victor Zverovich's avatar Victor Zverovich

Implement move assignment operator for Array.

parent 5adc272e
...@@ -226,12 +226,13 @@ TEST(ArrayTest, MoveCtor) { ...@@ -226,12 +226,13 @@ TEST(ArrayTest, MoveCtor) {
// dynamic allocation. // dynamic allocation.
array.push_back('a'); array.push_back('a');
CheckMoveArray("testa", array); CheckMoveArray("testa", array);
const char *inline_buffer_ptr = &array[0];
// Adding one more character causes the content to move from the inline to // Adding one more character causes the content to move from the inline to
// a dynamically allocated buffer. // a dynamically allocated buffer.
array.push_back('b'); array.push_back('b');
Array<char, 5> array2(std::move(array)); Array<char, 5> array2(std::move(array));
// Move should rip the guts of the first array. // Move should rip the guts of the first array.
EXPECT_TRUE(!&array[0]); EXPECT_EQ(inline_buffer_ptr, &array[0]);
EXPECT_EQ("testab", std::string(&array2[0], array2.size())); EXPECT_EQ("testab", std::string(&array2[0], array2.size()));
EXPECT_GT(array2.capacity(), 5); EXPECT_GT(array2.capacity(), 5);
} }
...@@ -335,12 +336,13 @@ TEST(WriterTest, MoveCtor) { ...@@ -335,12 +336,13 @@ TEST(WriterTest, MoveCtor) {
w.Clear(); w.Clear();
w << s; w << s;
CheckMoveWriter(s, w); CheckMoveWriter(s, w);
const char *inline_buffer_ptr = w.data();
// Adding one more character causes the content to move from the inline to // Adding one more character causes the content to move from the inline to
// a dynamically allocated buffer. // a dynamically allocated buffer.
w << '*'; w << '*';
Writer w2(std::move(w)); Writer w2(std::move(w));
// Move should rip the guts of the first writer. // Move should rip the guts of the first writer.
EXPECT_TRUE(!w.data()); EXPECT_EQ(inline_buffer_ptr, w.data());
EXPECT_EQ(s + '*', w2.str()); EXPECT_EQ(s + '*', w2.str());
} }
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "format.h" #include "format.h"
#include <cassert>
#include <cctype> #include <cctype>
#include <climits> #include <climits>
#include <cmath> #include <cmath>
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <stdint.h> #include <stdint.h>
#include <cassert>
#include <cstddef> // for std::ptrdiff_t #include <cstddef> // for std::ptrdiff_t
#include <cstdio> #include <cstdio>
#include <algorithm> #include <algorithm>
...@@ -143,30 +144,47 @@ class Array { ...@@ -143,30 +144,47 @@ class Array {
void Grow(std::size_t size); void Grow(std::size_t size);
// Do not implement! // Free memory allocated by the array.
Array(const Array &); void Free() {
void operator=(const Array &);
public:
Array() : size_(0), capacity_(SIZE), ptr_(data_) {}
~Array() {
if (ptr_ != data_) delete [] ptr_; if (ptr_ != data_) delete [] ptr_;
} }
#if FMT_USE_RVALUE_REFERENCES // Move data from other to this array.
Array(Array &&other) void Move(Array &other) {
: size_(other.size_), size_ = other.size_;
capacity_(other.capacity_) { capacity_ = other.capacity_;
if (other.ptr_ == other.data_) { if (other.ptr_ == other.data_) {
ptr_ = data_; ptr_ = data_;
std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_)); std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_));
} else { } else {
ptr_ = other.ptr_; ptr_ = other.ptr_;
other.ptr_ = 0; // Set pointer to the inline array so that delete is not called
// when freeing.
other.ptr_ = other.data_;
} }
} }
// TODO: move assignment operator // Do not implement!
Array(const Array &);
void operator=(const Array &);
public:
Array() : size_(0), capacity_(SIZE), ptr_(data_) {}
~Array() { Free(); }
#if FMT_USE_RVALUE_REFERENCES
Array(Array &&other) {
Move(other);
}
Array& operator=(Array&& other) {
assert(this != &other);
Free();
Move(other);
return *this;
}
#endif #endif
// Returns the size of this array. // Returns the size of this array.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment