summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydataops.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-10-30 13:01:56 +0100
committerLars Knoll <lars.knoll@qt.io>2020-11-04 11:21:50 +0100
commit9ee50a14b72706334c7a26469afac3999d3bdac5 (patch)
treef244720aae86af8ae99925bd4aaa82486cd4328f /src/corelib/tools/qarraydataops.h
parentb76fbb48fba51df95d1776b8c1ff358789d78031 (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.h45
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)
{