From 786b48878f37edafd5eb928ed0f4d046ee1d6bec Mon Sep 17 00:00:00 2001 From: Karsten Heimrich Date: Thu, 26 Mar 2020 15:47:04 +0100 Subject: Improve Map|Map-Reduce and Filter|Filter-Reduce implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * support lambda expressions * remove the need to specify result_type * use std::invoke to apply map|filter function * remove usage of FunctionWrapper* and createFunctionWrapper Task-number: QTBUG-33735 Task-number: QTBUG-82646 Change-Id: Ibcbe4278f0742c29182bd506081db0abb516f85f Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Sona Kurazyan --- .../qtconcurrentfilter/tst_qtconcurrentfilter.cpp | 343 +++++++++++ .../qtconcurrentmap/tst_qtconcurrentmap.cpp | 675 ++++++++++++++++++++- .../qtconcurrentrun/tst_qtconcurrentrun.cpp | 6 - 3 files changed, 1008 insertions(+), 16 deletions(-) (limited to 'tests/auto/concurrent') diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index 1b52f52038..e89e5cf2e3 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -38,12 +38,16 @@ class tst_QtConcurrentFilter : public QObject private slots: void filter(); + void filterLambda(); void filtered(); + void filteredLambda(); void filteredReduced(); + void filteredReduceLambda(); void resultAt(); void incrementalResults(); void noDetach(); void stlContainers(); + void stlContainersLambda(); void filteredReduceInitialValue(); }; @@ -118,6 +122,22 @@ void tst_QtConcurrentFilter::filter() } } +void tst_QtConcurrentFilter::filterLambda() +{ + { + QList list; + list << 1 << 2 << 3 << 4; + QtConcurrent::filter(list, [](const Number &number) { return number.isEven(); }).waitForFinished(); + QCOMPARE(list, QList() << 2 << 4); + } + { + QList list; + list << 1 << 2 << 3 << 4; + QtConcurrent::blockingFilter(list, [](const Number &number) { return number.isEven(); }); + QCOMPARE(list, QList() << 2 << 4); + } +} + void tst_QtConcurrentFilter::filtered() { QList list; @@ -292,6 +312,64 @@ void tst_QtConcurrentFilter::filtered() } } +void tst_QtConcurrentFilter::filteredLambda() +{ + QList list; + list << 1 << 2 << 3 << 4; + + { + QFuture f = QtConcurrent::filtered(list, + [](int x) { + return (x & 1) == 0; + } + ); + QList list2 = f.results(); + QCOMPARE(list2, QList() << 2 << 4); + } + { + QFuture f = QtConcurrent::filtered(list.begin(), list.end(), + [](const int &x) { + return (x & 1) == 0; + } + ); + QList list2 = f.results(); + QCOMPARE(list2, QList() << 2 << 4); + } + { + QFuture f = QtConcurrent::filtered(list.constBegin(), list.constEnd(), + [](const int &x) { + return (x & 1) == 0; + } + ); + QList list2 = f.results(); + QCOMPARE(list2, QList() << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFiltered(list, + [](const int &x) { + return (x & 1) == 0; + } + ); + QCOMPARE(list2, QList() << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFiltered >(list.begin(), list.end(), + [](const int &x) { + return (x & 1) == 0; + } + ); + QCOMPARE(list2, QList() << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFiltered >(list.constBegin(), list.constEnd(), + [](const int &x) { + return (x & 1) == 0; + } + ); + QCOMPARE(list2, QList() << 2 << 4); + } +} + void tst_QtConcurrentFilter::filteredReduced() { QList list; @@ -728,7 +806,221 @@ void tst_QtConcurrentFilter::filteredReduced() numberSumReduce); QCOMPARE(sum, 6); } +} + +void tst_QtConcurrentFilter::filteredReduceLambda() +{ + QList list; + list << 1 << 2 << 3 << 4; + QList numberList; + numberList << 1 << 2 << 3 << 4; + + // lambda-lambda + { + int sum = QtConcurrent::filteredReduced(list, + [](const int &x) { + return (x & 1) == 0; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::blockingFilteredReduced(list, + [](const int &x) { + return (x & 1) == 0; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 6); + } + // lambda-functor + { + int sum = QtConcurrent::filteredReduced(list, + [](const int &x) { + return (x & 1) == 0; + }, + IntSumReduce() + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::blockingFilteredReduced(list, + [](const int &x) { + return (x & 1) == 0; + }, + IntSumReduce() + ); + QCOMPARE(sum2, 6); + } + + // functor-lambda + { + int sum = QtConcurrent::filteredReduced(list, + KeepEvenIntegers(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::blockingFilteredReduced(list, + KeepEvenIntegers(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 6); + } + + // lambda-function + { + int sum = QtConcurrent::filteredReduced(list, + [] (const int &x) { + return (x & 1) == 0; + }, + intSumReduce + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::filteredReduced(list.begin(), list.end(), + [](const int &x) { + return (x & 1) == 0; + }, + intSumReduce + ); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingFilteredReduced(list, + [] (const int &x) { + return (x & 1) == 0; + }, + intSumReduce + ); + QCOMPARE(sum3, 6); + + int sum4 = QtConcurrent::blockingFilteredReduced(list.begin(), list.end(), + [] (const int &x) { + return (x & 1) == 0; + }, + intSumReduce + ); + QCOMPARE(sum4, 6); + } + + // function-lambda + { + int sum = QtConcurrent::filteredReduced(list, + keepEvenIntegers, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::filteredReduced(list.begin(), list.end(), + keepEvenIntegers, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingFilteredReduced(list, + keepEvenIntegers, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 6); + + int sum4 = QtConcurrent::blockingFilteredReduced(list.begin(), list.end(), + keepEvenIntegers, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum4, 6); + } + + // lambda-member + { + auto push_back = static_cast::*)(const int &)>(&QVector::push_back); + + QList list2 = QtConcurrent::filteredReduced(list, + [] (const int &x) { + return (x & 1) == 0; + }, + push_back, + QtConcurrent::OrderedReduce + ); + QCOMPARE(list2, QList() << 2 << 4); + + QList list3 = QtConcurrent::filteredReduced(list.begin(), list.end(), + [] (const int &x) { + return (x & 1) == 0; + }, + push_back, + QtConcurrent::OrderedReduce + ); + QCOMPARE(list3, QList() << 2 << 4); + + QList list4 = QtConcurrent::blockingFilteredReduced(list, + [] (const int &x) { + return (x & 1) == 0; + }, + push_back, + QtConcurrent::OrderedReduce + ); + QCOMPARE(list4, QList() << 2 << 4); + + QList list5 = QtConcurrent::blockingFilteredReduced(list.begin(), list.end(), + [] (const int &x) { + return (x & 1) == 0; + }, + push_back, + QtConcurrent::OrderedReduce + ); + QCOMPARE(list5, QList() << 2 << 4); + } + + // member-lambda + { + int sum = QtConcurrent::filteredReduced(numberList, + &Number::isEven, + [](int &sum, const Number &x) { + sum += x.toInt(); + } + ); + QCOMPARE(sum, 6); + + int sum2 = QtConcurrent::filteredReduced(numberList.begin(), numberList.end(), + &Number::isEven, + [](int &sum, const Number &x) { + sum += x.toInt(); + } + ); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingFilteredReduced(numberList, + &Number::isEven, + [](int &sum, const Number &x) { + sum += x.toInt(); + } + ); + QCOMPARE(sum3, 6); + + int sum4 = QtConcurrent::blockingFilteredReduced(numberList.begin(), numberList.end(), + &Number::isEven, + [](int &sum, const Number &x) { + sum += x.toInt(); + } + ); + QCOMPARE(sum4, 6); + } } bool filterfn(int i) @@ -857,6 +1149,57 @@ void tst_QtConcurrentFilter::stlContainers() QCOMPARE(*list2.begin(), 1); } +void tst_QtConcurrentFilter::stlContainersLambda() +{ + std::vector vector; + vector.push_back(1); + vector.push_back(2); + + std::vector vector2 = QtConcurrent::blockingFiltered(vector, + [](const int &i) { + return waitFilterfn(i); + } + ); + QCOMPARE(vector2.size(), (std::vector::size_type)(1)); + QCOMPARE(vector2[0], 1); + + std::list list; + list.push_back(1); + list.push_back(2); + + std::list list2 = QtConcurrent::blockingFiltered(list, + [](const int &i) { + return waitFilterfn(i); + } + ); + QCOMPARE(list2.size(), (std::list::size_type)(1)); + QCOMPARE(*list2.begin(), 1); + + QtConcurrent::filtered(list, + [](const int &i) { + return waitFilterfn(i); + } + ).waitForFinished(); + QtConcurrent::filtered(vector, + [](const int &i) { + return waitFilterfn(i); + } + ).waitForFinished(); + QtConcurrent::filtered(vector.begin(), vector.end(), + [](const int &i) { + return waitFilterfn(i); + } + ).waitForFinished(); + + QtConcurrent::blockingFilter(list, + [](const int &i) { + return waitFilterfn(i); + } + ); + QCOMPARE(list.size(), (std::list::size_type)(1)); + QCOMPARE(*list.begin(), 1); +} + void tst_QtConcurrentFilter::filteredReduceInitialValue() { // This test's the same as filteredReduce, but with an initial value on all calls diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index 1a8978c7ea..85acc6f729 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -36,7 +36,7 @@ #include "functions.h" -class tst_QtConcurrentMap: public QObject +class tst_QtConcurrentMap : public QObject { Q_OBJECT private slots: @@ -45,7 +45,9 @@ private slots: void mapped(); void blocking_mapped(); void mappedReduced(); + void mappedReducedLambda(); void blocking_mappedReduced(); + void blocking_mappedReducedLambda(); void assignResult(); void functionOverloads(); void noExceptFunctionOverloads(); @@ -55,6 +57,7 @@ private slots: void incrementalResults(); void noDetach(); void stlContainers(); + void stlContainersLambda(); void qFutureAssignmentLeak(); void stressTest(); void persistentResultTest(); @@ -240,6 +243,12 @@ void tst_QtConcurrentMap::blocking_map() QCOMPARE(numberList, QList() << 2 << 4 << 6); QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2); QCOMPARE(numberList, QList() << 4 << 8 << 12); + + // lambda + QtConcurrent::blockingMap(list, [](int &x) { x *= 2; }); + QCOMPARE(list, QList() << 128 << 256 << 384); + QtConcurrent::blockingMap(list.begin(), list.end(), [](int &x) { x *= 2; }); + QCOMPARE(list, QList() << 256 << 512 << 768); } // functors don't take arguments by reference, making these no-ops @@ -264,6 +273,12 @@ void tst_QtConcurrentMap::blocking_map() QCOMPARE(list, QList() << 1 << 2 << 3); QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable); QCOMPARE(list, QList() << 1 << 2 << 3); + + // lambda + QtConcurrent::blockingMap(list, [](int x) { x *= 2; }); + QCOMPARE(list, QList() << 1 << 2 << 3); + QtConcurrent::blockingMap(list.begin(), list.end(), [](int x) { x *= 2; }); + QCOMPARE(list, QList() << 1 << 2 << 3); } #if 0 @@ -317,8 +332,6 @@ int multiplyBy2(int x) class MultiplyBy2 { public: - typedef int result_type; - int operator()(int x) const { int y = x * 2; @@ -334,8 +347,6 @@ double intToDouble(int x) class IntToDouble { public: - typedef double result_type; - double operator()(int x) const { return double(x); @@ -350,8 +361,6 @@ int stringToInt(const QString &string) class StringToInt { public: - typedef int result_type; - int operator()(const QString &string) const { return string.toInt(); @@ -437,6 +446,32 @@ void tst_QtConcurrentMap::mapped() QCOMPARE(numberList4, QList() << 2 << 4 << 6); } + { + QList numberList2 = QtConcurrent::mapped(numberList, + [](const Number &num) { + return num.multipliedBy2(); + } + ).results(); + QCOMPARE(numberList, QList() << 1 << 2 << 3); + QCOMPARE(numberList2, QList() << 2 << 4 << 6); + + QList numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(), + [](const Number &num) { + return num.multipliedBy2(); + } + ).results(); + QCOMPARE(numberList, QList() << 1 << 2 << 3); + QCOMPARE(numberList3, QList() << 2 << 4 << 6); + + QList numberList4 = QtConcurrent::mapped(QList(numberList), + [](const Number &num) { + return num.multipliedBy2(); + } + ).results(); + QCOMPARE(numberList, QList() << 1 << 2 << 3); + QCOMPARE(numberList4, QList() << 2 << 4 << 6); + } + // change the value_type, same container // functor @@ -517,6 +552,33 @@ void tst_QtConcurrentMap::mapped() QCOMPARE(list4, QList() << "1" << "2" << "3"); } + // lambda + { + QList list2 = QtConcurrent::mapped(list, + [](int x) { + return double(x); + } + ).results(); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 1.0 << 2.0 << 3.0); + + QList list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(), + [](int x) { + return double(x); + } + ).results(); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 1.0 << 2.0 << 3.0); + + QList list4 = QtConcurrent::mapped(QList(list), + [](int x) { + return double(x); + } + ).results(); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 1.0 << 2.0 << 3.0); + } + // change the value_type { QList strings = QStringList() << "1" << "2" << "3"; @@ -551,6 +613,22 @@ void tst_QtConcurrentMap::mapped() QCOMPARE(numberList3, QList() << 1 << 2 << 3); } + { + QList numberList2 = QtConcurrent::mapped(numberList, + [] (const Number number) { + return number.toInt(); + } + ).results(); + QCOMPARE(numberList2, QList() << 1 << 2 << 3); + + QList numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(), + [](const Number number) { + return number.toInt(); + } + ).results(); + QCOMPARE(numberList3, QList() << 1 << 2 << 3); + } + // change the value_type from QStringList { QStringList strings = QStringList() << "1" << "2" << "3"; @@ -574,6 +652,22 @@ void tst_QtConcurrentMap::mapped() .results(); QCOMPARE(list2, QList() << 1 << 2 << 3); } + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList list = QtConcurrent::mapped(strings, + [](const QString &string) { + return string.toInt(); + } + ).results(); + QCOMPARE(list, QList() << 1 << 2 << 3); + + QList list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(), + [](const QString &string) { + return string.toInt(); + } + ).results(); + QCOMPARE(list2, QList() << 1 << 2 << 3); + } } void tst_QtConcurrentMap::blocking_mapped() @@ -652,6 +746,33 @@ void tst_QtConcurrentMap::blocking_mapped() QCOMPARE(numberList4, QList() << 2 << 4 << 6); } + // lambda + { + QList list2 = QtConcurrent::blockingMapped(list, + [](int x) { + return x * 2; + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 2 << 4 << 6); + + QList list3 = QtConcurrent::blockingMapped >(list.constBegin(), list.constEnd(), + [](int x) { + return x * 2; + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 2 << 4 << 6); + + QList list4 = QtConcurrent::blockingMapped(QList(list), + [](int x) { + return x * 2; + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 2 << 4 << 6); + } + // change the value_type, same container // functor @@ -727,6 +848,34 @@ void tst_QtConcurrentMap::blocking_mapped() QCOMPARE(list4, QList() << "1" << "2" << "3"); } + // lambda + { + QList list2 = QtConcurrent::blockingMapped >(numberList, + [] (const Number &number) { + return number.toString(); + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << "1" << "2" << "3"); + + QList list3 = QtConcurrent::blockingMapped >(numberList.constBegin(), + numberList.constEnd(), + [](const Number &number) { + return number.toString(); + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << "1" << "2" << "3"); + + QList list4 = QtConcurrent::blockingMapped >(QList(numberList), + [](const Number &number) { + return number.toString(); + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << "1" << "2" << "3"); + } + // change the value_type { QList strings = QStringList() << "1" << "2" << "3"; @@ -759,6 +908,23 @@ void tst_QtConcurrentMap::blocking_mapped() QCOMPARE(numberList3, QList() << 1 << 2 << 3); } + { + QList numberList2 = QtConcurrent::blockingMapped(numberList, + [] (const Number &number) { + return number.toInt(); + } + ); + QCOMPARE(numberList2, QList() << 1 << 2 << 3); + + QList numberList3 = QtConcurrent::blockingMapped >(numberList.constBegin(), + numberList.constEnd(), + [](const Number &number) { + return number.toInt(); + } + ); + QCOMPARE(numberList3, QList() << 1 << 2 << 3); + } + // change the value_type from QStringList { QStringList strings = QStringList() << "1" << "2" << "3"; @@ -780,6 +946,23 @@ void tst_QtConcurrentMap::blocking_mapped() stringToInt); QCOMPARE(list2, QList() << 1 << 2 << 3); } + { + QStringList strings = QStringList() << "1" << "2" << "3"; + QList list = QtConcurrent::blockingMapped(strings, + [](const QString &string) { + return string.toInt(); + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + + QList list2 = QtConcurrent::blockingMapped >(strings.constBegin(), + strings.constEnd(), + [](const QString &string) { + return string.toInt(); + } + ); + QCOMPARE(list2, QList() << 1 << 2 << 3); + } // functor { @@ -882,6 +1065,40 @@ void tst_QtConcurrentMap::blocking_mapped() QCOMPARE(list5, QVector() << 1 << 2 << 3); #endif } + + // lambda + { + QVector list2 = QtConcurrent::blockingMapped >(list, + [](int x) { + return double(x); + } + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QVector() << 1.0 << 2.0 << 3.0); + + QVector list3 = QtConcurrent::blockingMapped >(QList(list), + [](int x) { + return double(x); + } + ); + 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, + [](const QString &string) { + return string.toInt(); + } + ); + QCOMPARE(list4, QVector() << 1 << 2 << 3); + + QVector list5 = QtConcurrent::blockingMapped >(QStringList(strings), + [](const QString &string) { + return string.toInt(); + } + ); + QCOMPARE(list5, QVector() << 1 << 2 << 3); + } } int intSquare(int x) @@ -892,8 +1109,6 @@ int intSquare(int x) class IntSquare { public: - typedef int result_type; - int operator()(int x) { return x * x; @@ -1088,6 +1303,211 @@ void tst_QtConcurrentMap::mappedReduced() } } +void tst_QtConcurrentMap::mappedReducedLambda() +{ + QList list; + list << 1 << 2 << 3; + QList numberList; + numberList << 1 << 2 << 3; + + // lambda-lambda + { + int sum = QtConcurrent::mappedReduced(list, + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced(QList(list), + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-functor + { + int sum = QtConcurrent::mappedReduced(list, + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced(QList(list), + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum3, 14); + } + + // functor-lambda + { + int sum = QtConcurrent::mappedReduced(list, + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced(QList(list), + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-function + { + int sum = QtConcurrent::mappedReduced(list, + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced(QList(list), + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum3, 14); + } + + // function-lambda + { + int sum = QtConcurrent::mappedReduced(list, + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::mappedReduced(QList(list), + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-member + { + auto push_back = static_cast::*)(const int &)>(&QVector::push_back); + + QList list2 = QtConcurrent::mappedReduced(list, + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 1 << 4 << 9); + + QList list3 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 1 << 4 << 9); + + QList list4 = QtConcurrent::mappedReduced(QList(list), + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 1 << 4 << 9); + } + + // member-lambda + { + int sum = QtConcurrent::mappedReduced(numberList, + &Number::toInt, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::mappedReduced(numberList.constBegin(), numberList.constEnd(), + &Number::toInt, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::mappedReduced(QList(numberList), + &Number::toInt, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 6); + } +} + void tst_QtConcurrentMap::blocking_mappedReduced() { QList list; @@ -1273,6 +1693,213 @@ void tst_QtConcurrentMap::blocking_mappedReduced() } } +void tst_QtConcurrentMap::blocking_mappedReducedLambda() +{ + QList list; + list << 1 << 2 << 3; + QList numberList; + numberList << 1 << 2 << 3; + + // lambda-lambda + { + int sum = QtConcurrent::blockingMappedReduced(list, + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(list), + [](int x) { + return x * x; + }, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-functor + { + int sum = QtConcurrent::blockingMappedReduced(list, + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(list), + [](int x) { + return x * x; + }, + IntSumReduce() + ); + QCOMPARE(sum3, 14); + } + + // functor-lambda + { + int sum = QtConcurrent::blockingMappedReduced(list, + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(list), + IntSquare(), + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-function + { + int sum = QtConcurrent::blockingMappedReduced(list, + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(list), + [](int x) { + return x * x; + }, + intSumReduce + ); + QCOMPARE(sum3, 14); + } + + // function-lambda + { + int sum = QtConcurrent::blockingMappedReduced(list, + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum, 14); + int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 14); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(list), + intSquare, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 14); + } + + // lambda-member + { + auto push_back = static_cast::*)(const int &)>(&QVector::push_back); + + QList list2 = QtConcurrent::blockingMappedReduced(list, + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 1 << 4 << 9); + + QList list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(), + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 1 << 4 << 9); + + QList list4 = QtConcurrent::blockingMappedReduced(QList(list), + [](int x) { + return x * x; + }, + push_back, + OrderedReduce + ); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 1 << 4 << 9); + } + + // member-lambda + { + std::function sumRecuce = [](int &sum, int x) { + sum += x; + }; + + int sum = QtConcurrent::blockingMappedReduced(numberList, + &Number::toInt, + sumRecuce + ); + QCOMPARE(sum, 6); + int sum2 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), numberList.constEnd(), + &Number::toInt, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum2, 6); + + int sum3 = QtConcurrent::blockingMappedReduced(QList(numberList), + &Number::toInt, + [](int &sum, int x) { + sum += x; + } + ); + QCOMPARE(sum3, 6); + } +} + int sleeper(int val) { QTest::qSleep(100); @@ -1646,6 +2273,35 @@ void tst_QtConcurrentMap::stlContainers() QtConcurrent::blockingMap(list, multiplyBy2Immutable); } +void tst_QtConcurrentMap::stlContainersLambda() +{ + std::vector vector; + vector.push_back(1); + vector.push_back(2); + + std::vector vector2 = QtConcurrent::blockingMapped >(vector, + [](const int &i) { + return mapper(i); + } + ); + 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, + [](const int &i) { + return mapper(i); + } + ); + QCOMPARE(list2.size(), (std::vector::size_type)(2)); + + QtConcurrent::mapped(list, [](const int &i) { return mapper(i); }).waitForFinished(); + + QtConcurrent::blockingMap(list, [](int x) { x *= 2; }); +} + InstanceCounter ic_fn(const InstanceCounter & ic) { return InstanceCounter(ic); @@ -1730,7 +2386,6 @@ struct LockedCounter : mtx(mutex), ref(ai) {} - typedef int result_type; int operator()(int x) { QMutexLocker locker(mtx); diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index c0782d8483..8f50329ec5 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -104,7 +104,6 @@ public: int member0() { return 10; } int member1(int in) { return in; } - typedef int result_type; int operator()() { return 10; } int operator()(int in) { return in; } }; @@ -115,7 +114,6 @@ public: int member0() const { return 10; } int member1(int in) const { return in; } - typedef int result_type; int operator()() const { return 10; } int operator()(int in) const { return in; } }; @@ -126,7 +124,6 @@ public: int member0() noexcept { return 10; } int member1(int in) noexcept { return in; } - typedef int result_type; int operator()() noexcept { return 10; } int operator()(int in) noexcept { return in; } }; @@ -137,7 +134,6 @@ public: int member0() const noexcept { return 10; } int member1(int in) const noexcept { return in; } - typedef int result_type; int operator()() const noexcept { return 10; } int operator()(int in) const noexcept { return in; } }; @@ -320,7 +316,6 @@ void tst_QtConcurrentRun::returnValue() struct TestClass { void foo() { } - typedef void result_type; void operator()() { } void operator()(int) { } void fooInt(int){ }; @@ -329,7 +324,6 @@ struct TestClass struct TestConstClass { void foo() const { } - typedef void result_type; void operator()() const { } void operator()(int) const { } void fooInt(int) const { }; -- cgit v1.2.3