/**************************************************************************** ** ** 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 test suite 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 #include #include #include #include "functions.h" #include "../qfuture/versioncheck.h" Q_DECLARE_METATYPE(QVector); Q_DECLARE_METATYPE(QVector); Q_DECLARE_METATYPE(QVector); Q_DECLARE_METATYPE(QList); Q_DECLARE_METATYPE(QList); Q_DECLARE_METATYPE(QList); class tst_QtConcurrentMap: public QObject { Q_OBJECT private slots: void map(); void blocking_map(); void mapped(); void blocking_mapped(); void mappedReduced(); void blocking_mappedReduced(); void assignResult(); void functionOverloads(); #ifndef QT_NO_EXCEPTIONS void exceptions(); #endif void incrementalResults(); void noDetatch(); void stlContainers(); void qFutureAssignmentLeak(); void stressTest(); public slots: void throttling(); }; #if !defined (QT_NO_CONCURRENT_TEST) && !defined(QT_NO_CONCURRENT_MAP) using namespace QtConcurrent; void multiplyBy2Immutable(int x) { x *= 2; } class MultiplyBy2Immutable { public: void operator()(int x) { x *= 2; } }; void multiplyBy2InPlace(int &x) { x *= 2; } class MultiplyBy2InPlace { public: void operator()(int &x) { x *= 2; } }; Q_DECLARE_METATYPE(QList); void tst_QtConcurrentMap::map() { // functors take arguments by reference, modifying the sequence in place { QList list; list << 1 << 2 << 3; // functor QtConcurrent::map(list, MultiplyBy2InPlace()).waitForFinished(); QCOMPARE(list, QList() << 2 << 4 << 6); QtConcurrent::map(list.begin(), list.end(), MultiplyBy2InPlace()).waitForFinished(); QCOMPARE(list, QList() << 4 << 8 << 12); // function QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QList() << 8 << 16 << 24); QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QList() << 16 << 32 << 48); // bound function QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QList() << 32 << 64 << 96); QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QList() << 64 << 128 << 192); // member function QList numberList; numberList << 1 << 2 << 3; QtConcurrent::map(numberList, &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QList() << 2 << 4 << 6); QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QList() << 4 << 8 << 12); } // functors don't take arguments by reference, making these no-ops { QList list; list << 1 << 2 << 3; // functor QtConcurrent::map(list, MultiplyBy2Immutable()).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::map(list.begin(), list.end(), MultiplyBy2Immutable()).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); // function QtConcurrent::map(list, multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); // bound function QtConcurrent::map(list, multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); QCOMPARE(list, QList() << 1 << 2 << 3); } // Linked lists and forward iterators { QLinkedList list; list << 1 << 2 << 3; // functor QtConcurrent::map(list, MultiplyBy2InPlace()).waitForFinished(); QCOMPARE(list, QLinkedList() << 2 << 4 << 6); QtConcurrent::map(list.begin(), list.end(), MultiplyBy2InPlace()).waitForFinished(); QCOMPARE(list, QLinkedList() << 4 << 8 << 12); // function QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QLinkedList() << 8 << 16 << 24); QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QLinkedList() << 16 << 32 << 48); // bound function QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QLinkedList() << 32 << 64 << 96); QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); QCOMPARE(list, QLinkedList() << 64 << 128 << 192); // member function QLinkedList numberList; numberList << 1 << 2 << 3; QtConcurrent::map(numberList, &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QLinkedList() << 2 << 4 << 6); QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); QCOMPARE(numberList, QLinkedList() << 4 << 8 << 12); } #if 0 // not allowed: map() with immutable sequences makes no sense { const QList list = QList() << 1 << 2 << 3; QtConcurrent::map(list, MultiplyBy2Immutable()); QtConcurrent::map(list, multiplyBy2Immutable); QtConcurrent::map(list, multiplyBy2Immutable); } #endif #if 0 // not allowed: in place modification of a temp copy (since temp copy goes out of scope) { QList list; list << 1 << 2 << 3; QtConcurrent::map(QList(list), MultiplyBy2InPlace()); QtConcurrent::map(QList(list), multiplyBy2); QtConcurrent::map(QList(list), multiplyBy2InPlace); QList numberList; numberList << 1 << 2 << 3; QtConcurrent::map(QList(numberList), &Number::multiplyBy2); } #endif #if 0 // not allowed: map() on a const list, where functors try to modify the items in the list { const QList list = QList() << 1 << 2 << 3;; QtConcurrent::map(list, MultiplyBy2InPlace()); QtConcurrent::map(list, multiplyBy2InPlace); QtConcurrent::map(list, multiplyBy2InPlace); const QList numberList = QList() << 1 << 2 << 3; QtConcurrent::map(numberList, &Number::multiplyBy2); } #endif } void tst_QtConcurrentMap::blocking_map() { // functors take arguments by reference, modifying the sequence in place { QList list; list << 1 << 2 << 3; // functor QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); QCOMPARE(list, QList() << 2 << 4 << 6); QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2InPlace()); QCOMPARE(list, QList() << 4 << 8 << 12); // function QtConcurrent::blockingMap(list, multiplyBy2InPlace); QCOMPARE(list, QList() << 8 << 16 << 24); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); QCOMPARE(list, QList() << 16 << 32 << 48); // bound function QtConcurrent::blockingMap(list, multiplyBy2InPlace); QCOMPARE(list, QList() << 32 << 64 << 96); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); QCOMPARE(list, QList() << 64 << 128 << 192); // member function QList numberList; numberList << 1 << 2 << 3; QtConcurrent::blockingMap(numberList, &Number::multiplyBy2); QCOMPARE(numberList, QList() << 2 << 4 << 6); QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2); QCOMPARE(numberList, QList() << 4 << 8 << 12); } // functors don't take arguments by reference, making these no-ops { QList list; list << 1 << 2 << 3; // functor QtConcurrent::blockingMap(list, MultiplyBy2Immutable()); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2Immutable()); QCOMPARE(list, QList() << 1 << 2 << 3); // function QtConcurrent::blockingMap(list, multiplyBy2Immutable); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable); QCOMPARE(list, QList() << 1 << 2 << 3); // bound function QtConcurrent::blockingMap(list, multiplyBy2Immutable); QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable); QCOMPARE(list, QList() << 1 << 2 << 3); } // Linked lists and forward iterators { QLinkedList list; list << 1 << 2 << 3; // functor QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); QCOMPARE(list, QLinkedList() << 2 << 4 << 6); QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2InPlace()); QCOMPARE(list, QLinkedList() << 4 << 8 << 12); // function QtConcurrent::blockingMap(list, multiplyBy2InPlace); QCOMPARE(list, QLinkedList() << 8 << 16 << 24); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); QCOMPARE(list, QLinkedList() << 16 << 32 << 48); // bound function QtConcurrent::blockingMap(list, multiplyBy2InPlace); QCOMPARE(list, QLinkedList() << 32 << 64 << 96); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); QCOMPARE(list, QLinkedList() << 64 << 128 << 192); // member function QLinkedList numberList; numberList << 1 << 2 << 3; QtConcurrent::blockingMap(numberList, &Number::multiplyBy2); QCOMPARE(numberList, QLinkedList() << 2 << 4 << 6); QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2); QCOMPARE(numberList, QLinkedList() << 4 << 8 << 12); } #if 0 // not allowed: map() with immutable sequences makes no sense { const QList list = QList() << 1 << 2 << 3; QtConcurrent::blockingMap(list, MultiplyBy2Immutable()); QtConcurrent::blockkng::map(list, multiplyBy2Immutable); QtConcurrent::blockingMap(list, multiplyBy2Immutable); } #endif #if 0 // not allowed: in place modification of a temp copy (since temp copy goes out of scope) { QList list; list << 1 << 2 << 3; QtConcurrent::blockingMap(QList(list), MultiplyBy2InPlace()); QtConcurrent::blockingMap(QList(list), multiplyBy2); QtConcurrent::blockingMap(QList(list), multiplyBy2InPlace); QList numberList; numberList << 1 << 2 << 3; QtConcurrent::blockingMap(QList(numberList), &Number::multiplyBy2); } #endif #if 0 // not allowed: map() on a const list, where functors try to modify the items in the list { const QList list = QList() << 1 << 2 << 3;; QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); QtConcurrent::blockingMap(list, multiplyBy2InPlace); QtConcurrent::blockingMap(list, multiplyBy2InPlace); const QList numberList = QList() << 1 << 2 << 3; QtConcurrent::blockingMap(numberList, &Number::multiplyBy2); } #endif } int multiplyBy2(int x) { int y = x * 2; return y; } class MultiplyBy2 { public: typedef int result_type; int operator()(int x) const { int y = x * 2; return y; } }; double intToDouble(int x) { return double(x); } class IntToDouble { public: typedef double result_type; double operator()(int x) const { return double(x); } }; int stringToInt(const QString &string) { return string.toInt(); } class StringToInt { public: typedef int result_type; int operator()(const QString &string) const { return string.toInt(); } }; void tst_QtConcurrentMap::mapped() { QList list; list << 1 << 2 << 3; QLinkedList linkedList; linkedList << 1 << 2 << 3; QList numberList; numberList << 1 << 2 << 3; QLinkedList numberLinkedList; numberLinkedList << 1 << 2 << 3; // functor { QList list2 = QtConcurrent::mapped(list, MultiplyBy2()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), MultiplyBy2()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QList(list), MultiplyBy2()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QList list2 = QtConcurrent::mapped(linkedList, MultiplyBy2()).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), MultiplyBy2()).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), MultiplyBy2()).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } // function { QList list2 = QtConcurrent::mapped(list, multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QList(list), multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QList list2 = QtConcurrent::mapped(linkedList, multiplyBy2).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), multiplyBy2).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), multiplyBy2).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } // bound function { QList list2 = QtConcurrent::mapped(list, multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QList(list), multiplyBy2).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QList list2 = QtConcurrent::mapped(linkedList, multiplyBy2).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), multiplyBy2) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), multiplyBy2) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } // const member function { QList numberList2 = QtConcurrent::mapped(numberList, &Number::multipliedBy2) .results(); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList2, QList() << 2 << 4 << 6); QList numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(), &Number::multipliedBy2) .results(); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList3, QList() << 2 << 4 << 6); QList numberList4 = QtConcurrent::mapped(QList(numberList), &Number::multipliedBy2) .results(); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList4, QList() << 2 << 4 << 6); } { QList numberList2 = QtConcurrent::mapped(numberLinkedList, &Number::multipliedBy2) .results(); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberList2, QList() << 2 << 4 << 6); QList numberList3 = QtConcurrent::mapped(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::multipliedBy2) .results(); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberList3, QList() << 2 << 4 << 6); QList numberList4 = QtConcurrent::mapped(QLinkedList(numberLinkedList), &Number::multipliedBy2) .results(); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberList4, QList() << 2 << 4 << 6); } // change the value_type, same container // functor { QList list2 = QtConcurrent::mapped(list, IntToDouble()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), IntToDouble()) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QList(list), IntToDouble()) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QList list2 = QtConcurrent::mapped(linkedList, IntToDouble()).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), IntToDouble()) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), IntToDouble()) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } // function { QList list2 = QtConcurrent::mapped(list, intToDouble).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), intToDouble) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QList(list), intToDouble).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QList list2 = QtConcurrent::mapped(linkedList, intToDouble).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), intToDouble) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), intToDouble) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } // bound function { QList list2 = QtConcurrent::mapped(list, intToDouble).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), intToDouble) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QList(list), intToDouble) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QList list2 = QtConcurrent::mapped(linkedList, intToDouble).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::mapped(linkedList.constBegin(), linkedList.constEnd(), intToDouble) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::mapped(QLinkedList(linkedList), intToDouble) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } // const member function { QList list2 = QtConcurrent::mapped(numberList, &Number::toString).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << "1" << "2" << "3"); QList list3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(), &Number::toString) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << "1" << "2" << "3"); QList list4 = QtConcurrent::mapped(QList(numberList), &Number::toString) .results(); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << "1" << "2" << "3"); } { QList list2 = QtConcurrent::mapped(numberLinkedList, &Number::toString).results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list2, QList() << "1" << "2" << "3"); QList list3 = QtConcurrent::mapped(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toString) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list3, QList() << "1" << "2" << "3"); QList list4 = QtConcurrent::mapped(QLinkedList(numberLinkedList), &Number::toString) .results(); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(list4, QList() << "1" << "2" << "3"); } // change the value_type { QList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::mapped(strings, StringToInt()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(), StringToInt()) .results(); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::mapped(strings, stringToInt).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(), stringToInt).results(); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QList numberList2 = QtConcurrent::mapped(numberList, &Number::toInt).results(); QCOMPARE(numberList2, QList() << 1 << 2 << 3); QList numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(), &Number::toInt) .results(); QCOMPARE(numberList3, QList() << 1 << 2 << 3); } // change the value_type from QStringList { QStringList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::mapped(strings, StringToInt()).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(), StringToInt()) .results(); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QStringList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::mapped(strings, stringToInt).results(); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(), stringToInt) .results(); QCOMPARE(list2, QList() << 1 << 2 << 3); } } void tst_QtConcurrentMap::blocking_mapped() { QList list; list << 1 << 2 << 3; QLinkedList linkedList; linkedList << 1 << 2 << 3; QList numberList; numberList << 1 << 2 << 3; QLinkedList numberLinkedList; numberLinkedList << 1 << 2 << 3; // functor { QList list2 = QtConcurrent::blockingMapped(list, MultiplyBy2()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), MultiplyBy2()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::blockingMapped(QList(list), MultiplyBy2()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped(linkedList, MultiplyBy2()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), MultiplyBy2()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList4 = QtConcurrent::blockingMapped(QLinkedList(linkedList), MultiplyBy2()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 2 << 4 << 6); } // function { QList list2 = QtConcurrent::blockingMapped(list, multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::blockingMapped(QList(list), multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped(linkedList, multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList4 = QtConcurrent::blockingMapped(QLinkedList(linkedList), multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 2 << 4 << 6); } // bound function { QList list2 = QtConcurrent::blockingMapped(list, multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 2 << 4 << 6); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 2 << 4 << 6); QList list4 = QtConcurrent::blockingMapped(QList(list), multiplyBy2); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 2 << 4 << 6); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped(linkedList, multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 2 << 4 << 6); QLinkedList linkedList4 = QtConcurrent::blockingMapped(QLinkedList(linkedList), multiplyBy2); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 2 << 4 << 6); } // const member function { QList numberList2 = QtConcurrent::blockingMapped(numberList, &Number::multipliedBy2); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList2, QList() << 2 << 4 << 6); QList numberList3 = QtConcurrent::blockingMapped >(numberList.constBegin(), numberList.constEnd(), &Number::multipliedBy2); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList3, QList() << 2 << 4 << 6); QList numberList4 = QtConcurrent::blockingMapped(QList(numberList), &Number::multipliedBy2); QCOMPARE(numberList, QList() << 1 << 2 << 3); QCOMPARE(numberList4, QList() << 2 << 4 << 6); } { QLinkedList numberLinkedList2 = QtConcurrent::blockingMapped(numberLinkedList, &Number::multipliedBy2); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberLinkedList2, QLinkedList() << 2 << 4 << 6); QLinkedList numberLinkedList3 = QtConcurrent::blockingMapped >(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::multipliedBy2); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberLinkedList3, QLinkedList() << 2 << 4 << 6); QLinkedList numberLinkedList4 = QtConcurrent::blockingMapped(QLinkedList(numberLinkedList), &Number::multipliedBy2); QCOMPARE(numberLinkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(numberLinkedList4, QLinkedList() << 2 << 4 << 6); } // change the value_type, same container // functor { QList list2 = QtConcurrent::blockingMapped >(list, IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::blockingMapped >(QList(list), IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped >(linkedList, IntToDouble()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), IntToDouble()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList4 = QtConcurrent::blockingMapped >(QLinkedList(linkedList), IntToDouble()); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1.0 << 2.0 << 3.0); } // function { QList list2 = QtConcurrent::blockingMapped >(list, intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::blockingMapped >(QList(list), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped >(linkedList, intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList4 = QtConcurrent::blockingMapped >(QLinkedList(linkedList), intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1.0 << 2.0 << 3.0); } // bound function { QList list2 = QtConcurrent::blockingMapped >(list, intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); QList list4 = QtConcurrent::blockingMapped >(QList(list), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped >(linkedList, intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(linkedList.constBegin(), linkedList.constEnd(), intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1.0 << 2.0 << 3.0); QLinkedList linkedList4 = QtConcurrent::blockingMapped >(QLinkedList(linkedList), intToDouble); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1.0 << 2.0 << 3.0); } // const member function { QList list2 = QtConcurrent::blockingMapped >(numberList, &Number::toString); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << "1" << "2" << "3"); QList list3 = QtConcurrent::blockingMapped >(numberList.constBegin(), numberList.constEnd() , &Number::toString); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << "1" << "2" << "3"); QList list4 = QtConcurrent::blockingMapped >(QList(numberList), &Number::toString); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << "1" << "2" << "3"); } { QLinkedList linkedList2 = QtConcurrent::blockingMapped >(numberLinkedList, &Number::toString); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << "1" << "2" << "3"); QLinkedList linkedList3 = QtConcurrent::blockingMapped >(numberLinkedList.constBegin(), numberLinkedList.constEnd() , &Number::toString); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << "1" << "2" << "3"); QLinkedList linkedList4 = QtConcurrent::blockingMapped >(QLinkedList(numberLinkedList), &Number::toString); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << "1" << "2" << "3"); } // change the value_type { QList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::blockingMapped(strings, StringToInt()); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), StringToInt()); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::blockingMapped(strings, stringToInt); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), stringToInt); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QList numberList2 = QtConcurrent::blockingMapped(numberList, &Number::toInt); QCOMPARE(numberList2, QList() << 1 << 2 << 3); QList numberList3 = QtConcurrent::blockingMapped >(numberList.constBegin(), numberList.constEnd(), &Number::toInt); QCOMPARE(numberList3, QList() << 1 << 2 << 3); } // change the value_type from QStringList { QStringList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::blockingMapped(strings, StringToInt()); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), StringToInt()); QCOMPARE(list2, QList() << 1 << 2 << 3); } { QStringList strings = QStringList() << "1" << "2" << "3"; QList list = QtConcurrent::blockingMapped(strings, stringToInt); QCOMPARE(list, QList() << 1 << 2 << 3); QList list2 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), stringToInt); QCOMPARE(list2, QList() << 1 << 2 << 3); } // functor { QVector list2 = QtConcurrent::blockingMapped >(list, IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QVector() << 1.0 << 2.0 << 3.0); QVector list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QVector() << 1.0 << 2.0 << 3.0); QVector list4 = QtConcurrent::blockingMapped >(QList(list), IntToDouble()); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QVector() << 1.0 << 2.0 << 3.0); QStringList strings = QStringList() << "1" << "2" << "3"; QVector list5 = QtConcurrent::blockingMapped >(strings, StringToInt()); QCOMPARE(list5, QVector() << 1 << 2 << 3); QVector list6 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), StringToInt()); QCOMPARE(list6, QVector() << 1 << 2 << 3); QVector list7 = QtConcurrent::blockingMapped >(QStringList(strings), StringToInt()); QCOMPARE(list7, QVector() << 1 << 2 << 3); } // function { QVector list2 = QtConcurrent::blockingMapped >(list, intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QVector() << 1.0 << 2.0 << 3.0); QVector list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QVector() << 1.0 << 2.0 << 3.0); QVector list4 = QtConcurrent::blockingMapped >(QList(list), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QVector() << 1.0 << 2.0 << 3.0); QStringList strings = QStringList() << "1" << "2" << "3"; QVector list5 = QtConcurrent::blockingMapped >(strings, stringToInt); QCOMPARE(list5, QVector() << 1 << 2 << 3); QVector list6 = QtConcurrent::blockingMapped >(strings.constBegin(), strings.constEnd(), stringToInt); QCOMPARE(list6, QVector() << 1 << 2 << 3); QVector list7 = QtConcurrent::blockingMapped >(QStringList(strings), stringToInt); QCOMPARE(list7, QVector() << 1 << 2 << 3); } // bound function { QVector list2 = QtConcurrent::blockingMapped >(list, intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QVector() << 1.0 << 2.0 << 3.0); QVector list3 = QtConcurrent::blockingMapped >(QList(list), intToDouble); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QVector() << 1.0 << 2.0 << 3.0); QStringList strings = QStringList() << "1" << "2" << "3"; QVector list4 = QtConcurrent::blockingMapped >(strings, stringToInt); QCOMPARE(list4, QVector() << 1 << 2 << 3); QVector list5 = QtConcurrent::blockingMapped >(QStringList(strings), stringToInt); QCOMPARE(list5, QVector() << 1 << 2 << 3); } // const member function { QVector list2 = QtConcurrent::blockingMapped >(numberList, &Number::toString); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QVector() << "1" << "2" << "3"); QVector list3 = QtConcurrent::blockingMapped >(QList(numberList), &Number::toString); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QVector() << "1" << "2" << "3"); // not allowed: const member function where all arguments have default values #if 0 QStringList strings = QStringList() << "1" << "2" << "3"; QVector list4 = QtConcurrent::blockingMapped >(strings, &QString::toInt); QCOMPARE(list4, QVector() << 1 << 2 << 3); QVector list5 = QtConcurrent::blockingMapped >(QStringList(strings), &QString::toInt); QCOMPARE(list5, QVector() << 1 << 2 << 3); #endif } } int intSquare(int x) { return x * x; } class IntSquare { public: typedef int result_type; int operator()(int x) { return x * x; } }; void tst_QtConcurrentMap::mappedReduced() { QList list; list << 1 << 2 << 3; QLinkedList linkedList; linkedList << 1 << 2 << 3; QList numberList; numberList << 1 << 2 << 3; QLinkedList numberLinkedList; numberLinkedList << 1 << 2 << 3; // test Q_DECLARE_OPERATORS_FOR_FLAGS QtConcurrent::ReduceOptions opt = (QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce); // functor-functor { int sum = QtConcurrent::mappedReduced(list, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QList(list), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::mappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::mappedReduced(QList(list), intSquare, intSumReduce); QCOMPARE(sum6, 14); } { int sum = QtConcurrent::mappedReduced(linkedList, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QLinkedList(linkedList), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::mappedReduced(linkedList, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::mappedReduced(QLinkedList(linkedList), intSquare, intSumReduce); QCOMPARE(sum6, 14); } // function-functor { int sum = QtConcurrent::mappedReduced(list, intSquare, IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), intSquare, IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QList(list), intSquare, IntSumReduce()); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::mappedReduced(linkedList, intSquare, IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QLinkedList(linkedList), intSquare, IntSumReduce()); QCOMPARE(sum3, 14); } // functor-function { int sum = QtConcurrent::mappedReduced(list, IntSquare(), intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), IntSquare(), intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QList(list), IntSquare(), intSumReduce); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::mappedReduced(linkedList, IntSquare(), intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QLinkedList(linkedList), IntSquare(), intSumReduce); QCOMPARE(sum3, 14); } // function-function { int sum = QtConcurrent::mappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QList(list), intSquare, intSumReduce); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::mappedReduced(linkedList, intSquare, intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QLinkedList(linkedList), intSquare, intSumReduce); QCOMPARE(sum3, 14); } // functor-member { QList list2 = QtConcurrent::mappedReduced(list, IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1 << 4 << 9); QList list3 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1 << 4 << 9); QList list4 = QtConcurrent::mappedReduced(QList(list), IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1 << 4 << 9); } { QLinkedList linkedList2 = QtConcurrent::mappedReduced(linkedList, IntSquare(), &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList3 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList4 = QtConcurrent::mappedReduced(QLinkedList(linkedList), IntSquare(), &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1 << 4 << 9); } // member-functor { int sum = QtConcurrent::mappedReduced(numberList, &Number::toInt, IntSumReduce()); QCOMPARE(sum, 6); int sum2 = QtConcurrent::mappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, IntSumReduce()); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::mappedReduced(QList(numberList), &Number::toInt, IntSumReduce()); QCOMPARE(sum3, 6); } { int sum = QtConcurrent::mappedReduced(numberLinkedList, &Number::toInt, IntSumReduce()); QCOMPARE(sum, 6); int sum2 = QtConcurrent::mappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, IntSumReduce()); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::mappedReduced(QLinkedList(numberLinkedList), &Number::toInt, IntSumReduce()); QCOMPARE(sum3, 6); } // member-member { QList list2 = QtConcurrent::mappedReduced(numberList, &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list2, QList() << 1 << 2 << 3); QList list3 = QtConcurrent::mappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list3, QList() << 1 << 2 << 3); QList list4 = QtConcurrent::mappedReduced(QList(numberList), &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list4, QList() << 1 << 2 << 3); } { QLinkedList linkedList2 = QtConcurrent::mappedReduced(numberLinkedList, &Number::toInt, &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList2, QLinkedList() << 1 << 2 << 3); QLinkedList linkedList3 = QtConcurrent::mappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList3, QLinkedList() << 1 << 2 << 3); QLinkedList linkedList4 = QtConcurrent::mappedReduced(QLinkedList(numberLinkedList), &Number::toInt, &QLinkedList::push_back, OrderedReduce); QCOMPARE(linkedList4, QLinkedList() << 1 << 2 << 3); } // function-member { QList list2 = QtConcurrent::mappedReduced(list, intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1 << 4 << 9); QList list3 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1 << 4 << 9); QList list4 = QtConcurrent::mappedReduced(QList(list), intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1 << 4 << 9); } { QLinkedList linkedList2 = QtConcurrent::mappedReduced(linkedList, intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList3 = QtConcurrent::mappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList4 = QtConcurrent::mappedReduced(QLinkedList(linkedList), intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1 << 4 << 9); } // member-function { int sum = QtConcurrent::mappedReduced(numberList, &Number::toInt, intSumReduce); QCOMPARE(sum, 6); int sum2 = QtConcurrent::mappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, intSumReduce); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::mappedReduced(QList(numberList), &Number::toInt, intSumReduce); QCOMPARE(sum3, 6); } { int sum = QtConcurrent::mappedReduced(numberLinkedList, &Number::toInt, intSumReduce); QCOMPARE(sum, 6); int sum2 = QtConcurrent::mappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, intSumReduce); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::mappedReduced(QLinkedList(numberLinkedList), &Number::toInt, intSumReduce); QCOMPARE(sum3, 6); } // linked lists { QLinkedList list; list << 1 << 2 << 3; QLinkedList numberList; numberList << 1 << 2 << 3; int sum = QtConcurrent::mappedReduced(list, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::mappedReduced(QLinkedList(list), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::mappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::mappedReduced(QLinkedList(list), intSquare, intSumReduce); QCOMPARE(sum6, 14); } // ### the same as above, with an initial result value } void tst_QtConcurrentMap::blocking_mappedReduced() { QList list; list << 1 << 2 << 3; QLinkedList linkedList; linkedList << 1 << 2 << 3; QList numberList; numberList << 1 << 2 << 3; QLinkedList numberLinkedList; numberLinkedList << 1 << 2 << 3; // functor-functor { int sum = QtConcurrent::blockingMappedReduced(list, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QList(list), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::blockingMappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::blockingMappedReduced(QList(list), intSquare, intSumReduce); QCOMPARE(sum6, 14); } { int sum = QtConcurrent::blockingMappedReduced(linkedList, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::blockingMappedReduced(linkedList, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), intSquare, intSumReduce); QCOMPARE(sum6, 14); } // function-functor { int sum = QtConcurrent::blockingMappedReduced(list, intSquare, IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), intSquare, IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QList(list), intSquare, IntSumReduce()); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::blockingMappedReduced(linkedList, intSquare, IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), intSquare, IntSumReduce()); QCOMPARE(sum3, 14); } // functor-function { int sum = QtConcurrent::blockingMappedReduced(list, IntSquare(), intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), IntSquare(), intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QList(list), IntSquare(), intSumReduce); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::blockingMappedReduced(linkedList, IntSquare(), intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), IntSquare(), intSumReduce); QCOMPARE(sum3, 14); } // function-function { int sum = QtConcurrent::blockingMappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QList(list), intSquare, intSumReduce); QCOMPARE(sum3, 14); } { int sum = QtConcurrent::blockingMappedReduced(linkedList, intSquare, intSumReduce); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, intSumReduce); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), intSquare, intSumReduce); QCOMPARE(sum3, 14); } // functor-member { QList list2 = QtConcurrent::blockingMappedReduced(list, IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1 << 4 << 9); QList list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1 << 4 << 9); QList list4 = QtConcurrent::blockingMappedReduced(QList(list), IntSquare(), &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1 << 4 << 9); } { QLinkedList linkedList2 = QtConcurrent::blockingMappedReduced(linkedList, IntSquare(), &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList3 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), IntSquare(), &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), IntSquare(), &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1 << 4 << 9); } // member-functor { int sum = QtConcurrent::blockingMappedReduced(numberList, &Number::toInt, IntSumReduce()); QCOMPARE(sum, 6); int sum2 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, IntSumReduce()); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::blockingMappedReduced(QList(numberList), &Number::toInt, IntSumReduce()); QCOMPARE(sum3, 6); } { int sum = QtConcurrent::blockingMappedReduced(numberLinkedList, &Number::toInt, IntSumReduce()); QCOMPARE(sum, 6); int sum2 = QtConcurrent::blockingMappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, IntSumReduce()); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(numberLinkedList), &Number::toInt, IntSumReduce()); QCOMPARE(sum3, 6); } // member-member { QList list2 = QtConcurrent::blockingMappedReduced(numberList, &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list2, QList() << 1 << 2 << 3); QList list3 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list3, QList() << 1 << 2 << 3); QList list4 = QtConcurrent::blockingMappedReduced(QList(numberList), &Number::toInt, &QList::push_back, OrderedReduce); QCOMPARE(list4, QList() << 1 << 2 << 3); } { QLinkedList linkedList2 = QtConcurrent::blockingMappedReduced(numberLinkedList, &Number::toInt, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList2, QLinkedList() << 1 << 2 << 3); QLinkedList linkedList3 = QtConcurrent::blockingMappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList3, QLinkedList() << 1 << 2 << 3); QLinkedList linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList(numberLinkedList), &Number::toInt, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList4, QLinkedList() << 1 << 2 << 3); } // function-member { QList list2 = QtConcurrent::blockingMappedReduced(list, intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list2, QList() << 1 << 4 << 9); QList list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list3, QList() << 1 << 4 << 9); QList list4 = QtConcurrent::blockingMappedReduced(QList(list), intSquare, &QList::push_back, OrderedReduce); QCOMPARE(list, QList() << 1 << 2 << 3); QCOMPARE(list4, QList() << 1 << 4 << 9); } { QLinkedList linkedList2 = QtConcurrent::blockingMappedReduced(linkedList, intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList2, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList3 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), linkedList.constEnd(), intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList3, QLinkedList() << 1 << 4 << 9); QLinkedList linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList(linkedList), intSquare, &QLinkedList::append, OrderedReduce); QCOMPARE(linkedList, QLinkedList() << 1 << 2 << 3); QCOMPARE(linkedList4, QLinkedList() << 1 << 4 << 9); } // member-function { int sum = QtConcurrent::blockingMappedReduced(numberList, &Number::toInt, intSumReduce); QCOMPARE(sum, 6); int sum2 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), numberList.constEnd(), &Number::toInt, intSumReduce); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::blockingMappedReduced(QList(numberList), &Number::toInt, intSumReduce); QCOMPARE(sum3, 6); } { int sum = QtConcurrent::blockingMappedReduced(numberLinkedList, &Number::toInt, intSumReduce); QCOMPARE(sum, 6); int sum2 = QtConcurrent::blockingMappedReduced(numberLinkedList.constBegin(), numberLinkedList.constEnd(), &Number::toInt, intSumReduce); QCOMPARE(sum2, 6); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(numberLinkedList), &Number::toInt, intSumReduce); QCOMPARE(sum3, 6); } // linked lists { QLinkedList list; list << 1 << 2 << 3; QLinkedList numberList; numberList << 1 << 2 << 3; int sum = QtConcurrent::blockingMappedReduced(list, IntSquare(), IntSumReduce()); QCOMPARE(sum, 14); int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce()); QCOMPARE(sum2, 14); int sum3 = QtConcurrent::blockingMappedReduced(QLinkedList(list), IntSquare(), IntSumReduce()); QCOMPARE(sum3, 14); int sum4 = QtConcurrent::blockingMappedReduced(list, intSquare, intSumReduce); QCOMPARE(sum4, 14); int sum5 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), intSquare, intSumReduce); QCOMPARE(sum5, 14); int sum6 = QtConcurrent::blockingMappedReduced(QLinkedList(list), intSquare, intSumReduce); QCOMPARE(sum6, 14); } // ### the same as above, with an initial result value } int sleeper(int val) { QTest::qSleep(100); return val; } void tst_QtConcurrentMap::assignResult() { const QList startList = QList() << 0 << 1 << 2; QList list = QtConcurrent::blockingMapped(startList, sleeper); QCOMPARE(list.at(0), 0); QCOMPARE(list.at(1), 1); } int fnConst(const int &i) { return i; } int fn(int &i) { return i; } QString changeTypeConst(const int &) { return QString(); } QString changeType(int &) { return QString(); } int changeTypeQStringListConst(const QStringList &) { return 0; } int changeTypeQStringList(QStringList &) { return 0; } class MemFnTester { public: MemFnTester() {} MemFnTester fn() { return MemFnTester(); } MemFnTester fnConst() const { return MemFnTester(); } QString changeType() { return QString(); } QString changeTypeConst() const { return QString(); } }; Q_DECLARE_METATYPE(QVector); Q_DECLARE_METATYPE(QList); void tst_QtConcurrentMap::functionOverloads() { QList intList; const QList constIntList; QList classList; const QList constMemFnTesterList; QtConcurrent::mapped(intList, fnConst); QtConcurrent::mapped(constIntList, fnConst); QtConcurrent::mapped(classList, &MemFnTester::fnConst); QtConcurrent::mapped(constMemFnTesterList, &MemFnTester::fnConst); QtConcurrent::blockingMapped >(intList, fnConst); QtConcurrent::blockingMapped >(constIntList, fnConst); QtConcurrent::blockingMapped >(classList, &MemFnTester::fnConst); QtConcurrent::blockingMapped >(constMemFnTesterList, &MemFnTester::fnConst); QtConcurrent::blockingMapped >(intList, changeTypeConst); QtConcurrent::blockingMapped >(constIntList, changeTypeConst); QtConcurrent::blockingMapped >(classList, &MemFnTester::changeTypeConst); QtConcurrent::blockingMapped >(constMemFnTesterList, &MemFnTester::changeTypeConst); QStringList stringList; const QStringList constStringList; // QtConcurrent::map(stringList, changeTypeQStringListConst); // QtConcurrent::map(intList, changeTypeNonConst); // QList(QtConcurrent::map(constStringList, changeTypeQStringList)); // QtConcurrent::map(classList, &MemFnTester::changeType); // QtConcurrent::map(classList, &MemFnTester::changeTypeConst); // QtConcurrent::map(constMemFnTesterList, &MemFnTester::changeTypeConst); } QAtomicInt currentInstanceCount; QAtomicInt peakInstanceCount; class InstanceCounter { public: inline InstanceCounter() { currentInstanceCount.fetchAndAddRelaxed(1); updatePeak(); } inline ~InstanceCounter() { currentInstanceCount.fetchAndAddRelaxed(-1);} inline InstanceCounter(const InstanceCounter &) { currentInstanceCount.fetchAndAddRelaxed(1); updatePeak(); } void updatePeak() { forever { const int localPeak = peakInstanceCount; const int localCurrent = currentInstanceCount; if (localCurrent <= localPeak) break; if (peakInstanceCount.testAndSetOrdered(localPeak, localCurrent)) break; } } }; InstanceCounter slowMap(const InstanceCounter &in) { QTest::qSleep(2); return in; } InstanceCounter fastMap(const InstanceCounter &in) { QTest::qSleep(rand() % 2 + 1); // qDebug() << "map " << QThread::currentThread(); return in; } void slowReduce(int &result, const InstanceCounter&) { QTest::qSleep(rand() % 4 + 1); // qDebug() << "reduce" << QThread::currentThread(); ++result; } void fastReduce(int &result, const InstanceCounter&) { ++result; } void tst_QtConcurrentMap::throttling() { const int itemcount = 100; const int allowedTemporaries = QThread::idealThreadCount() * 40; { currentInstanceCount = 0; peakInstanceCount = 0; QList instances; for (int i = 0; i < itemcount; ++i) instances.append(InstanceCounter()); QCOMPARE((int)currentInstanceCount, itemcount); int results = QtConcurrent::blockingMappedReduced(instances, slowMap, fastReduce); QCOMPARE(results, itemcount); qDebug() << (int)currentInstanceCount; qDebug() << (int)peakInstanceCount; QCOMPARE(int(currentInstanceCount), itemcount); QVERIFY(int(peakInstanceCount) < itemcount + allowedTemporaries); } { QCOMPARE(int(currentInstanceCount), 0); peakInstanceCount = 0; QList instances; for (int i = 0; i < itemcount; ++i) instances.append(InstanceCounter()); QCOMPARE(int(currentInstanceCount), itemcount); int results = QtConcurrent::blockingMappedReduced(instances, fastMap, slowReduce); QCOMPARE(results, itemcount); qDebug() << (int)currentInstanceCount; qDebug() << (int)peakInstanceCount; QCOMPARE((int)currentInstanceCount, itemcount); QVERIFY(int(peakInstanceCount) < itemcount + allowedTemporaries); } } #ifndef QT_NO_EXCEPTIONS void throwMapper(int &e) { Q_UNUSED(e); throw QtConcurrent::Exception(); } void tst_QtConcurrentMap::exceptions() { bool caught = false; try { QList list = QList() << 1 << 2 << 3; QtConcurrent::map(list, throwMapper).waitForFinished(); } catch (Exception &e) { caught = true; } if (!caught) QFAIL("did not get exception"); } #endif int mapper(const int &i) { QTest::qWait(1); return i; } void tst_QtConcurrentMap::incrementalResults() { const int count = 200; QList ints; for (int i=0; i < count; ++i) ints << i; QFuture future = QtConcurrent::mapped(ints, mapper); QList results; while (future.isFinished() == false) { for (int i = 0; i < future.resultCount(); ++i) { results += future.resultAt(i); } QTest::qWait(1); } QCOMPARE(future.isFinished(), true); QCOMPARE(future.resultCount(), count); QCOMPARE(future.results().count(), count); } /* Test that mapped does not cause deep copies when holding references to Qt containers. */ void tst_QtConcurrentMap::noDetatch() { { QList l = QList() << 1; QVERIFY(l.isDetached()); QList ll = l; QVERIFY(l.isDetached() == false); QtConcurrent::mapped(l, mapper).waitForFinished(); QVERIFY(l.isDetached() == false); QVERIFY(ll.isDetached() == false); QtConcurrent::mappedReduced(l, mapper, intSumReduce).waitForFinished(); QVERIFY(l.isDetached() == false); QVERIFY(ll.isDetached() == false); QtConcurrent::map(l, multiplyBy2Immutable).waitForFinished(); QVERIFY(l.isDetached() == true); QVERIFY(ll.isDetached() == true); } { const QList l = QList() << 1; QVERIFY(l.isDetached()); const QList ll = l; QVERIFY(l.isDetached() == false); QtConcurrent::mapped(l, mapper).waitForFinished(); QVERIFY(l.isDetached() == false); QVERIFY(ll.isDetached() == false); QtConcurrent::mappedReduced(l, mapper, intSumReduce).waitForFinished(); QVERIFY(l.isDetached() == false); QVERIFY(ll.isDetached() == false); } } void tst_QtConcurrentMap::stlContainers() { #ifdef QT_NO_STL QSKIP("Qt compiled without STL support", SkipAll); #else std::vector vector; vector.push_back(1); vector.push_back(2); std::vector vector2 = QtConcurrent::blockingMapped >(vector, mapper); QCOMPARE(vector2.size(), (std::vector::size_type)(2)); std::list list; list.push_back(1); list.push_back(2); std::list list2 = QtConcurrent::blockingMapped >(list, mapper); QCOMPARE(list2.size(), (std::vector::size_type)(2)); QtConcurrent::mapped(list, mapper).waitForFinished(); QtConcurrent::blockingMap(list, multiplyBy2Immutable); #endif } InstanceCounter ic_fn(const InstanceCounter & ic) { return InstanceCounter(ic); }; // Verify that held results are deleted when a future is // assigned over with operator == void tst_QtConcurrentMap::qFutureAssignmentLeak() { currentInstanceCount = 0; peakInstanceCount = 0; QFuture future; { QList list; for (int i=0;i<1000;++i) list += InstanceCounter(); future = QtConcurrent::mapped(list, ic_fn); future.waitForFinished(); future = QtConcurrent::mapped(list, ic_fn); future.waitForFinished(); future = QtConcurrent::mapped(list, ic_fn); future.waitForFinished(); } QCOMPARE(int(currentInstanceCount), 1000); future = QFuture(); QCOMPARE(int(currentInstanceCount), 0); } inline void increment(int &num) { ++num; } inline int echo(const int &num) { return num; } void add(int &result, const int &sum) { result += sum; } void tst_QtConcurrentMap::stressTest() { const int listSize = 1000; const int sum = (listSize - 1) * (listSize / 2); QList list; for (int i = 0; i < listSize; ++i) { list.append(i); } for (int i =0 ; i < 100; ++i) { QList result = QtConcurrent::blockingMapped(list, echo); for (int j = 0; j < listSize; ++j) QCOMPARE(result.at(j), j); } for (int i = 0 ; i < 100; ++i) { int result = QtConcurrent::blockingMappedReduced(list, echo, add); QCOMPARE(result, sum); } for (int i = 0 ; i < 100; ++i) { QtConcurrent::map(list, increment).waitForFinished(); for (int j = 0; j < listSize; ++j) QCOMPARE(list.at(j), i + j + 1); } } QTEST_MAIN(tst_QtConcurrentMap) #else void tst_QtConcurrentMap::map() {} void tst_QtConcurrentMap::blocking_map() {} void tst_QtConcurrentMap::mapped() {} void tst_QtConcurrentMap::blocking_mapped() {} void tst_QtConcurrentMap::mappedReduced() {} void tst_QtConcurrentMap::blocking_mappedReduced() {} void tst_QtConcurrentMap::assignResult() {} void tst_QtConcurrentMap::functionOverloads() {} #ifndef QT_NO_EXCEPTIONS void tst_QtConcurrentMap::exceptions() {} #endif void tst_QtConcurrentMap::incrementalResults() {} void tst_QtConcurrentMap::stressTest() {} void tst_QtConcurrentMap::throttling() {} void tst_QtConcurrentMap::stlContainers() {} void tst_QtConcurrentMap::noDetatch() {} QTEST_NOOP_MAIN #endif #include "tst_qtconcurrentmap.moc"