/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include static const int N = 1000; struct MyBase { MyBase(int i_) : isCopy(false) { ++liveCount; i = i_; } MyBase(const MyBase &other) : isCopy(true) { if (isCopy) ++copyCount; ++liveCount; i = other.i; } MyBase &operator=(const MyBase &other) { if (!isCopy) { isCopy = true; ++copyCount; } else { ++errorCount; } i = other.i; return *this; } ~MyBase() { if (isCopy) { if (!copyCount) ++errorCount; else --copyCount; } if (!liveCount) ++errorCount; else --liveCount; } bool operator==(const MyBase &other) const { return i == other.i; } protected: ushort i; bool isCopy; public: static int errorCount; static int liveCount; static int copyCount; }; int MyBase::errorCount = 0; int MyBase::liveCount = 0; int MyBase::copyCount = 0; struct MyPrimitive : public MyBase { MyPrimitive(int i = -1) : MyBase(i) { ++errorCount; } MyPrimitive(const MyPrimitive &other) : MyBase(other) { ++errorCount; } ~MyPrimitive() { ++errorCount; } }; struct MyMovable : public MyBase { MyMovable(int i = -1) : MyBase(i) {} }; struct MyComplex : public MyBase { MyComplex(int i = -1) : MyBase(i) {} }; QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE); QT_END_NAMESPACE class tst_QList: public QObject { Q_OBJECT private Q_SLOTS: void removeAll_primitive_data(); void removeAll_primitive(); void removeAll_movable_data(); void removeAll_movable(); void removeAll_complex_data(); void removeAll_complex(); }; template void removeAll_test(const QList &i10, ushort valueToRemove, int itemsToRemove) { bool isComplex = QTypeInfo::isComplex; MyBase::errorCount = 0; MyBase::liveCount = 0; MyBase::copyCount = 0; { QList list; QCOMPARE(MyBase::liveCount, 0); QCOMPARE(MyBase::copyCount, 0); for (int i = 0; i < 10 * N; ++i) { T t(i10.at(i % 10)); list.append(t); } QCOMPARE(MyBase::liveCount, isComplex ? list.size() : 0); QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0); T t(valueToRemove); QCOMPARE(MyBase::liveCount, isComplex ? list.size() + 1 : 1); QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0); int removedCount; QList l; QBENCHMARK { l = list; removedCount = l.removeAll(t); } QCOMPARE(removedCount, itemsToRemove * N); QCOMPARE(l.size() + removedCount, list.size()); QVERIFY(!l.contains(valueToRemove)); QCOMPARE(MyBase::liveCount, isComplex ? l.isDetached() ? list.size() + l.size() + 1 : list.size() + 1 : 1); QCOMPARE(MyBase::copyCount, isComplex ? l.isDetached() ? list.size() + l.size() : list.size() : 0); } if (isComplex) QCOMPARE(MyBase::errorCount, 0); } void tst_QList::removeAll_primitive_data() { qRegisterMetaType >(); QTest::addColumn >("i10"); QTest::addColumn("valueToRemove"); QTest::addColumn("itemsToRemove"); QTest::newRow("0%") << (QList() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0) << 5 << 0; QTest::newRow("10%") << (QList() << 0 << 0 << 0 << 0 << 5 << 0 << 0 << 0 << 0 << 0) << 5 << 1; QTest::newRow("90%") << (QList() << 5 << 5 << 5 << 5 << 0 << 5 << 5 << 5 << 5 << 5) << 5 << 9; QTest::newRow("100%") << (QList() << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5) << 5 << 10; } void tst_QList::removeAll_primitive() { QFETCH(QList, i10); QFETCH(int, valueToRemove); QFETCH(int, itemsToRemove); removeAll_test(i10, valueToRemove, itemsToRemove); } void tst_QList::removeAll_movable_data() { removeAll_primitive_data(); } void tst_QList::removeAll_movable() { QFETCH(QList, i10); QFETCH(int, valueToRemove); QFETCH(int, itemsToRemove); removeAll_test(i10, valueToRemove, itemsToRemove); } void tst_QList::removeAll_complex_data() { removeAll_primitive_data(); } void tst_QList::removeAll_complex() { QFETCH(QList, i10); QFETCH(int, valueToRemove); QFETCH(int, itemsToRemove); removeAll_test(i10, valueToRemove, itemsToRemove); } QTEST_APPLESS_MAIN(tst_QList) #include "main.moc"