diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-11-04 22:59:09 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-11-17 11:45:46 +0100 |
commit | 6be39809b038768a665b0e29a3a3668fdc424d9a (patch) | |
tree | 51b29213d4beed589e89a6bcae34874d5f63c593 /src/corelib/tools/qarraydataops.h | |
parent | 20883c9bcc7882b79db438ed0959530f82c8ee0a (diff) |
Simplify reallocation handling in QList
Have one generic method for detaching and reallocations.
Use that method throughout QList to avoid duplicated
instantiations of code paths that are rarely used.
Change-Id: I5b9add3be5f17b387e2d34028b72c8f52db68444
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qarraydataops.h')
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 77 |
1 files changed, 27 insertions, 50 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index d7e7b4bf07..3548424b53 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -1311,60 +1311,37 @@ public: public: void insert(qsizetype i, qsizetype n, parameter_type t) { - if (this->needsDetach() || (n > this->freeSpaceAtBegin() && n > this->freeSpaceAtEnd())) { - typename Data::GrowthPosition pos = Data::GrowsAtEnd; - if (this->size != 0 && i <= (this->size >> 1)) - pos = Data::GrowsAtBeginning; - - DataPointer detached(DataPointer::allocateGrow(*this, n, pos)); - const_iterator where = this->constBegin() + i; - detached->copyAppend(this->constBegin(), where); - detached->copyAppend(n, t); - detached->copyAppend(where, this->constEnd()); - this->swap(detached); - } else { - T copy(t); - // Insert elements based on the divided distance. Good case: only 1 - // insert happens (either to the front part or to the back part). Bad - // case: both inserts happen, meaning that we touch all N elements in - // the container (this should be handled "outside" by ensuring enough - // free space by reallocating more frequently) - T *where = this->begin() + i; - const auto beginSize = sizeToInsertAtBegin(where, n); - if (beginSize) - Base::insert(GrowsBackwardsTag{}, where, beginSize, copy); - if (n - beginSize) - Base::insert(GrowsForwardTag{}, where, n - beginSize, copy); - } + T copy(t); + + typename Data::GrowthPosition pos = Data::GrowsAtEnd; + if (this->size != 0 && i <= (this->size >> 1)) + pos = Data::GrowsAtBeginning; + this->detachAndGrow(pos, n); + Q_ASSERT((pos == Data::GrowsAtBeginning && this->freeSpaceAtBegin() >= n) || + (pos == Data::GrowsAtEnd && this->freeSpaceAtEnd() >= n)); + + T *where = this->begin() + i; + if (pos == QArrayData::GrowsAtBeginning) + Base::insert(GrowsBackwardsTag{}, where, n, copy); + else + Base::insert(GrowsForwardTag{}, where, n, copy); } void insert(qsizetype i, const T *data, qsizetype n) { - if (this->needsDetach() || (n > this->freeSpaceAtBegin() && n > this->freeSpaceAtEnd())) { - typename Data::GrowthPosition pos = Data::GrowsAtEnd; - if (this->size != 0 && i <= (this->size >> 1)) - pos = Data::GrowsAtBeginning; - - DataPointer detached(DataPointer::allocateGrow(*this, n, pos)); - auto where = this->constBegin() + i; - detached->copyAppend(this->constBegin(), where); - detached->copyAppend(data, data + n); - detached->copyAppend(where, this->constEnd()); - this->swap(detached); - } else { - // Insert elements based on the divided distance. Good case: only 1 - // insert happens (either to the front part or to the back part). Bad - // case: both inserts happen, meaning that we touch all N elements in - // the container (this should be handled "outside" by ensuring enough - // free space by reallocating more frequently) - T *where = this->begin() + i; - const auto k = sizeToInsertAtBegin(where, n); - if (k) - Base::insert(GrowsBackwardsTag{}, where, data, data + k); - if (k != n) - Base::insert(GrowsForwardTag{}, where, data + k, data + n); - } - + typename Data::GrowthPosition pos = Data::GrowsAtEnd; + if (this->size != 0 && i <= (this->size >> 1)) + pos = Data::GrowsAtBeginning; + DataPointer oldData; + this->detachAndGrow(pos, n, &oldData); + Q_ASSERT((pos == Data::GrowsAtBeginning && this->freeSpaceAtBegin() >= n) || + (pos == Data::GrowsAtEnd && this->freeSpaceAtEnd() >= n)); + + T *where = this->begin() + i; + if (pos == QArrayData::GrowsAtBeginning) + Base::insert(GrowsBackwardsTag{}, where, data, data + n); + else + Base::insert(GrowsForwardTag{}, where, data, data + n); } template<typename... Args> |