summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydataops.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-11-11 13:19:53 +0100
committerLars Knoll <lars.knoll@qt.io>2020-11-17 11:47:09 +0100
commit39ca7d4bd189645c1b812c1ab3dbfc80a2bdfc33 (patch)
tree8937b981ced8b7fd46b02dc7abab7c57186dbb23 /src/corelib/tools/qarraydataops.h
parent168772fe8f1d83ffb480c3cc049595c82b4720df (diff)
Simplify insert() code for POD types
Change-Id: If2fba71ab690de6178fcdc0f27de08f2f8a01593 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@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.h100
1 files changed, 23 insertions, 77 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index fa3824f34b..020ffee4e1 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -255,6 +255,25 @@ public:
// exception safe; size not updated.
}
+ T *createHole(QArrayData::GrowthPosition pos, qsizetype where, qsizetype n)
+ {
+ Q_ASSERT((pos == QArrayData::GrowsAtBeginning && n <= this->freeSpaceAtBegin()) ||
+ (pos == QArrayData::GrowsAtEnd && n <= this->freeSpaceAtEnd()));
+
+ T *insertionPoint = this->ptr + where;
+ if (pos == QArrayData::GrowsAtEnd) {
+ if (where < this->size)
+ ::memmove(static_cast<void *>(insertionPoint + n), static_cast<void *>(insertionPoint), (this->size - where) * sizeof(T));
+ } else {
+ if (where > 0)
+ ::memmove(static_cast<void *>(this->ptr - n), static_cast<const void *>(this->ptr), where * sizeof(T));
+ this->ptr -= n;
+ insertionPoint -= n;
+ }
+ this->size += n;
+ return insertionPoint;
+ }
+
void insert(qsizetype i, const T *data, qsizetype n)
{
typename Data::GrowthPosition pos = Data::GrowsAtEnd;
@@ -265,46 +284,8 @@ public:
Q_ASSERT((pos == Data::GrowsAtBeginning && this->freeSpaceAtBegin() >= n) ||
(pos == Data::GrowsAtEnd && this->freeSpaceAtEnd() >= n));
- T *where = this->begin() + i;
- if (pos == QArrayData::GrowsAtBeginning)
- insert(GrowsBackwardsTag{}, where, data, data + n);
- else
- insert(GrowsForwardTag{}, where, data, data + n);
- }
-
- void insert(GrowsForwardTag, T *where, const T *b, const T *e) noexcept
- {
- Q_ASSERT(this->isMutable() || (b == e && where == this->end()));
- Q_ASSERT(!this->isShared() || (b == e && where == this->end()));
- Q_ASSERT(where >= this->begin() && where <= this->end());
- Q_ASSERT(b < e);
- Q_ASSERT(e <= where || b > this->end() || where == this->end()); // No overlap or append
- Q_ASSERT((e - b) <= this->freeSpaceAtEnd());
-
- if (where != this->end())
- ::memmove(static_cast<void *>(where + (e - b)), static_cast<void *>(where),
- (static_cast<const T*>(this->end()) - where) * sizeof(T));
- ::memcpy(static_cast<void *>(where), static_cast<const void *>(b), (e - b) * sizeof(T));
- this->size += (e - b);
- }
-
- void insert(GrowsBackwardsTag, T *where, const T *b, const T *e) noexcept
- {
- Q_ASSERT(this->isMutable() || (b == e && where == this->end()));
- Q_ASSERT(!this->isShared() || (b == e && where == this->end()));
- Q_ASSERT(where >= this->begin() && where <= this->end());
- Q_ASSERT(b < e);
- Q_ASSERT(e <= where || b > this->end() || where == this->end()); // No overlap or append
- Q_ASSERT((e - b) <= this->freeSpaceAtBegin());
-
- const T *oldBegin = this->begin();
- this->ptr -= (e - b);
- if (where != oldBegin)
- ::memmove(static_cast<void *>(this->begin()), static_cast<const void *>(oldBegin),
- (where - oldBegin) * sizeof(T));
- ::memcpy(static_cast<void *>(where - (e - b)), static_cast<const void *>(b),
- (e - b) * sizeof(T));
- this->size += (e - b);
+ T *where = createHole(pos, i, n);
+ ::memcpy(static_cast<void *>(where), static_cast<const void *>(data), n * sizeof(T));
}
void insert(qsizetype i, qsizetype n, parameter_type t)
@@ -318,44 +299,9 @@ public:
Q_ASSERT((pos == Data::GrowsAtBeginning && this->freeSpaceAtBegin() >= n) ||
(pos == Data::GrowsAtEnd && this->freeSpaceAtEnd() >= n));
- T *where = this->begin() + i;
- if (pos == QArrayData::GrowsAtBeginning)
- insert(GrowsBackwardsTag{}, where, n, copy);
- else
- insert(GrowsForwardTag{}, where, n, copy);
- }
-
- void insert(GrowsForwardTag, T *where, size_t n, parameter_type t) noexcept
- {
- Q_ASSERT(!this->isShared());
- Q_ASSERT(n);
- Q_ASSERT(where >= this->begin() && where <= this->end());
- Q_ASSERT(size_t(this->freeSpaceAtEnd()) >= n);
-
- if (where != this->end())
- ::memmove(static_cast<void *>(where + n), static_cast<void *>(where),
- (static_cast<const T*>(this->end()) - where) * sizeof(T));
- this->size += qsizetype(n); // PODs can't throw on copy
- while (n--)
- *where++ = t;
- }
-
- void insert(GrowsBackwardsTag, T *where, size_t n, parameter_type t) noexcept
- {
- Q_ASSERT(!this->isShared());
- Q_ASSERT(n);
- Q_ASSERT(where >= this->begin() && where <= this->end());
- Q_ASSERT(size_t(this->freeSpaceAtBegin()) >= n);
-
- const T *oldBegin = this->begin();
- this->ptr -= n;
- if (where != oldBegin)
- ::memmove(static_cast<void *>(this->begin()), static_cast<const void *>(oldBegin),
- (where - oldBegin) * sizeof(T));
- this->size += qsizetype(n); // PODs can't throw on copy
- where -= n;
+ T *where = createHole(pos, i, n);
while (n--)
- *where++ = t;
+ *where++ = copy;
}
template <typename ...Args>