diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h index 86e9a531d29..e35c445b947 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -73,7 +73,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -95,7 +96,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -144,7 +146,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep, @@ -163,7 +166,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(Sequence &&sequence, KeepFunctor &&keep, ReduceFunctor &&reduce, @@ -211,7 +215,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(QThreadPool *pool, Iterator begin, @@ -233,7 +238,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(Iterator begin, Iterator end, @@ -281,7 +287,8 @@ QFuture filteredReduced(Iterator begin, template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -300,7 +307,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, @@ -400,7 +408,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -423,7 +432,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -475,7 +485,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep, @@ -495,7 +506,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&keep, ReduceFunctor &&reduce, @@ -547,7 +559,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, @@ -570,7 +583,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(Iterator begin, Iterator end, @@ -621,7 +635,8 @@ ResultType blockingFilteredReduced(Iterator begin, template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep, @@ -640,7 +655,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h index b337b90e0a3..4882ed8d89c 100644 --- a/src/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/concurrent/qtconcurrentfunctionwrappers.h @@ -5,6 +5,7 @@ #define QTCONCURRENT_FUNCTIONWRAPPERS_H #include +#include #include #include @@ -121,6 +122,11 @@ inline constexpr bool isIterator_v using isInvocable = std::is_invocable::value_type>; +template +inline constexpr bool isInitialValueCompatible_v = std::conjunction_v< + std::is_convertible, + std::negation, QtConcurrent::ReduceOption>>>; + template struct ReduceResultTypeHelper { @@ -163,14 +169,6 @@ struct MapSequenceResultType, MapFunctor> #endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER -template -struct SequenceHolder -{ - SequenceHolder(const Sequence &s) : sequence(s) { } - SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } - Sequence sequence; -}; - } // namespace QtPrivate. diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index 3358d93a4e7..2d829daca4e 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -77,7 +77,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -98,7 +99,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -149,7 +151,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -172,7 +175,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -221,7 +225,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Iterator begin, @@ -243,7 +248,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Iterator begin, Iterator end, @@ -295,7 +301,8 @@ template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Iterator begin, @@ -319,7 +326,8 @@ template, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Iterator begin, Iterator end, @@ -447,7 +455,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -470,7 +479,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -526,7 +536,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -550,7 +561,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -602,7 +614,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -626,7 +639,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, @@ -681,7 +695,8 @@ template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -706,7 +721,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index 9ea0f33f916..a58739fc410 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -5,7 +5,6 @@ #define QTCONCURRENT_REDUCEKERNEL_H #include -#include #if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) @@ -20,6 +19,17 @@ QT_BEGIN_NAMESPACE +namespace QtPrivate { + +template +struct SequenceHolder +{ + SequenceHolder(const Sequence &s) : sequence(s) { } + SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } + Sequence sequence; +}; + +} namespace QtConcurrent { diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index 85eb8c8259c..50819a37424 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -27,6 +27,7 @@ private slots: void filteredReducedInitialValueThreadPool(); void filteredReducedInitialValueWithMoveOnlyCallables(); void filteredReducedDifferentTypeInitialValue(); + void filteredReduceOptionConvertableToResultType(); void resultAt(); void incrementalResults(); void noDetach(); @@ -1338,6 +1339,56 @@ void tst_QtConcurrentFilter::filteredReducedDifferentTypeInitialValue() CHECK_FAIL("lambda-lambda"); } +void tst_QtConcurrentFilter::filteredReduceOptionConvertableToResultType() +{ + const QList intList { 1, 2, 3 }; + const int sum = 4; + QThreadPool p; + ReduceOption ro = OrderedReduce; + + // With container + QCOMPARE(QtConcurrent::filteredReduced(intList, keepOddIntegers, intSumReduce, ro).result(), + sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(intList, keepOddIntegers, intSumReduce, ro), + sum); + + // With iterators + QCOMPARE(QtConcurrent::filteredReduced(intList.begin(), intList.end(), keepOddIntegers, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(intList.begin(), intList.end(), keepOddIntegers, + intSumReduce, ro), sum); + + // With custom QThreadPool; + QCOMPARE(QtConcurrent::filteredReduced(&p, intList, keepOddIntegers, intSumReduce, ro).result(), + sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList, keepOddIntegers, intSumReduce, ro), + sum); + QCOMPARE(QtConcurrent::filteredReduced(&p, intList.begin(), intList.end(), keepOddIntegers, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList.begin(), intList.end(), + keepOddIntegers, intSumReduce, ro), sum); + + // The same as above, but specify the result type explicitly (this invokes different overloads) + QCOMPARE(QtConcurrent::filteredReduced(intList, keepOddIntegers, intSumReduce, + ro).result(), sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(intList, keepOddIntegers, intSumReduce, ro), + sum); + + QCOMPARE(QtConcurrent::filteredReduced(intList.begin(), intList.end(), keepOddIntegers, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(intList.begin(), intList.end(), + keepOddIntegers, intSumReduce, ro), sum); + + QCOMPARE(QtConcurrent::filteredReduced(&p, intList, keepOddIntegers, intSumReduce, + ro).result(), sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList, keepOddIntegers, intSumReduce, + ro), sum); + QCOMPARE(QtConcurrent::filteredReduced(&p, intList.begin(), intList.end(), keepOddIntegers, + intSumReduce, ro).result(),sum); + QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList.begin(), intList.end(), + keepOddIntegers, intSumReduce, ro), sum); +} + bool filterfn(int i) { return (i % 2); diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index cdf046a524f..a6c73777a18 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -30,6 +30,7 @@ private slots: void mappedReducedInitialValueThreadPool(); void mappedReducedInitialValueWithMoveOnlyCallable(); void mappedReducedDifferentTypeInitialValue(); + void mappedReduceOptionConvertableToResultType(); void assignResult(); void functionOverloads(); void noExceptFunctionOverloads(); @@ -1605,6 +1606,51 @@ void tst_QtConcurrentMap::mappedReducedDifferentTypeInitialValue() CHECK_FAIL("lambda-lambda"); } +void tst_QtConcurrentMap::mappedReduceOptionConvertableToResultType() +{ + const QList intList { 1, 2, 3 }; + const int sum = 12; + QThreadPool p; + ReduceOption ro = OrderedReduce; + + // With container + QCOMPARE(QtConcurrent::mappedReduced(intList, multiplyBy2, intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(intList, multiplyBy2, intSumReduce, ro), sum); + + // With iterators + QCOMPARE(QtConcurrent::mappedReduced(intList.begin(), intList.end(), multiplyBy2, intSumReduce, + ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro), sum); + + // With custom QThreadPool; + QCOMPARE(QtConcurrent::mappedReduced(&p, intList, multiplyBy2, intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList, multiplyBy2, intSumReduce, ro), sum); + QCOMPARE(QtConcurrent::mappedReduced(&p, intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro), sum); + + // The same as above, but specify the result type explicitly (this invokes different overloads) + QCOMPARE(QtConcurrent::mappedReduced(intList, multiplyBy2, intSumReduce, ro).result(), + sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(intList, multiplyBy2, intSumReduce, ro), sum); + + QCOMPARE(QtConcurrent::mappedReduced(intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro), sum); + + QCOMPARE(QtConcurrent::mappedReduced(&p, intList, multiplyBy2, intSumReduce, ro).result(), + sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList, multiplyBy2, intSumReduce, ro), + sum); + QCOMPARE(QtConcurrent::mappedReduced(&p, intList.begin(), intList.end(), multiplyBy2, + intSumReduce, ro).result(), sum); + QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList.begin(), intList.end(), + multiplyBy2, intSumReduce, ro), sum); +} + int sleeper(int val) { QTest::qSleep(100);