From fc172c43132a15e17bd435db90e85722c7100361 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 6 Nov 2020 15:57:03 +0100 Subject: Simplify the code for QList::emplace() Unify it with the code in QArrayDataOps and only have one emplace method there that handles it all. Adjust autotests to API changes in QArrayDataOps and fix a wrong test case (that just happened to pass by chance before). Change-Id: Ia08cadebe2f74b82c31f856b1ff8a3d8dc400a3c Reviewed-by: Andrei Golubev Reviewed-by: Thiago Macieira --- src/corelib/tools/qarraydataops.h | 34 ++++++++++++++++++++-------------- src/corelib/tools/qlist.h | 20 +------------------- 2 files changed, 21 insertions(+), 33 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 3548424b53..c2414f22f2 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -1345,22 +1345,28 @@ public: } template - void emplace(T *where, Args &&... args) + void emplace(qsizetype i, Args &&... args) { - Q_ASSERT(!this->isShared()); - Q_ASSERT(where >= this->begin() && where <= this->end()); - Q_ASSERT(this->allocatedCapacity() - this->size >= 1); - - const T *begin = this->begin(); - const T *end = this->end(); - // Qt5 QList in insert(1): try to move less data around - // Now: - const bool shouldInsertAtBegin = - (where - begin) < (end - where) || this->freeSpaceAtEnd() <= 0; - if (this->freeSpaceAtBegin() > 0 && shouldInsertAtBegin) { - Base::emplace(GrowsBackwardsTag{}, where, std::forward(args)...); + typename QArrayData::GrowthPosition pos = QArrayData::GrowsAtEnd; + if (this->size != 0 && i <= (this->size >> 1)) + pos = QArrayData::GrowsAtBeginning; + if (this->needsDetach() || + (pos == QArrayData::GrowsAtBeginning && !this->freeSpaceAtBegin()) || + (pos == QArrayData::GrowsAtEnd && !this->freeSpaceAtEnd())) { + T tmp(std::forward(args)...); + this->reallocateAndGrow(pos, 1); + + T *where = this->begin() + i; + if (pos == QArrayData::GrowsAtBeginning) + Base::emplace(GrowsBackwardsTag{}, where, std::move(tmp)); + else + Base::emplace(GrowsForwardTag{}, where, std::move(tmp)); } else { - Base::emplace(GrowsForwardTag{}, where, std::forward(args)...); + T *where = this->begin() + i; + if (pos == QArrayData::GrowsAtBeginning) + Base::emplace(GrowsBackwardsTag{}, where, std::forward(args)...); + else + Base::emplace(GrowsForwardTag{}, where, std::forward(args)...); } } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index a5cb560dc0..9c95d49bae 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -743,25 +743,7 @@ typename QList::iterator QList::emplace(qsizetype i, Args&&... args) { Q_ASSERT_X(i >= 0 && i <= d->size, "QList::insert", "index out of range"); - - if (d->needsDetach() || (d.size == d.constAllocatedCapacity())) { - typename QArrayData::GrowthPosition pos = QArrayData::GrowsAtEnd; - if (d.size != 0 && i <= (d.size >> 1)) - pos = QArrayData::GrowsAtBeginning; - - DataPointer detached(DataPointer::allocateGrow(d, 1, pos)); - const_iterator where = constBegin() + i; - - // protect against args being an element of the container - T tmp(std::forward(args)...); - - detached->copyAppend(constBegin(), where); - detached->emplace(detached.end(), std::move(tmp)); - detached->copyAppend(where, constEnd()); - d.swap(detached); - } else { - d->emplace(d.begin() + i, std::forward(args)...); - } + d->emplace(i, std::forward(args)...); return d.begin() + i; } -- cgit v1.2.3