diff --git a/common/algorithm.h b/common/algorithm.h index 2cec6555a687..3f27200d3b8f 100644 --- a/common/algorithm.h +++ b/common/algorithm.h @@ -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 +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). * @@ -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 +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)). * @@ -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 +Out move_if(In first, In last, Out dst, Op op) { + while (first != last) { + if (op(*first)) + *dst++ = std::move(*first); + ++first; + } + return dst; +} + /** * @} */ diff --git a/common/array.h b/common/array.h index 18dc406255f2..c28d9b290c38 100644 --- a/common/array.h +++ b/common/array.h @@ -118,7 +118,7 @@ class Array { Array(std::initializer_list 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); } /** @@ -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 &array) { if (_size + array.size() <= _capacity) { uninitialized_copy(array.begin(), array.end(), end()); @@ -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(); @@ -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); } } @@ -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. diff --git a/common/memory.h b/common/memory.h index bdd521a17a01..8476a9272548 100644 --- a/common/memory.h +++ b/common/memory.h @@ -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 +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 diff --git a/engines/director/director.h b/engines/director/director.h index 4f6a989a8e47..deaf90f0c5ff 100644 --- a/engines/director/director.h +++ b/engines/director/director.h @@ -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; diff --git a/engines/director/movie.h b/engines/director/movie.h index 56f958c2df88..17671d8e9ae6 100644 --- a/engines/director/movie.h +++ b/engines/director/movie.h @@ -49,10 +49,9 @@ 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() { @@ -60,11 +59,13 @@ struct InfoEntry { 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; }