From 4d9658b7cd2b072dd8b24d9bb6844b7cbcf22ad0 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 9 Oct 2020 18:21:17 +0200 Subject: Use universal references for passing callables in QtConcurrent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-87596 Change-Id: I219f08d73b97317820ec6e329ab1e6c89c0545f1 Reviewed-by: Jarek Kobus Reviewed-by: Andrei Golubev Reviewed-by: MÃ¥rten Nordheim --- .../qtconcurrentfilter/tst_qtconcurrentfilter.cpp | 191 ++++++++++++++++++++ .../qtconcurrentmap/tst_qtconcurrentmap.cpp | 194 +++++++++++++++++++++ tests/auto/concurrent/testhelper_functions.h | 26 +++ 3 files changed, 411 insertions(+) (limited to 'tests/auto') diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index 8cce82defd..242f95fd92 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -39,13 +39,17 @@ class tst_QtConcurrentFilter : public QObject private slots: void filter(); void filterThreadPool(); + void filterWithMoveOnlyCallable(); void filtered(); void filteredThreadPool(); + void filteredWithMoveOnlyCallable(); void filteredReduced(); void filteredReducedThreadPool(); + void filteredReducedWithMoveOnlyCallables(); void filteredReducedDifferentType(); void filteredReducedInitialValue(); void filteredReducedInitialValueThreadPool(); + void filteredReducedInitialValueWithMoveOnlyCallables(); void filteredReducedDifferentTypeInitialValue(); void resultAt(); void incrementalResults(); @@ -177,6 +181,34 @@ void tst_QtConcurrentFilter::filterThreadPool() CHECK_FAIL("lambda"); } +void tst_QtConcurrentFilter::filterWithMoveOnlyCallable() +{ + const QList intListEven { 2, 4 }; + { + QList intList { 1, 2, 3, 4 }; + QtConcurrent::filter(intList, KeepEvenIntegersMoveOnly()).waitForFinished(); + QCOMPARE(intList, intListEven); + } + + { + QList intList { 1, 2, 3, 4 }; + QtConcurrent::blockingFilter(intList, KeepEvenIntegersMoveOnly()); + QCOMPARE(intList, intListEven); + } + + QThreadPool pool; + { + QList intList { 1, 2, 3, 4 }; + QtConcurrent::filter(&pool, intList, KeepEvenIntegersMoveOnly()).waitForFinished(); + QCOMPARE(intList, intListEven); + } + { + QList intList { 1, 2, 3, 4 }; + QtConcurrent::blockingFilter(&pool, intList, KeepEvenIntegersMoveOnly()); + QCOMPARE(intList, intListEven); + } +} + template @@ -323,6 +355,52 @@ void tst_QtConcurrentFilter::filteredThreadPool() } } +void tst_QtConcurrentFilter::filteredWithMoveOnlyCallable() +{ + const QList intList { 1, 2, 3, 4 }; + const QList intListEven { 2, 4 }; + { + const auto result = QtConcurrent::filtered(intList, KeepEvenIntegersMoveOnly()).results(); + QCOMPARE(result, intListEven); + } + { + const auto result = QtConcurrent::filtered( + intList.begin(), intList.end(), KeepEvenIntegersMoveOnly()).results(); + QCOMPARE(result, intListEven); + } + { + const auto result = QtConcurrent::blockingFiltered(intList, KeepEvenIntegersMoveOnly()); + QCOMPARE(result, intListEven); + } + { + const auto result = QtConcurrent::blockingFiltered>( + intList.begin(), intList.end(), KeepEvenIntegersMoveOnly()); + QCOMPARE(result, intListEven); + } + + QThreadPool pool; + { + const auto result = + QtConcurrent::filtered(&pool, intList, KeepEvenIntegersMoveOnly()).results(); + QCOMPARE(result, intListEven); + } + { + const auto result = QtConcurrent::filtered(&pool, intList.begin(), intList.end(), + KeepEvenIntegersMoveOnly()).results(); + QCOMPARE(result, intListEven); + } + { + const auto result = + QtConcurrent::blockingFiltered(&pool, intList, KeepEvenIntegersMoveOnly()); + QCOMPARE(result, intListEven); + } + { + const auto result = QtConcurrent::blockingFiltered>( + &pool, intList.begin(), intList.end(), KeepEvenIntegersMoveOnly()); + QCOMPARE(result, intListEven); + } +} + template intList { 1, 2, 3, 4 }; + const QList intListEven { 2, 4 }; + const auto sum = 6; + { + const auto result = + QtConcurrent::filteredReduced(intList, KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::filteredReduced(intList.begin(), intList.end(), + KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + intList, KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + intList.begin(), intList.end(), KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + + QThreadPool pool; + { + const auto result = + QtConcurrent::filteredReduced(&pool, intList, KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::filteredReduced( + &pool, intList.begin(), intList.end(), + KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + &pool, intList, KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + &pool, intList.begin(), intList.end(), KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } +} + void tst_QtConcurrentFilter::filteredReducedDifferentType() { const QList numberList {1, 2, 3, 4}; @@ -911,6 +1044,64 @@ void tst_QtConcurrentFilter::filteredReducedInitialValueThreadPool() } } +void tst_QtConcurrentFilter::filteredReducedInitialValueWithMoveOnlyCallables() +{ + const QList intList { 1, 2, 3, 4 }; + const QList intListEven { 2, 4 }; + const auto initial = 10; + const auto sum = 16; + { + const auto result = + QtConcurrent::filteredReduced(intList, KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly(), initial).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::filteredReduced(intList.begin(), intList.end(), + KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly(), initial).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + intList, KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly(), initial); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + intList.begin(), intList.end(), KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly(), + initial); + QCOMPARE(result, sum); + } + + QThreadPool pool; + { + const auto result = + QtConcurrent::filteredReduced(&pool, intList, KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly(), initial).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::filteredReduced( + &pool, intList.begin(), intList.end(), + KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly(), initial).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + &pool, intList, KeepEvenIntegersMoveOnly(), IntSumReduceMoveOnly(), initial); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingFilteredReduced( + &pool, intList.begin(), intList.end(), KeepEvenIntegersMoveOnly(), + IntSumReduceMoveOnly(), initial); + QCOMPARE(result, sum); + } +} + void tst_QtConcurrentFilter::filteredReducedDifferentTypeInitialValue() { const QList numberList {1, 2, 3, 4}; diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index e3b61bb109..d1ea999e37 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -45,11 +45,14 @@ private slots: void mapOnRvalue(); void mapped(); void mappedThreadPool(); + void mappedWithMoveOnlyCallable(); void mappedReduced(); void mappedReducedThreadPool(); + void mappedReducedWithMoveOnlyCallable(); void mappedReducedDifferentType(); void mappedReducedInitialValue(); void mappedReducedInitialValueThreadPool(); + void mappedReducedInitialValueWithMoveOnlyCallable(); void mappedReducedDifferentTypeInitialValue(); void assignResult(); void functionOverloads(); @@ -98,6 +101,19 @@ public: } }; +class MultiplyBy2InPlaceMoveOnly +{ +public: + MultiplyBy2InPlaceMoveOnly() = default; + MultiplyBy2InPlaceMoveOnly(MultiplyBy2InPlaceMoveOnly &&) = default; + MultiplyBy2InPlaceMoveOnly &operator=(MultiplyBy2InPlaceMoveOnly &&other) = default; + + MultiplyBy2InPlaceMoveOnly(const MultiplyBy2InPlaceMoveOnly &) = delete; + MultiplyBy2InPlaceMoveOnly &operator=(const MultiplyBy2InPlaceMoveOnly &) = delete; + + void operator()(int &x) { x *= 2; } +}; + Q_DECLARE_METATYPE(QList); void tst_QtConcurrentMap::map() @@ -138,6 +154,12 @@ void tst_QtConcurrentMap::map() QCOMPARE(list, QList() << 128 << 256 << 384); QtConcurrent::map(list.begin(), list.end(), [](int &x){x *= 2;}).waitForFinished(); QCOMPARE(list, QList() << 256 << 512 << 768); + + // move-only functor + QtConcurrent::map(list, MultiplyBy2InPlaceMoveOnly()).waitForFinished(); + QCOMPARE(list, QList() << 512 << 1024 << 1536); + QtConcurrent::map(list.begin(), list.end(), MultiplyBy2InPlaceMoveOnly()).waitForFinished(); + QCOMPARE(list, QList() << 1024 << 2048 << 3072); } // functors don't take arguments by reference, making these no-ops @@ -259,6 +281,12 @@ void tst_QtConcurrentMap::blockingMap() QCOMPARE(list, QList() << 128 << 256 << 384); QtConcurrent::blockingMap(list.begin(), list.end(), [](int &x) { x *= 2; }); QCOMPARE(list, QList() << 256 << 512 << 768); + + // move-only functor + QtConcurrent::blockingMap(list, MultiplyBy2InPlaceMoveOnly()); + QCOMPARE(list, QList() << 512 << 1024 << 1536); + QtConcurrent::blockingMap(list.begin(), list.end(), MultiplyBy2InPlaceMoveOnly()); + QCOMPARE(list, QList() << 1024 << 2048 << 3072); } // functors take arguments by reference, modifying the move-only sequence in place @@ -409,6 +437,23 @@ public: } }; +class MultiplyBy2MoveOnly +{ +public: + MultiplyBy2MoveOnly() = default; + MultiplyBy2MoveOnly(MultiplyBy2MoveOnly &&) = default; + MultiplyBy2MoveOnly &operator=(MultiplyBy2MoveOnly &&other) = default; + + MultiplyBy2MoveOnly(const MultiplyBy2MoveOnly &) = delete; + MultiplyBy2MoveOnly &operator=(const MultiplyBy2MoveOnly &) = delete; + + int operator()(int x) const + { + int y = x * 2; + return y; + } +}; + double intToDouble(int x) { return double(x); @@ -642,6 +687,50 @@ void tst_QtConcurrentMap::mappedThreadPool() } } +void tst_QtConcurrentMap::mappedWithMoveOnlyCallable() +{ + const QList intList { 1, 2, 3 }; + const QList intListMultipiedBy2 { 2, 4, 6 }; + { + const auto result = QtConcurrent::mapped(intList, MultiplyBy2()).results(); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = + QtConcurrent::mapped(intList.begin(), intList.end(), MultiplyBy2()).results(); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = QtConcurrent::blockingMapped(intList, MultiplyBy2()); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = QtConcurrent::blockingMapped>(intList.begin(), intList.end(), + MultiplyBy2()); + QCOMPARE(result, intListMultipiedBy2); + } + + QThreadPool pool; + { + const auto result = QtConcurrent::mapped(&pool, intList, MultiplyBy2()).results(); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = QtConcurrent::mapped( + &pool, intList.begin(), intList.end(), MultiplyBy2()).results(); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = QtConcurrent::blockingMapped(&pool, intList, MultiplyBy2()); + QCOMPARE(result, intListMultipiedBy2); + } + { + const auto result = QtConcurrent::blockingMapped>(&pool, intList.begin(), + intList.end(), MultiplyBy2()); + QCOMPARE(result, intListMultipiedBy2); + } +} + int intSquare(int x) { return x * x; @@ -901,6 +990,56 @@ void tst_QtConcurrentMap::mappedReducedThreadPool() } } +void tst_QtConcurrentMap::mappedReducedWithMoveOnlyCallable() +{ + const QList intList { 1, 2, 3 }; + const auto sum = 12; + { + const auto result = QtConcurrent::mappedReduced( + intList, MultiplyBy2(), IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::mappedReduced(intList.begin(), intList.end(), + MultiplyBy2(), IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced(intList, MultiplyBy2(), + IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + intList.begin(), intList.end(), MultiplyBy2(), IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + + QThreadPool pool; + { + const auto result = QtConcurrent::mappedReduced(&pool, intList, MultiplyBy2(), + IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::mappedReduced(&pool, intList.begin(), intList.end(), + MultiplyBy2(), IntSumReduceMoveOnly()).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced(&pool, intList, MultiplyBy2(), + IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + &pool, intList.begin(), intList.end(), MultiplyBy2(), IntSumReduceMoveOnly()); + QCOMPARE(result, sum); + } +} + void tst_QtConcurrentMap::mappedReducedDifferentType() { const QList intList {1, 2, 3}; @@ -1196,6 +1335,61 @@ void tst_QtConcurrentMap::mappedReducedInitialValueThreadPool() } } +void tst_QtConcurrentMap::mappedReducedInitialValueWithMoveOnlyCallable() +{ + const QList intList { 1, 2, 3 }; + const auto initialValue = 10; + const auto sum = 22; + { + const auto result = + QtConcurrent::mappedReduced(intList, MultiplyBy2(), + IntSumReduceMoveOnly(), initialValue).result(); + QCOMPARE(result, sum); + } + { + const auto result = + QtConcurrent::mappedReduced(intList.begin(), intList.end(), MultiplyBy2(), + IntSumReduceMoveOnly(), initialValue).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + intList, MultiplyBy2(), IntSumReduceMoveOnly(), initialValue); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + intList.begin(), intList.end(), MultiplyBy2(), IntSumReduceMoveOnly(), + initialValue); + QCOMPARE(result, sum); + } + + QThreadPool pool; + { + const auto result = + QtConcurrent::mappedReduced(&pool, intList, MultiplyBy2(), + IntSumReduceMoveOnly(), initialValue).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::mappedReduced(&pool, intList.begin(), intList.end(), + MultiplyBy2(), IntSumReduceMoveOnly(), + initialValue).result(); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + &pool, intList, MultiplyBy2(), IntSumReduceMoveOnly(), initialValue); + QCOMPARE(result, sum); + } + { + const auto result = QtConcurrent::blockingMappedReduced( + &pool, intList.begin(), intList.end(), MultiplyBy2(), IntSumReduceMoveOnly(), + initialValue); + QCOMPARE(result, sum); + } +} + void tst_QtConcurrentMap::mappedReducedDifferentTypeInitialValue() { // This is a copy of tst_QtConcurrentMap::mappedReducedDifferentType diff --git a/tests/auto/concurrent/testhelper_functions.h b/tests/auto/concurrent/testhelper_functions.h index aeba794977..17836cba51 100644 --- a/tests/auto/concurrent/testhelper_functions.h +++ b/tests/auto/concurrent/testhelper_functions.h @@ -44,6 +44,19 @@ public: } }; +class KeepEvenIntegersMoveOnly +{ +public: + KeepEvenIntegersMoveOnly() = default; + KeepEvenIntegersMoveOnly(KeepEvenIntegersMoveOnly &&) = default; + KeepEvenIntegersMoveOnly &operator=(KeepEvenIntegersMoveOnly &&other) = default; + + KeepEvenIntegersMoveOnly(const KeepEvenIntegersMoveOnly &) = delete; + KeepEvenIntegersMoveOnly &operator=(const KeepEvenIntegersMoveOnly &) = delete; + + bool operator()(int x) { return (x & 1) == 0; } +}; + class Number { int n; @@ -121,6 +134,19 @@ public: } }; +class IntSumReduceMoveOnly +{ +public: + IntSumReduceMoveOnly() = default; + IntSumReduceMoveOnly(IntSumReduceMoveOnly &&) = default; + IntSumReduceMoveOnly &operator=(IntSumReduceMoveOnly &&other) = default; + + IntSumReduceMoveOnly(const IntSumReduceMoveOnly &) = delete; + IntSumReduceMoveOnly &operator=(const IntSumReduceMoveOnly &) = delete; + + void operator()(int &sum, int x) { sum += x; } +}; + void numberSumReduce(int &sum, const Number &x) { sum += x.toInt(); -- cgit v1.2.3