summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Kurazyan <[email protected]>2021-09-06 14:37:32 +0200
committerSona Kurazyan <[email protected]>2021-09-08 15:05:32 +0200
commit28e194d3b25f5fc6e17cce8dddba7f7e16002c43 (patch)
treed8291664b59379053806c5df00ed408c95e47421
parent2b0e55a3e2a4631bce12da633f8a9ce889a58878 (diff)
Fix QtConcurrent::blockingMapped to work with non-template sequences
The code for deducing the type of output sequence was assuming that the input sequence is always a template class and was trying to use the corresponding container type for the output sequence. Fixed the deduction code, to assume that the output sequence has the same type as the input sequence, when it's not a template class. Also added tests to verify that all QtConcurrent functions support non-template input sequences. Fixes: QTBUG-30617 Pick-to: 6.2 6.1 Change-Id: I486fe99f3207cfff5dcceb3712cc7de863067edb Reviewed-by: MÃ¥rten Nordheim <[email protected]>
-rw-r--r--src/concurrent/qtconcurrentfunctionwrappers.h8
-rw-r--r--tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp103
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp83
-rw-r--r--tests/auto/concurrent/testhelper_functions.h9
4 files changed, 202 insertions, 1 deletions
diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h
index be4a09f107d..1c882d3f194 100644
--- a/src/concurrent/qtconcurrentfunctionwrappers.h
+++ b/src/concurrent/qtconcurrentfunctionwrappers.h
@@ -190,7 +190,13 @@ struct ReduceResultTypeHelper<Callable,
// -- MapSequenceResultType
template <class InputSequence, class MapFunctor>
-struct MapSequenceResultType;
+struct MapSequenceResultType
+{
+ static_assert(std::is_same_v<typename InputSequence::value_type,
+ QtPrivate::MapResultType<InputSequence, MapFunctor>>,
+ "Couldn't deduce the output sequence type, you must specify it explicitly.");
+ typedef InputSequence ResultType;
+};
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
index 1a1ad6251aa..f9e68bd5f6e 100644
--- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
+++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
@@ -102,6 +102,19 @@ void tst_QtConcurrentFilter::filter()
CHECK_FAIL("member");
testFilter(intList, intListEven, lambdaIsEven);
CHECK_FAIL("lambda");
+
+ // non-template sequences
+ {
+
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ QtConcurrent::filter(list, keepEvenNumbers).waitForFinished();
+ QCOMPARE(list, NonTemplateSequence({ 2, 4 }));
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ QtConcurrent::blockingFilter(list, keepEvenNumbers);
+ QCOMPARE(list, NonTemplateSequence({ 2, 4 }));
+ }
}
static QSemaphore semaphore(1);
@@ -179,6 +192,19 @@ void tst_QtConcurrentFilter::filterThreadPool()
CHECK_FAIL("function");
testFilterThreadPool(&pool, intList, intListEven, lambdaIsOdd);
CHECK_FAIL("lambda");
+
+ // non-template sequences
+ {
+
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ QtConcurrent::filter(list, keepEvenIntegers).waitForFinished();
+ QCOMPARE(list, NonTemplateSequence({ 2, 4 }));
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ QtConcurrent::blockingFilter(list, keepEvenIntegers);
+ QCOMPARE(list, NonTemplateSequence({ 2, 4 }));
+ }
}
void tst_QtConcurrentFilter::filterWithMoveOnlyCallable()
@@ -254,6 +280,18 @@ void tst_QtConcurrentFilter::filtered()
testFiltered(intList, intListEven, lambdaIsEven);
CHECK_FAIL("lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future = QtConcurrent::filtered(list, keepEvenIntegers);
+ QCOMPARE(future.results(), QList({ 2, 4 }));
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result = QtConcurrent::blockingFiltered(list, keepEvenIntegers);
+ QCOMPARE(result, NonTemplateSequence({ 2, 4 }));
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filtered(std::vector { 1, 2, 3, 4 }, keepEvenIntegers);
@@ -329,6 +367,18 @@ void tst_QtConcurrentFilter::filteredThreadPool()
testFilteredThreadPool(&pool, intList, intListEven, lambdaIsOdd);
CHECK_FAIL("lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future = QtConcurrent::filtered(&pool, list, keepEvenIntegers);
+ QCOMPARE(future.results(), QList({ 2, 4 }));
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result = QtConcurrent::blockingFiltered(&pool, list, keepEvenIntegers);
+ QCOMPARE(result, NonTemplateSequence({ 2, 4 }));
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filtered(&pool, std::vector { 1, 2, 3, 4 }, keepEvenIntegers);
@@ -561,6 +611,18 @@ void tst_QtConcurrentFilter::filteredReduced()
testFilteredReduced(intList, intSum, lambdaIsEven, lambdaIntSumReduce);
CHECK_FAIL("lambda-lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future = QtConcurrent::filteredReduced(list, keepEvenIntegers, intSumReduce);
+ QCOMPARE(future.result(), intSum);
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result = QtConcurrent::blockingFilteredReduced(list, keepEvenIntegers, intSumReduce);
+ QCOMPARE(result, intSum);
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filteredReduced(std::vector { 1, 2, 3, 4 }, keepEvenIntegers,
@@ -689,6 +751,19 @@ void tst_QtConcurrentFilter::filteredReducedThreadPool()
testFilteredReducedThreadPool(&pool, intList, intSum, lambdaIsOdd, lambdaSumReduce);
CHECK_FAIL("lambda-lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future = QtConcurrent::filteredReduced(&pool, list, keepOddIntegers, intSumReduce);
+ QCOMPARE(future.result(), intSum);
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result =
+ QtConcurrent::blockingFilteredReduced(&pool, list, keepOddIntegers, intSumReduce);
+ QCOMPARE(result, intSum);
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filteredReduced(&pool, std::vector { 1, 2, 3, 4 },
@@ -987,6 +1062,20 @@ void tst_QtConcurrentFilter::filteredReducedInitialValue()
lambdaIntSumReduce, intInitial);
CHECK_FAIL("lambda-lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future =
+ QtConcurrent::filteredReduced(list, keepEvenIntegers, intSumReduce, intInitial);
+ QCOMPARE(future.result(), intSum);
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result = QtConcurrent::blockingFilteredReduced(list, keepEvenIntegers, intSumReduce,
+ intInitial);
+ QCOMPARE(result, intSum);
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filteredReduced(std::vector { 1, 2, 3, 4 }, keepEvenIntegers,
@@ -1127,6 +1216,20 @@ void tst_QtConcurrentFilter::filteredReducedInitialValueThreadPool()
lambdaSumReduce, intInitial);
CHECK_FAIL("lambda-lambda");
+ // non-template sequences
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto future =
+ QtConcurrent::filteredReduced(list, keepOddIntegers, intSumReduce, intInitial);
+ QCOMPARE(future.result(), intSum);
+ }
+ {
+ NonTemplateSequence list({ 1, 2, 3, 4 });
+ auto result = QtConcurrent::blockingFilteredReduced(list, keepOddIntegers, intSumReduce,
+ intInitial);
+ QCOMPARE(result, intSum);
+ }
+
{
// rvalue sequences
auto future = QtConcurrent::filteredReduced(&pool, std::vector { 1, 2, 3, 4 },
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index 93cf1bf99e8..973a9b4fa5b 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -201,6 +201,13 @@ void tst_QtConcurrentMap::map()
QCOMPARE(moveOnlyVector, MoveOnlyVector<int>({ 2, 4, 6 }));
}
+ // non-template sequences
+ {
+ NonTemplateSequence list { 1, 2, 3 };
+ QtConcurrent::map(list, multiplyBy2InPlace).waitForFinished();
+ QCOMPARE(list, NonTemplateSequence({ 2, 4, 6 }));
+ }
+
#if 0
// not allowed: map() with immutable sequences makes no sense
{
@@ -331,6 +338,13 @@ void tst_QtConcurrentMap::blockingMap()
QCOMPARE(list, QList<int>() << 1 << 2 << 3);
}
+ // non-template sequences
+ {
+ NonTemplateSequence list { 1, 2, 3 };
+ QtConcurrent::blockingMap(list, multiplyBy2InPlace);
+ QCOMPARE(list, NonTemplateSequence({ 2, 4, 6 }));
+ }
+
#if 0
// not allowed: map() with immutable sequences makes no sense
{
@@ -564,6 +578,17 @@ void tst_QtConcurrentMap::mapped()
#endif
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future = QtConcurrent::mapped(list, multiplyBy2);
+ QCOMPARE(future.results(), QList({ 2, 4, 6 }));
+
+ auto result = QtConcurrent::blockingMapped(list, multiplyBy2);
+ QCOMPARE(result, NonTemplateSequence({ 2, 4, 6 }));
+ }
+
+ {
// rvalue sequences
auto future = QtConcurrent::mapped(std::vector { 1, 2, 3 }, multiplyBy2);
QCOMPARE(future.results(), QList<int>({ 2, 4, 6 }));
@@ -667,6 +692,17 @@ void tst_QtConcurrentMap::mappedThreadPool()
CHECK_FAIL("lambda");
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future = QtConcurrent::mapped(&pool, list, multiplyBy2);
+ QCOMPARE(future.results(), QList({ 2, 4, 6 }));
+
+ auto result = QtConcurrent::blockingMapped(&pool, list, multiplyBy2);
+ QCOMPARE(result, NonTemplateSequence({ 2, 4, 6 }));
+ }
+
+ {
// rvalue sequences
auto future = QtConcurrent::mapped(&pool, std::vector { 1, 2, 3 }, multiplyBy2);
QCOMPARE(future.results(), QList<int>({ 2, 4, 6 }));
@@ -881,6 +917,17 @@ void tst_QtConcurrentMap::mappedReduced()
CHECK_FAIL("lambda-lambda");
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future = QtConcurrent::mappedReduced(list, multiplyBy2, intSumReduce);
+ QCOMPARE(future.result(), 12);
+
+ auto result = QtConcurrent::blockingMappedReduced(list, multiplyBy2, intSumReduce);
+ QCOMPARE(result, 12);
+ }
+
+ {
// rvalue sequences
auto future = QtConcurrent::mappedReduced(std::vector { 1, 2, 3 }, intSquare, intSumReduce);
QCOMPARE(future.result(), sumOfSquares);
@@ -1020,6 +1067,17 @@ void tst_QtConcurrentMap::mappedReducedThreadPool()
CHECK_FAIL("lambda-lambda");
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future = QtConcurrent::mappedReduced(&pool, list, multiplyBy2, intSumReduce);
+ QCOMPARE(future.result(), 12);
+
+ auto result = QtConcurrent::blockingMappedReduced(&pool, list, multiplyBy2, intSumReduce);
+ QCOMPARE(result, 12);
+ }
+
+ {
// rvalue sequences
auto future =
QtConcurrent::mappedReduced(&pool, std::vector { 1, 2, 3 }, intCube, intSumReduce);
@@ -1283,6 +1341,18 @@ void tst_QtConcurrentMap::mappedReducedInitialValue()
CHECK_FAIL("lambda-lambda");
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future = QtConcurrent::mappedReduced(list, multiplyBy2, intSumReduce, intInitial);
+ QCOMPARE(future.result(), intInitial + 12);
+
+ auto result =
+ QtConcurrent::blockingMappedReduced(list, multiplyBy2, intSumReduce, intInitial);
+ QCOMPARE(result, intInitial + 12);
+ }
+
+ {
// rvalue sequences
auto future = QtConcurrent::mappedReduced(std::vector { 1, 2, 3 }, intSquare, intSumReduce,
intInitial);
@@ -1420,6 +1490,19 @@ void tst_QtConcurrentMap::mappedReducedInitialValueThreadPool()
CHECK_FAIL("lambda-lambda");
{
+ // non-template sequences
+ NonTemplateSequence list { 1, 2, 3 };
+
+ auto future =
+ QtConcurrent::mappedReduced(&pool, list, multiplyBy2, intSumReduce, intInitial);
+ QCOMPARE(future.result(), intInitial + 12);
+
+ auto result = QtConcurrent::blockingMappedReduced(&pool, list, multiplyBy2, intSumReduce,
+ intInitial);
+ QCOMPARE(result, intInitial + 12);
+ }
+
+ {
// rvalue sequences
auto future = QtConcurrent::mappedReduced(&pool, std::vector { 1, 2, 3 }, intCube,
intSumReduce, intInitial);
diff --git a/tests/auto/concurrent/testhelper_functions.h b/tests/auto/concurrent/testhelper_functions.h
index e890053e5ca..a34e0f4ce9d 100644
--- a/tests/auto/concurrent/testhelper_functions.h
+++ b/tests/auto/concurrent/testhelper_functions.h
@@ -28,6 +28,8 @@
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
+#include <QList>
+
#include <vector>
bool keepEvenIntegers(const int &x)
@@ -196,4 +198,11 @@ private:
std::vector<T> data;
};
+struct NonTemplateSequence : public QList<int>
+{
+ NonTemplateSequence() = default;
+
+ NonTemplateSequence(std::initializer_list<int> args) : QList(args) { }
+};
+
#endif