diff options
Diffstat (limited to 'tests/auto/qtconcurrentmap')
-rw-r--r-- | tests/auto/qtconcurrentmap/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/qtconcurrentmap/functions.h | 130 | ||||
-rw-r--r-- | tests/auto/qtconcurrentmap/qtconcurrentmap.pro | 4 | ||||
-rw-r--r-- | tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp | 2396 |
4 files changed, 2531 insertions, 0 deletions
diff --git a/tests/auto/qtconcurrentmap/.gitignore b/tests/auto/qtconcurrentmap/.gitignore new file mode 100644 index 0000000..f1c563e --- /dev/null +++ b/tests/auto/qtconcurrentmap/.gitignore @@ -0,0 +1 @@ +tst_qtconcurrentmap diff --git a/tests/auto/qtconcurrentmap/functions.h b/tests/auto/qtconcurrentmap/functions.h new file mode 100644 index 0000000..b2db4f3 --- /dev/null +++ b/tests/auto/qtconcurrentmap/functions.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +bool keepEvenIntegers(const int &x) +{ + return (x & 1) == 0; +} + +class KeepEvenIntegers +{ +public: + bool operator()(const int &x) + { + return (x & 1) == 0; + } +}; + +class Number +{ + int n; + +public: + Number() + : n(0) + { } + + Number(int n) + : n(n) + { } + + void multiplyBy2() + { + n *= 2; + } + + Number multipliedBy2() const + { + return n * 2; + } + + bool isEven() const + { + return (n & 1) == 0; + } + + int toInt() const + { + return n; + } + + QString toString() const + { + return QString::number(n); + } + + bool operator==(const Number &other) const + { + return n == other.n; + } +}; + +void intSumReduce(int &sum, int x) +{ + sum += x; +} + +class IntSumReduce +{ +public: + void operator()(int &sum, int x) + { + sum += x; + } +}; + +void numberSumReduce(int &sum, const Number &x) +{ + sum += x.toInt(); +} + +class NumberSumReduce +{ +public: + void operator()(int &sum, const Number &x) + { + sum += x.toInt(); + } +}; + +#endif diff --git a/tests/auto/qtconcurrentmap/qtconcurrentmap.pro b/tests/auto/qtconcurrentmap/qtconcurrentmap.pro new file mode 100644 index 0000000..8cae714 --- /dev/null +++ b/tests/auto/qtconcurrentmap/qtconcurrentmap.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +DEFINES += QT_STRICT_ITERATORS +SOURCES += tst_qtconcurrentmap.cpp +QT = core diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp new file mode 100644 index 0000000..139eb6e --- /dev/null +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -0,0 +1,2396 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qtconcurrentmap.h> +#include <qtconcurrentexception.h> + +#include <qdebug.h> +#include <QThread> + +#include <QtTest/QtTest> + +#include "functions.h" +#include "../qfuture/versioncheck.h" + +Q_DECLARE_METATYPE(QVector<int>); +Q_DECLARE_METATYPE(QVector<double>); +Q_DECLARE_METATYPE(QVector<QString>); +Q_DECLARE_METATYPE(QList<int>); +Q_DECLARE_METATYPE(QList<double>); +Q_DECLARE_METATYPE(QList<QString>); + +class tst_map: 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 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<Number>); + +void tst_map::map() +{ + // functors take arguments by reference, modifying the sequence in place + { + QList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::map(list, MultiplyBy2InPlace()).waitForFinished(); + QCOMPARE(list, QList<int>() << 2 << 4 << 6); + QtConcurrent::map(list.begin(), list.end(), MultiplyBy2InPlace()).waitForFinished(); + QCOMPARE(list, QList<int>() << 4 << 8 << 12); + + // function + QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QList<int>() << 8 << 16 << 24); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QList<int>() << 16 << 32 << 48); + + // bound function + QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QList<int>() << 32 << 64 << 96); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QList<int>() << 64 << 128 << 192); + + // member function + QList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::map(numberList, &Number::multiplyBy2).waitForFinished(); + QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6); + QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); + QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12); + } + + // functors don't take arguments by reference, making these no-ops + { + QList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::map(list, MultiplyBy2Immutable()).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), MultiplyBy2Immutable()).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + // function + QtConcurrent::map(list, multiplyBy2Immutable).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + // bound function + QtConcurrent::map(list, multiplyBy2Immutable).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2Immutable).waitForFinished(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + } + + // Linked lists and forward iterators + { + QLinkedList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::map(list, MultiplyBy2InPlace()).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 2 << 4 << 6); + QtConcurrent::map(list.begin(), list.end(), MultiplyBy2InPlace()).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 4 << 8 << 12); + + // function + QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 8 << 16 << 24); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 16 << 32 << 48); + + // bound function + QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 32 << 64 << 96); + QtConcurrent::map(list.begin(), list.end(), multiplyBy2InPlace).waitForFinished(); + QCOMPARE(list, QLinkedList<int>() << 64 << 128 << 192); + + // member function + QLinkedList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::map(numberList, &Number::multiplyBy2).waitForFinished(); + QCOMPARE(numberList, QLinkedList<Number>() << 2 << 4 << 6); + QtConcurrent::map(numberList.begin(), numberList.end(), &Number::multiplyBy2).waitForFinished(); + QCOMPARE(numberList, QLinkedList<Number>() << 4 << 8 << 12); + } + +#if 0 + // not allowed: map() with immutable sequences makes no sense + { + const QList<int> list = QList<int>() << 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<int> list; + list << 1 << 2 << 3; + + QtConcurrent::map(QList<int>(list), MultiplyBy2InPlace()); + QtConcurrent::map(QList<int>(list), multiplyBy2); + QtConcurrent::map(QList<int>(list), multiplyBy2InPlace); + + QList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::map(QList<Number>(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<int> list = QList<int>() << 1 << 2 << 3;; + + QtConcurrent::map(list, MultiplyBy2InPlace()); + QtConcurrent::map(list, multiplyBy2InPlace); + QtConcurrent::map(list, multiplyBy2InPlace); + + const QList<Number> numberList = QList<Number>() << 1 << 2 << 3; + QtConcurrent::map(numberList, &Number::multiplyBy2); + } +#endif +} + +void tst_map::blocking_map() +{ + // functors take arguments by reference, modifying the sequence in place + { + QList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); + QCOMPARE(list, QList<int>() << 2 << 4 << 6); + QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2InPlace()); + QCOMPARE(list, QList<int>() << 4 << 8 << 12); + + // function + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + QCOMPARE(list, QList<int>() << 8 << 16 << 24); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); + QCOMPARE(list, QList<int>() << 16 << 32 << 48); + + // bound function + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + QCOMPARE(list, QList<int>() << 32 << 64 << 96); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); + QCOMPARE(list, QList<int>() << 64 << 128 << 192); + + // member function + QList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::blockingMap(numberList, &Number::multiplyBy2); + QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6); + QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2); + QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12); + } + + // functors don't take arguments by reference, making these no-ops + { + QList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::blockingMap(list, MultiplyBy2Immutable()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2Immutable()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + // function + QtConcurrent::blockingMap(list, multiplyBy2Immutable); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + // bound function + QtConcurrent::blockingMap(list, multiplyBy2Immutable); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + } + + // Linked lists and forward iterators + { + QLinkedList<int> list; + list << 1 << 2 << 3; + + // functor + QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); + QCOMPARE(list, QLinkedList<int>() << 2 << 4 << 6); + QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2InPlace()); + QCOMPARE(list, QLinkedList<int>() << 4 << 8 << 12); + + // function + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + QCOMPARE(list, QLinkedList<int>() << 8 << 16 << 24); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); + QCOMPARE(list, QLinkedList<int>() << 16 << 32 << 48); + + // bound function + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + QCOMPARE(list, QLinkedList<int>() << 32 << 64 << 96); + QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2InPlace); + QCOMPARE(list, QLinkedList<int>() << 64 << 128 << 192); + + // member function + QLinkedList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::blockingMap(numberList, &Number::multiplyBy2); + QCOMPARE(numberList, QLinkedList<Number>() << 2 << 4 << 6); + QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2); + QCOMPARE(numberList, QLinkedList<Number>() << 4 << 8 << 12); + } + +#if 0 + // not allowed: map() with immutable sequences makes no sense + { + const QList<int> list = QList<int>() << 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<int> list; + list << 1 << 2 << 3; + + QtConcurrent::blockingMap(QList<int>(list), MultiplyBy2InPlace()); + QtConcurrent::blockingMap(QList<int>(list), multiplyBy2); + QtConcurrent::blockingMap(QList<int>(list), multiplyBy2InPlace); + + QList<Number> numberList; + numberList << 1 << 2 << 3; + QtConcurrent::blockingMap(QList<Number>(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<int> list = QList<int>() << 1 << 2 << 3;; + + QtConcurrent::blockingMap(list, MultiplyBy2InPlace()); + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + QtConcurrent::blockingMap(list, multiplyBy2InPlace); + + const QList<Number> numberList = QList<Number>() << 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_map::mapped() +{ + QList<int> list; + list << 1 << 2 << 3; + QLinkedList<int> linkedList; + linkedList << 1 << 2 << 3; + QList<Number> numberList; + numberList << 1 << 2 << 3; + QLinkedList<Number> numberLinkedList; + numberLinkedList << 1 << 2 << 3; + + // functor + { + QList<int> list2 = QtConcurrent::mapped(list, MultiplyBy2()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + MultiplyBy2()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::mapped(QList<int>(list), MultiplyBy2()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QList<int> list2 = QtConcurrent::mapped(linkedList, MultiplyBy2()).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + MultiplyBy2()).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = + QtConcurrent::mapped(QLinkedList<int>(linkedList), MultiplyBy2()).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + + // function + { + QList<int> list2 = QtConcurrent::mapped(list, multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::mapped(QList<int>(list), multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QList<int> list2 = QtConcurrent::mapped(linkedList, multiplyBy2).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + multiplyBy2).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = + QtConcurrent::mapped(QLinkedList<int>(linkedList), multiplyBy2).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + + // bound function + { + QList<int> list2 = QtConcurrent::mapped(list, multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::mapped(QList<int>(list), multiplyBy2).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QList<int> list2 = QtConcurrent::mapped(linkedList, multiplyBy2).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + multiplyBy2) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::mapped(QLinkedList<int>(linkedList), multiplyBy2) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + + // const member function + { + QList<Number> numberList2 = QtConcurrent::mapped(numberList, &Number::multipliedBy2) + .results(); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList3 = QtConcurrent::mapped(numberList.constBegin(), + numberList.constEnd(), + &Number::multipliedBy2) + .results(); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList4 = QtConcurrent::mapped(QList<Number>(numberList), + &Number::multipliedBy2) + .results(); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6); + } + { + QList<Number> numberList2 = QtConcurrent::mapped(numberLinkedList, &Number::multipliedBy2) + .results(); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList3 = QtConcurrent::mapped(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::multipliedBy2) + .results(); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList4 = QtConcurrent::mapped(QLinkedList<Number>(numberLinkedList), + &Number::multipliedBy2) + .results(); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6); + } + + // change the value_type, same container + + // functor + { + QList<double> list2 = QtConcurrent::mapped(list, IntToDouble()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + IntToDouble()) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::mapped(QList<int>(list), + IntToDouble()) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QList<double> list2 = QtConcurrent::mapped(linkedList, IntToDouble()).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + IntToDouble()) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::mapped(QLinkedList<int>(linkedList), + IntToDouble()) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + + // function + { + QList<double> list2 = QtConcurrent::mapped(list, intToDouble).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + intToDouble) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::mapped(QList<int>(list), intToDouble).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QList<double> list2 = QtConcurrent::mapped(linkedList, intToDouble).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + intToDouble) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::mapped(QLinkedList<int>(linkedList), intToDouble) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + + // bound function + { + QList<double> list2 = QtConcurrent::mapped(list, intToDouble).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(list.constBegin(), + list.constEnd(), + intToDouble) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + + QList<double> list4 = QtConcurrent::mapped(QList<int>(list), + intToDouble) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QList<double> list2 = QtConcurrent::mapped(linkedList, intToDouble).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::mapped(linkedList.constBegin(), + linkedList.constEnd(), + intToDouble) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + + QList<double> list4 = QtConcurrent::mapped(QLinkedList<int>(linkedList), + intToDouble) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + + // const member function + { + QList<QString> list2 = QtConcurrent::mapped(numberList, &Number::toString).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list3 = QtConcurrent::mapped(numberList.constBegin(), + numberList.constEnd(), + &Number::toString) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list4 = QtConcurrent::mapped(QList<Number>(numberList), &Number::toString) + .results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<QString>() << "1" << "2" << "3"); + } + { + QList<QString> list2 = QtConcurrent::mapped(numberLinkedList, &Number::toString).results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list3 = QtConcurrent::mapped(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::toString) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list4 = QtConcurrent::mapped(QLinkedList<Number>(numberLinkedList), + &Number::toString) + .results(); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<QString>() << "1" << "2" << "3"); + } + + // change the value_type + { + QList<QString> strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::mapped(strings, StringToInt()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::mapped(strings.constBegin(), + strings.constEnd(), + StringToInt()) + .results(); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + { + QList<QString> strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::mapped(strings, stringToInt).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::mapped(strings.constBegin(), + strings.constEnd(), + stringToInt).results(); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + + { + QList<int> numberList2 = QtConcurrent::mapped(numberList, &Number::toInt).results(); + QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3); + + QList<int> numberList3 = QtConcurrent::mapped(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt) + .results(); + QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3); + } + + // change the value_type from QStringList + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::mapped(strings, StringToInt()).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::mapped(strings.constBegin(), + strings.constEnd(), + StringToInt()) + .results(); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::mapped(strings, stringToInt).results(); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::mapped(strings.constBegin(), + strings.constEnd(), + stringToInt) + .results(); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } +} + +void tst_map::blocking_mapped() +{ + QList<int> list; + list << 1 << 2 << 3; + QLinkedList<int> linkedList; + linkedList << 1 << 2 << 3; + QList<Number> numberList; + numberList << 1 << 2 << 3; + QLinkedList<Number> numberLinkedList; + numberLinkedList << 1 << 2 << 3; + + // functor + { + QList<int> list2 = QtConcurrent::blockingMapped(list, MultiplyBy2()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(list.constBegin(), + list.constEnd(), + MultiplyBy2()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::blockingMapped(QList<int>(list), MultiplyBy2()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(linkedList, MultiplyBy2()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(linkedList.constBegin(), + linkedList.constEnd(), + MultiplyBy2()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(QLinkedList<int>(linkedList), MultiplyBy2()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6); + } + + // function + { + QList<int> list2 = QtConcurrent::blockingMapped(list, multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(list.constBegin(), + list.constEnd(), + multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::blockingMapped(QList<int>(list), multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(linkedList, multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(linkedList.constBegin(), + linkedList.constEnd(), + multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(QLinkedList<int>(linkedList), multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6); + } + + // bound function + { + QList<int> list2 = QtConcurrent::blockingMapped(list, multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 2 << 4 << 6); + + QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(list.constBegin(), + list.constEnd(), + multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 2 << 4 << 6); + + QList<int> list4 = QtConcurrent::blockingMapped(QList<int>(list), multiplyBy2); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 2 << 4 << 6); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(linkedList, multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(linkedList.constBegin(), + linkedList.constEnd(), + multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(QLinkedList<int>(linkedList), multiplyBy2); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6); + } + + // const member function + { + QList<Number> numberList2 = QtConcurrent::blockingMapped(numberList, &Number::multipliedBy2); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList3 = QtConcurrent::blockingMapped<QList<Number> >(numberList.constBegin(), + numberList.constEnd(), + &Number::multipliedBy2); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6); + + QList<Number> numberList4 = QtConcurrent::blockingMapped(QList<Number>(numberList), + &Number::multipliedBy2); + QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3); + QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6); + } + { + QLinkedList<Number> numberLinkedList2 = QtConcurrent::blockingMapped(numberLinkedList, &Number::multipliedBy2); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberLinkedList2, QLinkedList<Number>() << 2 << 4 << 6); + + QLinkedList<Number> numberLinkedList3 = QtConcurrent::blockingMapped<QLinkedList<Number> >(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::multipliedBy2); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberLinkedList3, QLinkedList<Number>() << 2 << 4 << 6); + + QLinkedList<Number> numberLinkedList4 = QtConcurrent::blockingMapped(QLinkedList<Number>(numberLinkedList), + &Number::multipliedBy2); + QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3); + QCOMPARE(numberLinkedList4, QLinkedList<Number>() << 2 << 4 << 6); + } + + // change the value_type, same container + + // functor + { + QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(list, IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(list.constBegin(), + list.constEnd(), + IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(QList<int>(list), + IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList, IntToDouble()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList.constBegin(), + linkedList.constEnd(), + IntToDouble()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(QLinkedList<int>(linkedList), + IntToDouble()); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + } + + // function + { + QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(list, intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(list.constBegin(), + list.constEnd(), + intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(QList<int>(list), intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList, intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList.constBegin(), + linkedList.constEnd(), + intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(QLinkedList<int>(linkedList), intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + } + + // bound function + { + QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(list, intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0); + + QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(list.constBegin(), + list.constEnd(), + intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0); + + + QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(QList<int>(list), + intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0); + } + { + QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList, intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(linkedList.constBegin(), + linkedList.constEnd(), + intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + + + QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(QLinkedList<int>(linkedList), + intToDouble); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0); + } + + // const member function + { + QList<QString> list2 = + QtConcurrent::blockingMapped<QList<QString> >(numberList, &Number::toString); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list3 = QtConcurrent::blockingMapped<QList<QString> >(numberList.constBegin(), + numberList.constEnd() + , &Number::toString); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<QString>() << "1" << "2" << "3"); + + QList<QString> list4 = + QtConcurrent::blockingMapped<QList<QString> >(QList<Number>(numberList), &Number::toString); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<QString>() << "1" << "2" << "3"); + } + { + QLinkedList<QString> linkedList2 = + QtConcurrent::blockingMapped<QLinkedList<QString> >(numberLinkedList, &Number::toString); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<QString>() << "1" << "2" << "3"); + + QLinkedList<QString> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<QString> >(numberLinkedList.constBegin(), + numberLinkedList.constEnd() + , &Number::toString); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<QString>() << "1" << "2" << "3"); + + QLinkedList<QString> linkedList4 = + QtConcurrent::blockingMapped<QLinkedList<QString> >(QLinkedList<Number>(numberLinkedList), &Number::toString); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<QString>() << "1" << "2" << "3"); + } + + // change the value_type + { + QList<QString> strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::blockingMapped(strings, StringToInt()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(strings.constBegin(), + strings.constEnd(), + StringToInt()); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + { + QList<QString> strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::blockingMapped(strings, stringToInt); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(strings.constBegin(), + strings.constEnd(), + stringToInt); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + + { + QList<int> numberList2 = QtConcurrent::blockingMapped(numberList, &Number::toInt); + QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3); + + QList<int> numberList3 = QtConcurrent::blockingMapped<QList<int> >(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt); + QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3); + } + + // change the value_type from QStringList + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::blockingMapped(strings, StringToInt()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(strings.constBegin(), + strings.constEnd(), + StringToInt()); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList<int> list = QtConcurrent::blockingMapped(strings, stringToInt); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + + QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(strings.constBegin(), + strings.constEnd(), + stringToInt); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + } + + // functor + { + QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(list, IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0); + + QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(list.constBegin(), + list.constEnd(), + IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0); + + QVector<double> list4 = QtConcurrent::blockingMapped<QVector<double> >(QList<int>(list), + IntToDouble()); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QVector<double>() << 1.0 << 2.0 << 3.0); + + QStringList strings = QStringList() << "1" << "2" << "3"; + QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(strings, StringToInt()); + QCOMPARE(list5, QVector<int>() << 1 << 2 << 3); + + QVector<int> list6 = QtConcurrent::blockingMapped<QVector<int> >(strings.constBegin(), + strings.constEnd(), + StringToInt()); + QCOMPARE(list6, QVector<int>() << 1 << 2 << 3); + + QVector<int> list7 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings), + StringToInt()); + QCOMPARE(list7, QVector<int>() << 1 << 2 << 3); + } + + // function + { + QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(list, intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0); + + QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(list.constBegin(), + list.constEnd(), + intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0); + + QVector<double> list4 = QtConcurrent::blockingMapped<QVector<double> >(QList<int>(list), + intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QVector<double>() << 1.0 << 2.0 << 3.0); + + QStringList strings = QStringList() << "1" << "2" << "3"; + QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(strings, stringToInt); + QCOMPARE(list5, QVector<int>() << 1 << 2 << 3); + + QVector<int> list6 = QtConcurrent::blockingMapped<QVector<int> >(strings.constBegin(), + strings.constEnd(), + stringToInt); + QCOMPARE(list6, QVector<int>() << 1 << 2 << 3); + + QVector<int> list7 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings), + stringToInt); + QCOMPARE(list7, QVector<int>() << 1 << 2 << 3); + } + + // bound function + { + QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(list, intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0); + + QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(QList<int>(list), intToDouble); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0); + + QStringList strings = QStringList() << "1" << "2" << "3"; + QVector<int> list4 = QtConcurrent::blockingMapped<QVector<int> >(strings, stringToInt); + QCOMPARE(list4, QVector<int>() << 1 << 2 << 3); + + QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings), stringToInt); + QCOMPARE(list5, QVector<int>() << 1 << 2 << 3); + } + + // const member function + { + QVector<QString> list2 = QtConcurrent::blockingMapped<QVector<QString> >(numberList, &Number::toString); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QVector<QString>() << "1" << "2" << "3"); + + QVector<QString> list3 = + QtConcurrent::blockingMapped<QVector<QString> >(QList<Number>(numberList), &Number::toString); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QVector<QString>() << "1" << "2" << "3"); + + // not allowed: const member function where all arguments have default values +#if 0 + QStringList strings = QStringList() << "1" << "2" << "3"; + QVector<int> list4 = QtConcurrent::blockingMapped<QVector<int> >(strings, &QString::toInt); + QCOMPARE(list4, QVector<int>() << 1 << 2 << 3); + + QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings), &QString::toInt); + QCOMPARE(list5, QVector<int>() << 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_map::mappedReduced() +{ + QList<int> list; + list << 1 << 2 << 3; + QLinkedList<int> linkedList; + linkedList << 1 << 2 << 3; + QList<Number> numberList; + numberList << 1 << 2 << 3; + QLinkedList<Number> numberLinkedList; + numberLinkedList << 1 << 2 << 3; + + // test Q_DECLARE_OPERATORS_FOR_FLAGS + QtConcurrent::ReduceOptions opt = (QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce); + + // functor-functor + { + int sum = QtConcurrent::mappedReduced<int>(list, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), + list.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::mappedReduced<int>(list, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::mappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::mappedReduced<int>(QList<int>(list), + intSquare, + intSumReduce); + QCOMPARE(sum6, 14); + } + { + int sum = QtConcurrent::mappedReduced<int>(linkedList, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced<int>(QLinkedList<int>(linkedList), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::mappedReduced<int>(linkedList, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::mappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::mappedReduced<int>(QLinkedList<int>(linkedList), + intSquare, + intSumReduce); + QCOMPARE(sum6, 14); + } + + // function-functor + { + int sum = QtConcurrent::mappedReduced<int>(list, intSquare, IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list), intSquare, IntSumReduce()); + QCOMPARE(sum3, 14); + } + { + int sum = QtConcurrent::mappedReduced<int>(linkedList, intSquare, IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced<int>(QLinkedList<int>(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<int>(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<int>(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<int>(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<int>(linkedList), intSquare, intSumReduce); + QCOMPARE(sum3, 14); + } + + // functor-member + { + QList<int> list2 = QtConcurrent::mappedReduced(list, + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 1 << 4 << 9); + + QList<int> list3 = QtConcurrent::mappedReduced(list.constBegin(), + list.constEnd(), + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 1 << 4 << 9); + + QList<int> list4 = QtConcurrent::mappedReduced(QList<int>(list), + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 1 << 4 << 9); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(linkedList, + IntSquare(), + &QLinkedList<int>::push_back, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(linkedList.constBegin(), + linkedList.constEnd(), + IntSquare(), + &QLinkedList<int>::push_back, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(QLinkedList<int>(linkedList), + IntSquare(), + &QLinkedList<int>::push_back, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9); + } + + // member-functor + { + int sum = QtConcurrent::mappedReduced<int>(numberList, &Number::toInt, IntSumReduce()); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::mappedReduced<int>(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::mappedReduced<int>(QList<Number>(numberList), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum3, 6); + } + { + int sum = QtConcurrent::mappedReduced<int>(numberLinkedList, &Number::toInt, IntSumReduce()); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::mappedReduced<int>(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::mappedReduced<int>(QLinkedList<Number>(numberLinkedList), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum3, 6); + } + + // member-member + { + QList<int> list2 = QtConcurrent::mappedReduced(numberList, + &Number::toInt, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + + QList<int> list3 = QtConcurrent::mappedReduced(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list3, QList<int>() << 1 << 2 << 3); + + QList<int> list4 = QtConcurrent::mappedReduced(QList<Number>(numberList), + &Number::toInt, + &QList<int>::push_back, OrderedReduce); + QCOMPARE(list4, QList<int>() << 1 << 2 << 3); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(numberLinkedList, + &Number::toInt, + &QLinkedList<int>::push_back, + OrderedReduce); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 2 << 3); + + QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::toInt, + &QLinkedList<int>::push_back, + OrderedReduce); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 2 << 3); + + QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(QLinkedList<Number>(numberLinkedList), + &Number::toInt, + &QLinkedList<int>::push_back, OrderedReduce); + QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 2 << 3); + } + + // function-member + { + QList<int> list2 = QtConcurrent::mappedReduced(list, + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 1 << 4 << 9); + + QList<int> list3 = QtConcurrent::mappedReduced(list.constBegin(), + list.constEnd(), + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 1 << 4 << 9); + + QList<int> list4 = QtConcurrent::mappedReduced(QList<int>(list), + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 1 << 4 << 9); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(linkedList, + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(QLinkedList<int>(linkedList), + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 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<Number>(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<Number>(numberLinkedList), + &Number::toInt, + intSumReduce); + QCOMPARE(sum3, 6); + } + + // linked lists + { + + QLinkedList<int> list; + list << 1 << 2 << 3; + + QLinkedList<Number> numberList; + numberList << 1 << 2 << 3; + + int sum = QtConcurrent::mappedReduced<int>(list, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), + list.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced<int>(QLinkedList<int>(list), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::mappedReduced<int>(list, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::mappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::mappedReduced<int>(QLinkedList<int>(list), + intSquare, + intSumReduce); + QCOMPARE(sum6, 14); + } + + // ### the same as above, with an initial result value +} + +void tst_map::blocking_mappedReduced() +{ + QList<int> list; + list << 1 << 2 << 3; + QLinkedList<int> linkedList; + linkedList << 1 << 2 << 3; + QList<Number> numberList; + numberList << 1 << 2 << 3; + QLinkedList<Number> numberLinkedList; + numberLinkedList << 1 << 2 << 3; + + // functor-functor + { + int sum = QtConcurrent::blockingMappedReduced<int>(list, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), + list.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::blockingMappedReduced<int>(list, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list), + intSquare, + intSumReduce); + QCOMPARE(sum6, 14); + } + { + int sum = QtConcurrent::blockingMappedReduced<int>(linkedList, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<int>(linkedList), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::blockingMappedReduced<int>(linkedList, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::blockingMappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<int>(linkedList), + intSquare, + intSumReduce); + QCOMPARE(sum6, 14); + } + + // function-functor + { + int sum = QtConcurrent::blockingMappedReduced<int>(list, intSquare, IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list), intSquare, IntSumReduce()); + QCOMPARE(sum3, 14); + } + { + int sum = QtConcurrent::blockingMappedReduced<int>(linkedList, intSquare, IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced<int>(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<int>(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<int>(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<int>(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<int>(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<int>(linkedList), intSquare, intSumReduce); + QCOMPARE(sum3, 14); + } + + // functor-member + { + QList<int> list2 = QtConcurrent::blockingMappedReduced(list, + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 1 << 4 << 9); + + QList<int> list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), + list.constEnd(), + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 1 << 4 << 9); + + QList<int> list4 = QtConcurrent::blockingMappedReduced(QList<int>(list), + IntSquare(), + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 1 << 4 << 9); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(linkedList, + IntSquare(), + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), + linkedList.constEnd(), + IntSquare(), + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList<int>(linkedList), + IntSquare(), + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9); + } + + // member-functor + { + int sum = QtConcurrent::blockingMappedReduced<int>(numberList, &Number::toInt, + IntSumReduce()); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::blockingMappedReduced<int>(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<Number>(numberList), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum3, 6); + } + { + int sum = QtConcurrent::blockingMappedReduced<int>(numberLinkedList, &Number::toInt, IntSumReduce()); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::blockingMappedReduced<int>(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<Number>(numberLinkedList), + &Number::toInt, + IntSumReduce()); + QCOMPARE(sum3, 6); + } + + // member-member + { + QList<int> list2 = QtConcurrent::blockingMappedReduced(numberList, + &Number::toInt, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list2, QList<int>() << 1 << 2 << 3); + + QList<int> list3 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list3, QList<int>() << 1 << 2 << 3); + + QList<int> list4 = QtConcurrent::blockingMappedReduced(QList<Number>(numberList), + &Number::toInt, + &QList<int>::push_back, OrderedReduce); + QCOMPARE(list4, QList<int>() << 1 << 2 << 3); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(numberLinkedList, + &Number::toInt, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 2 << 3); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(numberLinkedList.constBegin(), + numberLinkedList.constEnd(), + &Number::toInt, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 2 << 3); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList<Number>(numberLinkedList), + &Number::toInt, + &QLinkedList<int>::append, OrderedReduce); + QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 2 << 3); + } + + // function-member + { + QList<int> list2 = QtConcurrent::blockingMappedReduced(list, + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list2, QList<int>() << 1 << 4 << 9); + + QList<int> list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), + list.constEnd(), + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list3, QList<int>() << 1 << 4 << 9); + + QList<int> list4 = QtConcurrent::blockingMappedReduced(QList<int>(list), + intSquare, + &QList<int>::push_back, + OrderedReduce); + QCOMPARE(list, QList<int>() << 1 << 2 << 3); + QCOMPARE(list4, QList<int>() << 1 << 4 << 9); + } + { + QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(linkedList, + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(linkedList.constBegin(), + linkedList.constEnd(), + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9); + + QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(QLinkedList<int>(linkedList), + intSquare, + &QLinkedList<int>::append, + OrderedReduce); + QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3); + QCOMPARE(linkedList4, QLinkedList<int>() << 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<Number>(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<Number>(numberLinkedList), + &Number::toInt, + intSumReduce); + QCOMPARE(sum3, 6); + } + + // linked lists + { + + QLinkedList<int> list; + list << 1 << 2 << 3; + + QLinkedList<Number> numberList; + numberList << 1 << 2 << 3; + + int sum = QtConcurrent::blockingMappedReduced<int>(list, IntSquare(), IntSumReduce()); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), + list.constEnd(), + IntSquare(), + IntSumReduce()); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<int>(list), IntSquare(), IntSumReduce()); + QCOMPARE(sum3, 14); + + int sum4 = QtConcurrent::blockingMappedReduced<int>(list, intSquare, intSumReduce); + QCOMPARE(sum4, 14); + int sum5 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), + list.constEnd(), + intSquare, + intSumReduce); + QCOMPARE(sum5, 14); + + int sum6 = QtConcurrent::blockingMappedReduced<int>(QLinkedList<int>(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_map::assignResult() +{ + const QList<int> startList = QList<int>() << 0 << 1 << 2; + QList<int> 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<MemFnTester>); +Q_DECLARE_METATYPE(QList<MemFnTester>); + +void tst_map::functionOverloads() +{ + QList<int> intList; + const QList<int> constIntList; + QList<MemFnTester> classList; + const QList<MemFnTester> constMemFnTesterList; + + QtConcurrent::mapped(intList, fnConst); + QtConcurrent::mapped(constIntList, fnConst); + QtConcurrent::mapped(classList, &MemFnTester::fnConst); + QtConcurrent::mapped(constMemFnTesterList, &MemFnTester::fnConst); + + QtConcurrent::blockingMapped<QVector<int> >(intList, fnConst); + QtConcurrent::blockingMapped<QVector<int> >(constIntList, fnConst); + QtConcurrent::blockingMapped<QVector<MemFnTester> >(classList, &MemFnTester::fnConst); + QtConcurrent::blockingMapped<QVector<MemFnTester> >(constMemFnTesterList, &MemFnTester::fnConst); + + QtConcurrent::blockingMapped<QList<QString> >(intList, changeTypeConst); + QtConcurrent::blockingMapped<QList<QString> >(constIntList, changeTypeConst); + QtConcurrent::blockingMapped<QList<QString> >(classList, &MemFnTester::changeTypeConst); + QtConcurrent::blockingMapped<QList<QString> >(constMemFnTesterList, &MemFnTester::changeTypeConst); + + QStringList stringList; + const QStringList constStringList; + // QtConcurrent::map(stringList, changeTypeQStringListConst); + // QtConcurrent::map(intList, changeTypeNonConst); + // QList<QString>(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_map::throttling() +{ + const int itemcount = 100; + const int allowedTemporaries = QThread::idealThreadCount() * 40; + + { + currentInstanceCount = 0; + peakInstanceCount = 0; + + QList<InstanceCounter> 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<InstanceCounter> 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_map::exceptions() +{ + bool caught = false; + try { + QList<int> list = QList<int>() << 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_map::incrementalResults() +{ + const int count = 200; + QList<int> ints; + for (int i=0; i < count; ++i) + ints << i; + + QFuture<int> future = QtConcurrent::mapped(ints, mapper); + + QList<int> 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_map::noDetatch() +{ + { + QList<int> l = QList<int>() << 1; + QVERIFY(l.isDetached()); + + QList<int> 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<int> l = QList<int>() << 1; + QVERIFY(l.isDetached()); + + const QList<int> 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_map::stlContainers() +{ +#ifdef QT_NO_STL + QSKIP("Qt compiled without STL support", SkipAll); +#else + std::vector<int> vector; + vector.push_back(1); + vector.push_back(2); + + std::vector<int> vector2 = QtConcurrent::blockingMapped<std::vector<int> >(vector, mapper); + QCOMPARE(vector2.size(), (std::vector<int>::size_type)(2)); + + std::list<int> list; + list.push_back(1); + list.push_back(2); + + std::list<int> list2 = QtConcurrent::blockingMapped<std::list<int> >(list, mapper); + QCOMPARE(list2.size(), (std::vector<int>::size_type)(2)); + + QtConcurrent::mapped(list, mapper).waitForFinished(); + + QtConcurrent::blockingMap(list, multiplyBy2Immutable); +#endif +} + + +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_map::stressTest() +{ + const int listSize = 1000; + const int sum = (listSize - 1) * (listSize / 2); + QList<int> list; + + + for (int i = 0; i < listSize; ++i) { + list.append(i); + } + + for (int i =0 ; i < 100; ++i) { + QList<int> 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_map) + +#else + +void tst_map::map() {} +void tst_map::blocking_map() {} +void tst_map::mapped() {} +void tst_map::blocking_mapped() {} +void tst_map::mappedReduced() {} +void tst_map::blocking_mappedReduced() {} +void tst_map::assignResult() {} +void tst_map::functionOverloads() {} +#ifndef QT_NO_EXCEPTIONS +void tst_map::exceptions() {} +#endif +void tst_map::incrementalResults() {} +void tst_map::stressTest() {} +void tst_map::throttling() {} +void tst_map::stlContainers() {} +void tst_map::noDetatch() {} + +QTEST_NOOP_MAIN + +#endif + +#include "tst_qtconcurrentmap.moc" |