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/text/qstring.cpp | |
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/text/qstring.cpp')
-rw-r--r-- | src/corelib/text/qstring.cpp | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 40d69c9d9c..6e7809d868 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2728,34 +2728,30 @@ QString& QString::insert(qsizetype i, const QChar *unicode, qsizetype size) return *this; const auto s = reinterpret_cast<const char16_t *>(unicode); - if (points_into_range(s, d.data(), d.data() + d.size)) - return insert(i, QStringView{QVarLengthArray(s, s + size)}); - - const auto oldSize = this->size(); - qsizetype sizeToGrow = size; - if (i > oldSize) - sizeToGrow += i - oldSize; - - if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) { - QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd; - if (oldSize != 0 && i <= (oldSize >> 1)) - pos = QArrayData::AllocateAtBeginning; - - DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos)); - auto where = d.constBegin() + qMin(i, d->size); - detached->copyAppend(d.constBegin(), where); - if (i > oldSize) - detached->copyAppend(i - oldSize, u' '); - detached->copyAppend(s, s + size); - detached->copyAppend(where, d.constEnd()); - d.swap(detached); - } else { - if (i > oldSize) // set spaces in the uninitialized gap - d->copyAppend(i - oldSize, u' '); - d->insert(d.begin() + i, s, s + size); + // handle this specially, as QArrayDataOps::insert() doesn't handle out of + // bounds positions + if (i >= d->size) { + // In case when data points into the range or is == *this, we need to + // defer a call to free() so that it comes after we copied the data from + // the old memory: + DataPointer detached{}; // construction is free + if (d->needsDetach() || i + size - d->size > d.freeSpaceAtEnd()) { + detached = DataPointer::allocateGrow(d, i + size - d->size, Data::AllocateAtEnd); + detached->copyAppend(d.constBegin(), d.constEnd()); + d.swap(detached); + } + d->copyAppend(i - d->size, u' '); + d->copyAppend(s, s + size); + d.data()[d.size] = u'\0'; + return *this; } - d.data()[d.size] = '\0'; + + if (!d->needsDetach() && points_into_range(s, d.data(), d.data() + d.size)) + return insert(i, QStringView{QVarLengthArray(s, s + size)}); + + d->insert(i, s, size); + d.data()[d.size] = u'\0'; return *this; } |