Smaller code cleanups in QList

Some cosmetics, but also some optimizations where we avoid a
temporary copy, or calling detach() twice.

Change-Id: I26803fdecf943ed9fab9baf58124091c7cebe1f3
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>
This commit is contained in:
Lars Knoll 2020-11-04 15:29:17 +01:00
parent 1c1c593510
commit 20883c9bcc
2 changed files with 13 additions and 14 deletions

View File

@ -162,17 +162,17 @@ public:
swap(tmp); swap(tmp);
} }
bool detach() QArrayDataPointer detach()
{ {
if (needsDetach()) { if (needsDetach()) {
QPair<Data *, T *> copy = clone(); QPair<Data *, T *> copy = clone();
QArrayDataPointer old(d, ptr, size); QArrayDataPointer old(d, ptr, size);
d = copy.first; d = copy.first;
ptr = copy.second; ptr = copy.second;
return true; return old;
} }
return false; return QArrayDataPointer();
} }
// forwards from QArrayData // forwards from QArrayData

View File

@ -385,8 +385,8 @@ public:
void replace(qsizetype i, parameter_type t) void replace(qsizetype i, parameter_type t)
{ {
Q_ASSERT_X(i >= 0 && i < d->size, "QList<T>::replace", "index out of range"); Q_ASSERT_X(i >= 0 && i < d->size, "QList<T>::replace", "index out of range");
const T copy(t); auto oldData = d.detach();
data()[i] = copy; d.data()[i] = t;
} }
void replace(qsizetype i, rvalue_ref t) void replace(qsizetype i, rvalue_ref t)
{ {
@ -395,16 +395,16 @@ public:
Q_UNUSED(t); Q_UNUSED(t);
} else { } else {
Q_ASSERT_X(i >= 0 && i < d->size, "QList<T>::replace", "index out of range"); Q_ASSERT_X(i >= 0 && i < d->size, "QList<T>::replace", "index out of range");
const T copy(std::move(t)); auto oldData = d.detach();
data()[i] = std::move(copy); d.data()[i] = std::move(t);
} }
} }
void remove(qsizetype i, qsizetype n = 1); void remove(qsizetype i, qsizetype n = 1);
void removeFirst(); void removeFirst();
void removeLast(); void removeLast();
value_type takeFirst() { Q_ASSERT(!isEmpty()); value_type v = std::move(first()); remove(0); return v; } value_type takeFirst() { Q_ASSERT(!isEmpty()); value_type v = std::move(first()); d->eraseFirst(); return v; }
value_type takeLast() { Q_ASSERT(!isEmpty()); value_type v = std::move(last()); remove(size() - 1); return v; } value_type takeLast() { Q_ASSERT(!isEmpty()); value_type v = std::move(last()); d->eraseLast(); return v; }
QList<T> &fill(parameter_type t, qsizetype size = -1); QList<T> &fill(parameter_type t, qsizetype size = -1);
@ -427,7 +427,6 @@ public:
return qsizetype(std::count(&*cbegin(), &*cend(), t)); return qsizetype(std::count(&*cbegin(), &*cend(), t));
} }
// QList compatibility
void removeAt(qsizetype i) { remove(i); } void removeAt(qsizetype i) { remove(i); }
template <typename AT = T> template <typename AT = T>
qsizetype removeAll(const AT &t) qsizetype removeAll(const AT &t)
@ -447,7 +446,7 @@ public:
const AT &tCopy = CopyProxy(t); const AT &tCopy = CopyProxy(t);
const iterator e = end(), it = std::remove(begin() + index, e, tCopy); const iterator e = end(), it = std::remove(begin() + index, e, tCopy);
const qsizetype result = std::distance(it, e); const qsizetype result = std::distance(it, e);
erase(it, e); d->erase(it, e);
return result; return result;
} }
template <typename AT = T> template <typename AT = T>
@ -606,9 +605,9 @@ inline void QList<T>::resize_internal(qsizetype newSize)
if (d->needsDetach() || newSize > capacity() - d.freeSpaceAtBegin()) { if (d->needsDetach() || newSize > capacity() - d.freeSpaceAtBegin()) {
// must allocate memory // must allocate memory
DataPointer detached(Data::allocate(d->detachCapacity(newSize))); DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
if (size() && newSize) { qsizetype toCopy = qMin(size(), newSize);
detached->copyAppend(constBegin(), constBegin() + qMin(newSize, size())); if (toCopy)
} detached->copyAppend(constBegin(), constBegin() + toCopy);
d.swap(detached); d.swap(detached);
} }