/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $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); } Q_DECLARE_METATYPE(QList); 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"