diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-10-30 13:01:56 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-11-04 11:21:50 +0100 |
commit | 9ee50a14b72706334c7a26469afac3999d3bdac5 (patch) | |
tree | f244720aae86af8ae99925bd4aaa82486cd4328f /src/corelib/tools/qarraydataops.h | |
parent | b76fbb48fba51df95d1776b8c1ff358789d78031 (diff) |
Move insert() operation into QArrayDataOps
This allows us to unify and simplify the code base between QList,
QString and QByteArray.
Change-Id: Idc8f360d78f508a68f38eb3ef0ed6e5d37f90574
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydataops.h')
-rw-r--r-- | src/corelib/tools/qarraydataops.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 7121da6660..02f52fbefe 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -1024,6 +1024,7 @@ struct QCommonArrayOps : QArrayOpsSelector<T>::Type { using Base = typename QArrayOpsSelector<T>::Type; using Data = QTypedArrayData<T>; + using DataPointer = QArrayDataPointer<T>; using parameter_type = typename Base::parameter_type; using iterator = typename Base::iterator; using const_iterator = typename Base::const_iterator; @@ -1216,6 +1217,50 @@ public: Base::insert(GrowsForwardTag{}, where, qsizetype(n) - beginSize, t); } + void insert(qsizetype i, qsizetype n, parameter_type t) + { + if (this->needsDetach() || (n > this->freeSpaceAtBegin() && n > this->freeSpaceAtEnd())) { + typename Data::AllocationPosition pos = Data::AllocateAtEnd; + if (this->size != 0 && i <= (this->size >> 1)) + pos = Data::AllocateAtBeginning; + + 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 { + // we're detached and we can just move data around + if (i == this->size && n <= this->freeSpaceAtEnd()) { + copyAppend(n, t); + } else { + T copy(t); + insert(this->begin() + i, n, copy); + } + } + } + + void insert(qsizetype i, const T *data, qsizetype n) + { + if (this->needsDetach() || (n > this->freeSpaceAtBegin() && n > this->freeSpaceAtEnd())) { + typename Data::AllocationPosition pos = Data::AllocateAtEnd; + if (this->size != 0 && i <= (this->size >> 1)) + pos = Data::AllocateAtBeginning; + + 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(this->begin() + i, data, data + n); + } + + } + + template <typename iterator, typename ...Args> void emplace(iterator where, Args&&... args) { |