Clean up QList(iterator, iterator)

Fold the two overloads into one, and distinguish the cases using
if constexpr. Do not overload QArrayOps::copyAppend(), to make it
clear which one is being used.

Change-Id: If6a894841aacb84ba190fb2209246f5f61034b42
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Lars Knoll 2020-11-12 17:24:56 +01:00
parent 8c1ff78018
commit a1f3be3e41
3 changed files with 17 additions and 18 deletions

View File

@ -917,18 +917,14 @@ public:
// using Base::assign;
// using Base::compare;
using Base::copyAppend;
template<typename It>
void copyAppend(It b, It e, QtPrivate::IfIsForwardIterator<It> = true,
QtPrivate::IfIsNotConvertible<It, const T *> = true,
QtPrivate::IfIsNotConvertible<It, const T *> = true)
void appendIteratorRange(It b, It e, QtPrivate::IfIsForwardIterator<It> = true)
{
Q_ASSERT(this->isMutable() || b == e);
Q_ASSERT(!this->isShared() || b == e);
const qsizetype distance = std::distance(b, e);
Q_ASSERT(distance >= 0 && distance <= this->allocatedCapacity() - this->size);
Q_UNUSED(distance);
T *iter = this->end();
for (; b != e; ++iter, ++b) {

View File

@ -181,22 +181,25 @@ public:
d->copyAppend(args.begin(), args.end());
return *this;
}
template <typename InputIterator, QtPrivate::IfIsForwardIterator<InputIterator> = true>
template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true>
QList(InputIterator i1, InputIterator i2)
{
const auto distance = std::distance(i1, i2);
if (distance) {
d = DataPointer(Data::allocate(distance));
d->copyAppend(i1, i2);
if constexpr (!std::is_convertible_v<typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>) {
std::copy(i1, i2, std::back_inserter(*this));
} else {
const auto distance = std::distance(i1, i2);
if (distance) {
d = DataPointer(Data::allocate(distance));
if constexpr (std::is_same_v<std::decay_t<InputIterator>, iterator> ||
std::is_same_v<std::decay_t<InputIterator>, const_iterator>) {
d->copyAppend(i1, i2);
} else {
d->appendIteratorRange(i1, i2);
}
}
}
}
template <typename InputIterator, QtPrivate::IfIsNotForwardIterator<InputIterator> = true>
QList(InputIterator i1, InputIterator i2)
{
std::copy(i1, i2, std::back_inserter(*this));
}
// This constructor is here for compatibility with QStringList in Qt 5, that has a QStringList(const QString &) constructor
template<typename String, typename = std::enable_if_t<std::is_same_v<T, QString> && std::is_convertible_v<String, QString>>>
inline explicit QList(const String &str)

View File

@ -1169,7 +1169,7 @@ void tst_QArrayData::arrayOpsExtra()
auto copy = cloneArrayDataPointer(dataPointer, dataPointer.size);
const size_t distance = std::distance(first, last);
dataPointer->copyAppend(first, last);
dataPointer->appendIteratorRange(first, last);
QCOMPARE(size_t(dataPointer.size), originalSize + distance);
size_t i = 0;
for (; i < originalSize; ++i)