From 0547598a28c3c1dd5c5f4c3ec9888b0de499199b Mon Sep 17 00:00:00 2001 From: Holger Ihrig Date: Wed, 24 Aug 2011 10:51:34 +0200 Subject: Moving relevant tests to corelib/concurrent Adding tests for QFutureSynchronizer and QtConcurrentResultStore Added minor things in QFutureSynchronizer and QtConcurrentResultStore and removed tests for destruction Task-number: QTBUG-21066 Change-Id: I9f088b89463340f339c914bcb37fb2f9d3b62057 Reviewed-on: http://codereview.qt.nokia.com/3477 Reviewed-by: Qt Sanity Bot Reviewed-by: Rohan McGovern Reviewed-by: Jason McDonald --- .../corelib/concurrent/qtconcurrentmap/.gitignore | 1 + .../corelib/concurrent/qtconcurrentmap/functions.h | 130 ++ .../concurrent/qtconcurrentmap/qtconcurrentmap.pro | 6 + .../qtconcurrentmap/tst_qtconcurrentmap.cpp | 2448 ++++++++++++++++++++ 4 files changed, 2585 insertions(+) create mode 100644 tests/auto/corelib/concurrent/qtconcurrentmap/.gitignore create mode 100644 tests/auto/corelib/concurrent/qtconcurrentmap/functions.h create mode 100644 tests/auto/corelib/concurrent/qtconcurrentmap/qtconcurrentmap.pro create mode 100644 tests/auto/corelib/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp (limited to 'tests/auto/corelib/concurrent/qtconcurrentmap') diff --git a/tests/auto/corelib/concurrent/qtconcurrentmap/.gitignore b/tests/auto/corelib/concurrent/qtconcurrentmap/.gitignore new file mode 100644 index 0000000000..f1c563e979 --- /dev/null +++ b/tests/auto/corelib/concurrent/qtconcurrentmap/.gitignore @@ -0,0 +1 @@ +tst_qtconcurrentmap diff --git a/tests/auto/corelib/concurrent/qtconcurrentmap/functions.h b/tests/auto/corelib/concurrent/qtconcurrentmap/functions.h new file mode 100644 index 0000000000..a3dcd3c300 --- /dev/null +++ b/tests/auto/corelib/concurrent/qtconcurrentmap/functions.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +#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/corelib/concurrent/qtconcurrentmap/qtconcurrentmap.pro b/tests/auto/corelib/concurrent/qtconcurrentmap/qtconcurrentmap.pro new file mode 100644 index 0000000000..6fc358514e --- /dev/null +++ b/tests/auto/corelib/concurrent/qtconcurrentmap/qtconcurrentmap.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +DEFINES += QT_STRICT_ITERATORS +SOURCES += tst_qtconcurrentmap.cpp +QT = core +CONFIG += parallel_test +CONFIG += parallel_test diff --git a/tests/auto/corelib/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/corelib/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp new file mode 100644 index 0000000000..74a254cbf4 --- /dev/null +++ b/tests/auto/corelib/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -0,0 +1,2448 @@ +/**************************************************************************** +** +** 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); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList() << 128 << 256 << 384); + QtConcurrent::map(list.begin(), list.end(), [](int &x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList() << 256 << 512 << 768); +#endif + + } + + // 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); + +#ifdef Q_COMPILER_LAMBDA + // lambda + QtConcurrent::map(list, [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList() << 1 << 2 << 3); + QtConcurrent::map(list.begin(), list.end(), [](int x){x *= 2;}).waitForFinished(); + QCOMPARE(list, QList() << 1 << 2 << 3); +#endif + } + + // 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); +#elif defined(Q_COMPILER_RVALUE_REFS) + //mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it + // meaning it is not possible to take the address of that function anymore. + QSKIP("mapped do not work with c++0x stl vector", 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" -- cgit v1.2.3