Implement move assignment operator for Array.

This commit is contained in:
Victor Zverovich 2014-04-25 08:18:07 -07:00
parent 5adc272ee7
commit 26277c8ab3
3 changed files with 36 additions and 17 deletions

View File

@ -226,12 +226,13 @@ TEST(ArrayTest, MoveCtor) {
// dynamic allocation.
array.push_back('a');
CheckMoveArray("testa", array);
const char *inline_buffer_ptr = &array[0];
// Adding one more character causes the content to move from the inline to
// a dynamically allocated buffer.
array.push_back('b');
Array<char, 5> array2(std::move(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_GT(array2.capacity(), 5);
}
@ -335,12 +336,13 @@ TEST(WriterTest, MoveCtor) {
w.Clear();
w << s;
CheckMoveWriter(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(std::move(w));
// 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());
}

View File

@ -33,7 +33,6 @@
#include "format.h"
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>

View File

@ -30,6 +30,7 @@
#include <stdint.h>
#include <cassert>
#include <cstddef> // for std::ptrdiff_t
#include <cstdio>
#include <algorithm>
@ -143,30 +144,47 @@ class Array {
void Grow(std::size_t size);
// Free memory allocated by the array.
void Free() {
if (ptr_ != data_) delete [] ptr_;
}
// Move data from other to this array.
void Move(Array &other) {
size_ = other.size_;
capacity_ = other.capacity_;
if (other.ptr_ == other.data_) {
ptr_ = data_;
std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_));
} else {
ptr_ = other.ptr_;
// Set pointer to the inline array so that delete is not called
// when freeing.
other.ptr_ = other.data_;
}
}
// Do not implement!
Array(const Array &);
void operator=(const Array &);
public:
Array() : size_(0), capacity_(SIZE), ptr_(data_) {}
~Array() {
if (ptr_ != data_) delete [] ptr_;
}
~Array() { Free(); }
#if FMT_USE_RVALUE_REFERENCES
Array(Array &&other)
: size_(other.size_),
capacity_(other.capacity_) {
if (other.ptr_ == other.data_) {
ptr_ = data_;
std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_));
} else {
ptr_ = other.ptr_;
other.ptr_ = 0;
}
Array(Array &&other) {
Move(other);
}
Array& operator=(Array&& other) {
assert(this != &other);
Free();
Move(other);
return *this;
}
// TODO: move assignment operator
#endif
// Returns the size of this array.