Implement fast paths for removeFirst() and removeLast()

This avoids lots of the code and checks in remove() making the
methods a lot faster.

Change-Id: If99c39f5b55672b341f9331b5903bf77e9e67477
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Lars Knoll 2020-11-04 11:10:56 +01:00
parent 13fcd02ff9
commit f438286875
2 changed files with 64 additions and 2 deletions

View File

@ -429,6 +429,19 @@ public:
this->size -= (e - b);
}
void eraseFirst()
{
Q_ASSERT(this->size);
++this->ptr;
--this->size;
}
void eraseLast()
{
Q_ASSERT(this->size);
--this->size;
}
void assign(T *b, T *e, parameter_type t)
{
Q_ASSERT(b <= e);
@ -830,6 +843,22 @@ public:
} while (b != e);
}
void eraseFirst()
{
Q_ASSERT(this->size);
this->begin()->~T();
++this->ptr;
--this->size;
}
void eraseLast()
{
Q_ASSERT(this->size);
(--this->end())->~T();
--this->size;
}
void assign(T *b, T *e, parameter_type t)
{
Q_ASSERT(b <= e);
@ -1300,6 +1329,21 @@ public:
Base::erase(GrowsForwardTag{}, b, e);
}
}
void eraseFirst()
{
Q_ASSERT(this->isMutable());
Q_ASSERT(this->size);
Base::eraseFirst();
}
void eraseLast()
{
Q_ASSERT(this->isMutable());
Q_ASSERT(this->size);
Base::eraseLast();
}
};
} // namespace QtPrivate

View File

@ -377,8 +377,8 @@ public:
}
void remove(qsizetype i, qsizetype n = 1);
void removeFirst() { Q_ASSERT(!isEmpty()); remove(0); }
void removeLast() { Q_ASSERT(!isEmpty()); remove(size() - 1); }
void removeFirst();
void removeLast();
value_type takeFirst() { Q_ASSERT(!isEmpty()); value_type v = std::move(first()); remove(0); return v; }
value_type takeLast() { Q_ASSERT(!isEmpty()); value_type v = std::move(last()); remove(size() - 1); return v; }
@ -655,8 +655,26 @@ inline void QList<T>::remove(qsizetype i, qsizetype n)
// we're detached and we can just move data around
d->erase(d->begin() + i, d->begin() + i + n);
}
template <typename T>
inline void QList<T>::removeFirst()
{
Q_ASSERT(!isEmpty());
if (d->needsDetach())
d.detach();
d->eraseFirst();
}
template <typename T>
inline void QList<T>::removeLast()
{
Q_ASSERT(!isEmpty());
if (d->needsDetach())
detach();
d->eraseLast();
}
template<typename T>
inline T QList<T>::value(qsizetype i, parameter_type defaultValue) const
{