Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COMMON/DIRECTOR: Move semantics for Arrays and some DIRECTOR structs #3480

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 48 additions & 0 deletions common/algorithm.h
Expand Up @@ -56,6 +56,19 @@ Out copy(In first, In last, Out dst) {
return dst;
}

/**
* Move data from the range [first, last) to [dst, dst + (last - first)).
*
* The function requires the range [dst, dst + (last - first)) to be valid.
* It also requires dst not to be in the range [first, last).
*/
template<class In, class Out>
Out move(In first, In last, Out dst) {
while (first != last)
*dst++ = std::move(*first++);
return dst;
}

/**
* Copy data from the range [first, last) to [dst - (last - first), dst).
*
Expand All @@ -71,6 +84,21 @@ Out copy_backward(In first, In last, Out dst) {
return dst;
}

/**
* Move data from the range [first, last) to [dst - (last - first), dst).
*
* The function requires the range [dst - (last - first), dst) to be valid.
* It also requires dst not to be in the range [first, last).
*
* Unlike move, move_backward copies the data from the end to the beginning.
*/
template<class In, class Out>
Out move_backward(In first, In last, Out dst) {
while (first != last)
*--dst = std::move(*--last);
return dst;
}

/**
* Copy data from the range [first, last) to [dst, dst + (last - first)).
*
Expand All @@ -91,6 +119,26 @@ Out copy_if(In first, In last, Out dst, Op op) {
return dst;
}

/**
* Move data from the range [first, last) to [dst, dst + (last - first)).
*
* The function requires the range [dst, dst + (last - first)) to be valid.
* It also requires dst not to be in the range [first, last).
*
* Unlike move or move_backward, it does not move all data. It only moves
* a data element when operator() of the op parameter returns true for the
* passed data element.
*/
template<class In, class Out, class Op>
Out move_if(In first, In last, Out dst, Op op) {
while (first != last) {
if (op(*first))
*dst++ = std::move(*first);
++first;
}
return dst;
}

/**
* @}
*/
Expand Down
26 changes: 13 additions & 13 deletions common/array.h
Expand Up @@ -118,7 +118,7 @@ class Array {
Array(std::initializer_list<T> list) : _size(list.size()) {
allocCapacity(list.size());
if (_storage)
Common::uninitialized_copy(list.begin(), list.end(), _storage);
Common::uninitialized_move(list.begin(), list.end(), _storage);
}

/**
Expand All @@ -145,7 +145,7 @@ class Array {
insert_aux(end(), &element, &element + 1);
}

/** Append an element to the end of the array. */
/** Append the elements of a given array to the end of this array. */
void push_back(const Array<T> &array) {
if (_size + array.size() <= _capacity) {
uninitialized_copy(array.begin(), array.end(), end());
Expand Down Expand Up @@ -285,7 +285,7 @@ class Array {

/** Erase the element at @p pos position and return an iterator pointing to the next element in the array. */
iterator erase(iterator pos) {
copy(pos + 1, _storage + _size, pos);
move(pos + 1, _storage + _size, pos);
_size--;
// We also need to destroy the last object properly here.
_storage[_size].~T();
Expand Down Expand Up @@ -346,8 +346,8 @@ class Array {
allocCapacity(newCapacity);

if (oldStorage) {
// Copy old data
uninitialized_copy(oldStorage, oldStorage + _size, _storage);
// Move old data
uninitialized_move(oldStorage, oldStorage + _size, _storage);
freeStorage(oldStorage, _size);
}
}
Expand Down Expand Up @@ -429,30 +429,30 @@ class Array {
// storage to avoid conflicts.
allocCapacity(roundUpCapacity(_size + n));

// Copy the data from the old storage till the position where
// Move the data from the old storage till the position where
// we insert new data
uninitialized_copy(oldStorage, oldStorage + idx, _storage);
uninitialized_move(oldStorage, oldStorage + idx, _storage);
// Copy the data we insert
uninitialized_copy(first, last, _storage + idx);
// Afterwards, copy the old data from the position where we
// Afterwards, move the old data from the position where we
// insert.
uninitialized_copy(oldStorage + idx, oldStorage + _size, _storage + idx + n);
uninitialized_move(oldStorage + idx, oldStorage + _size, _storage + idx + n);

freeStorage(oldStorage, _size);
} else if (idx + n <= _size) {
// Make room for the new elements by shifting back
// existing ones.
// 1. Move a part of the data to the uninitialized area
uninitialized_copy(_storage + _size - n, _storage + _size, _storage + _size);
uninitialized_move(_storage + _size - n, _storage + _size, _storage + _size);
// 2. Move a part of the data to the initialized area
copy_backward(pos, _storage + _size - n, _storage + _size);
move_backward(pos, _storage + _size - n, _storage + _size);

// Insert the new elements.
copy(first, last, pos);
} else {
// Copy the old data from the position till the end to the new
// Move the old data from the position till the end to the new
// place.
uninitialized_copy(pos, _storage + _size, _storage + idx + n);
uninitialized_move(pos, _storage + _size, _storage + idx + n);

// Copy a part of the new data to the position inside the
// initialized space.
Expand Down
12 changes: 12 additions & 0 deletions common/memory.h
Expand Up @@ -47,6 +47,18 @@ Type *uninitialized_copy(In first, In last, Type *dst) {
return dst;
}

/**
* Moves data from the range [first, last) to [dst, dst + (last - first)).
* It requires the range [dst, dst + (last - first)) to be valid and
* uninitialized.
*/
template<class In, class Type>
Type *uninitialized_move(In first, In last, Type *dst) {
while (first != last)
new ((void *)dst++) Type(std::move(*first++));
return dst;
}

/**
* Initializes the memory [first, first + (last - first)) with the value x.
* It requires the range [first, first + (last - first)) to be valid and
Expand Down
22 changes: 9 additions & 13 deletions engines/director/director.h
Expand Up @@ -166,21 +166,17 @@ struct DirectorPlotData {
applyColor = false;
}

DirectorPlotData(const DirectorPlotData &old) : _wm(old._wm), sprite(old.sprite),
ink(old.ink), alpha(old.alpha),
backColor(old.backColor), foreColor(old.foreColor),
srf(old.srf), dst(old.dst),
destRect(old.destRect), srcPoint(old.srcPoint),
colorWhite(old.colorWhite), colorBlack(old.colorBlack),
applyColor(old.applyColor) {
if (old.ms) {
ms = new MacShape(*old.ms);
} else {
ms = nullptr;
}
DirectorPlotData(DirectorPlotData &&old) : _wm(old._wm), sprite(old.sprite),
ink(old.ink), alpha(old.alpha),
backColor(old.backColor), foreColor(old.foreColor),
srf(old.srf), ms(old.ms), dst(old.dst),
destRect(old.destRect), srcPoint(old.srcPoint),
colorWhite(old.colorWhite), colorBlack(old.colorBlack),
applyColor(old.applyColor) {
old.ms = nullptr;
}

DirectorPlotData &operator=(const DirectorPlotData &);
DirectorPlotData &operator=(DirectorPlotData &&);

~DirectorPlotData() {
delete ms;
Expand Down
17 changes: 9 additions & 8 deletions engines/director/movie.h
Expand Up @@ -49,22 +49,23 @@ struct InfoEntry {

InfoEntry() { len = 0; data = nullptr; }

InfoEntry(const InfoEntry &old) {
len = old.len;
data = (byte *)malloc(len);
memcpy(data, old.data, len);
InfoEntry(InfoEntry &&old) : len(old.len), data(old.data) {
old.len = 0;
old.data = nullptr;
}

~InfoEntry() {
free(data);
data = nullptr;
}

InfoEntry &operator=(const InfoEntry &old) {
free(data);
InfoEntry &operator=(InfoEntry &&old) {
if (&old == this)
return *this;
len = old.len;
data = (byte *)malloc(len);
memcpy(data, old.data, len);
data = old.data;
old.len = 0;
old.data = nullptr;
return *this;
}

Expand Down