summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydataops.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-11-04 22:59:09 +0100
committerLars Knoll <lars.knoll@qt.io>2020-11-17 11:45:46 +0100
commit6be39809b038768a665b0e29a3a3668fdc424d9a (patch)
tree51b29213d4beed589e89a6bcae34874d5f63c593 /src/corelib/tools/qarraydataops.h
parent20883c9bcc7882b79db438ed0959530f82c8ee0a (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.h77
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>