summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/concurrent/qtconcurrentfilter.cpp100
-rw-r--r--src/concurrent/qtconcurrentfilter.h119
-rw-r--r--src/concurrent/qtconcurrentfilterkernel.h44
-rw-r--r--src/concurrent/qtconcurrentmap.cpp81
-rw-r--r--src/concurrent/qtconcurrentmap.h132
-rw-r--r--src/concurrent/qtconcurrentmapkernel.h49
-rw-r--r--src/concurrent/qtconcurrentreducekernel.h10
-rw-r--r--tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp423
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp370
9 files changed, 1309 insertions, 19 deletions
diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp
index 606a9dbe03..bac8ac59fc 100644
--- a/src/concurrent/qtconcurrentfilter.cpp
+++ b/src/concurrent/qtconcurrentfilter.cpp
@@ -93,7 +93,7 @@
\section1 Concurrent Filter-Reduce
QtConcurrent::filteredReduced() is similar to QtConcurrent::filtered(),
- but instead of returing a sequence with the filtered results, the results
+ but instead of returning a sequence with the filtered results, the results
are combined into a single value using a reduce function.
The reduce function must be of the form:
@@ -267,6 +267,27 @@
*/
/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
\fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item from \a begin to \a end. If
@@ -285,6 +306,27 @@
*/
/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \sa {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
\fn template <typename Sequence, typename KeepFunctor> void QtConcurrent::blockingFilter(Sequence &sequence, KeepFunctor filterFunction)
Calls \a filterFunction once for each item in \a sequence. If
@@ -344,6 +386,29 @@
*/
/*!
+ \fn template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item in \a sequence. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which \a reduceFunction
+ is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of
+ the original sequence.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
\fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a filterFunction once for each item from \a begin to \a end. If
@@ -365,6 +430,30 @@
*/
/*!
+ \fn template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a filterFunction once for each item from \a begin to \a end. If
+ \a filterFunction returns \c true for an item, that item is then passed to
+ \a reduceFunction. In other words, the return value is the result of
+ \a reduceFunction for each item where \a filterFunction returns \c true.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a filterFunction is called concurrently, only one thread
+ at a time will call \a reduceFunction. The order in which
+ \a reduceFunction is called is undefined if \a reduceOptions is
+ QtConcurrent::UnorderedReduce. If \a reduceOptions is
+ QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order
+ of the original sequence.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce}
+*/
+
+/*!
\fn [QtConcurrent-2] ThreadEngineStarter<typename qValueType<Iterator>::value_type> QtConcurrent::startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
\internal
*/
@@ -384,3 +473,12 @@
\internal
*/
+/*!
+ \fn [QtConcurrent-6] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType initialValue, ReduceOptions options)
+ \internal
+*/
+
+/*!
+ \fn [QtConcurrent-7] ThreadEngineStarter<ResultType> QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType initialValue, ReduceOptions options)
+ \internal
+*/
diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h
index d01b351ad0..4c7d1ee7e5 100644
--- a/src/concurrent/qtconcurrentfilter.h
+++ b/src/concurrent/qtconcurrentfilter.h
@@ -76,6 +76,20 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence,
return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options);
}
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
#ifndef Q_CLANG_QDOC
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(const Sequence &sequence,
@@ -89,6 +103,21 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere
QtPrivate::createFunctionWrapper(reduce),
options);
}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
#endif
// filteredReduced() on iterators
@@ -102,6 +131,20 @@ QFuture<ResultType> filteredReduced(Iterator begin,
return startFilteredReduced<ResultType>(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options);
}
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
#ifndef Q_CLANG_QDOC
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor>
QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(Iterator begin,
@@ -116,6 +159,21 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere
QtPrivate::createFunctionWrapper(reduce),
options);
}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
#endif
// filtered() on sequences
@@ -150,6 +208,21 @@ ResultType blockingFilteredReduced(const Sequence &sequence,
.startBlocking();
}
+template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
#ifndef Q_CLANG_QDOC
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(const Sequence &sequence,
@@ -163,6 +236,21 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered
QtPrivate::createFunctionWrapper(reduce),
options);
}
+
+template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return blockingFilteredReduced<ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
#endif
// blocking filteredReduced() on iterators
@@ -181,6 +269,21 @@ ResultType blockingFilteredReduced(Iterator begin,
.startBlocking();
}
+template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
#ifndef Q_CLANG_QDOC
template <typename Iterator, typename KeepFunctor, typename ReduceFunctor>
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(Iterator begin,
@@ -196,6 +299,22 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered
options)
.startBlocking();
}
+
+template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startFilteredReduced<ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(keep),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
#endif
// blocking filtered() on sequences
diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h
index e921a3d51a..8ec551eeb2 100644
--- a/src/concurrent/qtconcurrentfilterkernel.h
+++ b/src/concurrent/qtconcurrentfilterkernel.h
@@ -173,14 +173,15 @@ public:
: IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption)
{ }
-#if 0
- FilteredReducedKernel(ReducedResultType initialValue,
- KeepFunctor keep,
- ReduceFunctor reduce,
- ReduceOption reduceOption)
- : reducedResult(initialValue), keep(keep), reduce(reduce), reducer(reduceOption)
- { }
-#endif
+ FilteredReducedKernel(Iterator begin, Iterator end, KeepFunctor _keep, ReduceFunctor _reduce,
+ ReducedResultType &&initialValue, ReduceOptions reduceOption)
+ : IterateKernelType(begin, end),
+ reducedResult(std::forward<ReducedResultType>(initialValue)),
+ keep(_keep),
+ reduce(_reduce),
+ reducer(reduceOption)
+ {
+ }
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
@@ -337,6 +338,33 @@ inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iter
return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options));
}
+// Repeat the two functions above, but now with an initial value!
+//! [QtConcurrent-6]
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startFilteredReduced(const Sequence & sequence,
+ MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ typedef typename Sequence::const_iterator Iterator;
+ typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type > Reducer;
+ typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
+ typedef SequenceHolder2<Sequence, FilteredReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
+ return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, std::forward<ResultType>(initialValue), options));
+}
+
+//! [QtConcurrent-7]
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iterator end,
+ MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type> Reducer;
+ typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
+ return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, std::forward<ResultType>(initialValue), options));
+}
+
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp
index 157ea14b32..eff381c567 100644
--- a/src/concurrent/qtconcurrentmap.cpp
+++ b/src/concurrent/qtconcurrentmap.cpp
@@ -119,6 +119,16 @@
*/
/*!
+ \fn [qtconcurrentmapkernel-6] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType &&initialValue, ReduceOptions options)
+ \internal
+*/
+
+/*!
+ \fn [qtconcurrentmapkernel-7] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType &&initialValue, ReduceOptions options)
+ \internal
+*/
+
+/*!
\enum QtConcurrent::ReduceOption
This enum specifies the order of which results from the map or filter
function are passed to the reduce function.
@@ -344,6 +354,22 @@
*/
/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence. The return value of
+ each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
\fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item from \a begin to \a end. The return
@@ -359,6 +385,24 @@
*/
/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end. The return
+ value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. By default, the order in which
+ \a reduceFunction is called is undefined.
+
+ \note QtConcurrent::OrderedReduce results in the ordered reduction.
+
+ \sa {Concurrent Map and Map-Reduce}
+*/
+
+/*!
\fn template <typename Sequence, typename MapFunctor> void QtConcurrent::blockingMap(Sequence &sequence, MapFunctor function)
Calls \a function once for each item in \a sequence. The \a function is
@@ -427,6 +471,24 @@
*/
/*!
+ \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item in \a sequence. The return value of
+ each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is determined by \a reduceOptions.
+
+ \note This function will block until all items in the sequence have been processed.
+
+ \sa mapped(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
\fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
Calls \a mapFunction once for each item from \a begin to \a end. The return
@@ -443,6 +505,25 @@
*/
/*!
+ \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename InitialValueType> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions)
+
+ Calls \a mapFunction once for each item from \a begin to \a end. The return
+ value of each \a mapFunction is passed to \a reduceFunction.
+ The result value is initialized to \a initialValue when the function is
+ called, and the first call to \a reduceFunction will operate on
+ this value.
+
+ Note that while \a mapFunction is called concurrently, only one thread at a
+ time will call \a reduceFunction. The order in which \a reduceFunction is
+ called is undefined.
+
+ \note This function will block until the iterator reaches the end of the
+ sequence being processed.
+
+ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
+*/
+
+/*!
\class QtConcurrent::FunctionWrapper0
\inmodule QtConcurrent
\internal
diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h
index 151f03cf56..a1e7cf1044 100644
--- a/src/concurrent/qtconcurrentmap.h
+++ b/src/concurrent/qtconcurrentmap.h
@@ -83,6 +83,21 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence,
options);
}
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ ResultType>(sequence, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)),
+ options);
+}
+
template <typename Sequence, typename MapFunctor, typename ReduceFunctor>
QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(const Sequence &sequence,
MapFunctor map,
@@ -96,6 +111,22 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR
options);
}
+template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
// mappedReduced() for iterators
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
QFuture<ResultType> mappedReduced(Iterator begin,
@@ -111,6 +142,21 @@ QFuture<ResultType> mappedReduced(Iterator begin,
options);
}
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, MapFunctor map,
+ ReduceFunctor reduce, InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ ResultType>(begin, end, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)),
+ options);
+}
+
template <typename Iterator, typename MapFunctor, typename ReduceFunctor>
QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(Iterator begin,
Iterator end,
@@ -125,6 +171,22 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR
options);
}
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(
+ Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+{
+ return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options);
+}
+
// mapped() for sequences
template <typename Sequence, typename MapFunctor>
QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(const Sequence &sequence, MapFunctor map)
@@ -168,6 +230,22 @@ ResultType blockingMappedReduced(const Sequence &sequence,
.startBlocking();
}
+template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce
+ | SequentialReduce))
+{
+ return QtConcurrent::startMappedReduced<
+ typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
template <typename MapFunctor, typename ReduceFunctor, typename Sequence>
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(const Sequence &sequence,
MapFunctor map,
@@ -182,6 +260,24 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
.startBlocking();
}
+template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(
+ const Sequence &sequence, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
+{
+ return QtConcurrent::startMappedReduced<
+ typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
+ sequence, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
// blockingMappedReduced() for iterator ranges
template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
ResultType blockingMappedReduced(Iterator begin,
@@ -198,6 +294,23 @@ ResultType blockingMappedReduced(Iterator begin,
.startBlocking();
}
+template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(
+ QtConcurrent::UnorderedReduce
+ | QtConcurrent::SequentialReduce))
+{
+ return QtConcurrent::startMappedReduced<
+ typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
template <typename Iterator, typename MapFunctor, typename ReduceFunctor>
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(Iterator begin,
Iterator end,
@@ -213,6 +326,25 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
.startBlocking();
}
+template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
+ typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
+ typename InitialValueType,
+ std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
+typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(
+ Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce,
+ InitialValueType &&initialValue,
+ QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(
+ QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
+{
+ return QtConcurrent::startMappedReduced<
+ typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
+ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
+ begin, end, QtPrivate::createFunctionWrapper(map),
+ QtPrivate::createFunctionWrapper(reduce),
+ ResultType(std::forward<InitialValueType>(initialValue)), options)
+ .startBlocking();
+}
+
// mapped() for sequences with a different putput sequence type.
template <typename OutputSequence, typename InputSequence, typename MapFunctor>
OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map)
diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h
index 7c9538a015..3de275a192 100644
--- a/src/concurrent/qtconcurrentmapkernel.h
+++ b/src/concurrent/qtconcurrentmapkernel.h
@@ -101,11 +101,15 @@ public:
: IterateKernel<Iterator, ReducedResultType>(begin, end), reducedResult(), map(_map), reduce(_reduce), reducer(reduceOptions)
{ }
- MappedReducedKernel(ReducedResultType initialValue,
- MapFunctor _map,
- ReduceFunctor _reduce)
- : reducedResult(initialValue), map(_map), reduce(_reduce)
- { }
+ MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce,
+ ReducedResultType &&initialValue, ReduceOptions reduceOptions)
+ : IterateKernel<Iterator, ReducedResultType>(begin, end),
+ reducedResult(std::forward<ReducedResultType>(initialValue)),
+ map(_map),
+ reduce(_reduce),
+ reducer(reduceOptions)
+ {
+ }
bool runIteration(Iterator it, int index, ReducedResultType *) override
{
@@ -261,6 +265,41 @@ inline ThreadEngineStarter<ResultType> startMappedReduced(Iterator begin, Iterat
return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, options));
}
+//! [qtconcurrentmapkernel-6]
+template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(const Sequence &sequence,
+ MapFunctor mapFunctor,
+ ReduceFunctor reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ typedef typename Sequence::const_iterator Iterator;
+ typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
+ typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer>
+ MappedReduceType;
+ typedef SequenceHolder2<Sequence, MappedReduceType, MapFunctor, ReduceFunctor>
+ SequenceHolderType;
+ return startThreadEngine(new SequenceHolderType(
+ sequence, mapFunctor, reduceFunctor, std::forward<ResultType>(initialValue), options));
+}
+
+//! [qtconcurrentmapkernel-7]
+template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
+ typename ReduceFunctor>
+inline ThreadEngineStarter<ResultType> startMappedReduced(Iterator begin, Iterator end,
+ MapFunctor mapFunctor,
+ ReduceFunctor reduceFunctor,
+ ResultType &&initialValue,
+ ReduceOptions options)
+{
+ typedef ReduceKernel<ReduceFunctor, ResultType, IntermediateType> Reducer;
+ typedef MappedReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer>
+ MappedReduceType;
+ return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor,
+ std::forward<ResultType>(initialValue), options));
+}
+
} // namespace QtConcurrent
diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h
index 8f9a938952..eabc432374 100644
--- a/src/concurrent/qtconcurrentreducekernel.h
+++ b/src/concurrent/qtconcurrentreducekernel.h
@@ -232,6 +232,16 @@ struct SequenceHolder2 : public Base
sequence(_sequence)
{ }
+ template <typename InitialValueType>
+ SequenceHolder2(const Sequence &_sequence,
+ Functor1 functor1,
+ Functor2 functor2,
+ InitialValueType &&initialValue,
+ ReduceOptions reduceOptions)
+ : Base(_sequence.begin(), _sequence.end(), functor1, functor2, std::forward<InitialValueType>(initialValue), reduceOptions),
+ sequence(_sequence)
+ { }
+
Sequence sequence;
void finish() override
diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
index e6ac829230..1b52f52038 100644
--- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
+++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
@@ -44,6 +44,7 @@ private slots:
void incrementalResults();
void noDetach();
void stlContainers();
+ void filteredReduceInitialValue();
};
void tst_QtConcurrentFilter::filter()
@@ -728,7 +729,6 @@ void tst_QtConcurrentFilter::filteredReduced()
QCOMPARE(sum, 6);
}
- // ### the same as above, with an initial result value
}
bool filterfn(int i)
@@ -857,5 +857,426 @@ void tst_QtConcurrentFilter::stlContainers()
QCOMPARE(*list2.begin(), 1);
}
+void tst_QtConcurrentFilter::filteredReduceInitialValue()
+{
+ // This test's the same as filteredReduce, but with an initial value on all calls
+ QList<int> list;
+ list << 1 << 2 << 3 << 4;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3 << 4;
+
+ // functor-functor
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list, KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(list, keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ QVector<int> vector;
+ vector << 1 << 2 << 3 << 4;
+ int sum =
+ QtConcurrent::filteredReduced<int>(vector, KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ list.begin(), list.end(), KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(
+ list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ list.constBegin(), list.constEnd(), KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list, KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(
+ list, keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list.begin(), list.end(), KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(
+ list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list.constBegin(), list.constEnd(), KeepEvenIntegers(), IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+
+ // function-functor
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list, keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ list.begin(), list.end(), keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list, keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list.begin(), list.end(), keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, IntSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+
+ // functor-function
+ {
+ int sum = QtConcurrent::filteredReduced(list, KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(
+ list.begin(), list.end(), KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(
+ list.constBegin(), list.constEnd(), KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(list, KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ list.begin(), list.end(), KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ list.constBegin(), list.constEnd(), KeepEvenIntegers(), intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+
+ // function-function
+ {
+ int sum = QtConcurrent::filteredReduced(list, keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(
+ list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(list, keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+ // functor-member
+ QVector<int> initialIntVector;
+ initialIntVector.push_back(10);
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(
+ list, KeepEvenIntegers(), push_back, initialIntVector, QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(list.begin(),
+ list.end(),
+ KeepEvenIntegers(),
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(list.constBegin(),
+ list.constEnd(),
+ KeepEvenIntegers(),
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(
+ list, KeepEvenIntegers(), push_back, initialIntVector, QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(list.begin(),
+ list.end(),
+ KeepEvenIntegers(),
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(list.constBegin(),
+ list.constEnd(),
+ KeepEvenIntegers(),
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+
+ // member-functor
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ numberList, &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(
+ QList<Number>(numberList), &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(
+ numberList.begin(), numberList.end(), &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced<int>(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::isEven,
+ NumberSumReduce(),
+ 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ numberList, &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(
+ QList<Number>(numberList), &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(
+ numberList.begin(), numberList.end(), &Number::isEven, NumberSumReduce(), 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced<int>(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::isEven,
+ NumberSumReduce(),
+ 10);
+ QCOMPARE(sum, 16);
+ }
+
+ // member-member
+
+ auto push_back_number =
+ static_cast<void (QVector<Number>::*)(const Number &)>(&QVector<Number>::push_back);
+ QVector<Number> initialNumberVector { 10 };
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::filteredReduced(numbers,
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::filteredReduced(numbers.begin(),
+ numbers.end(),
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::filteredReduced(numbers.constBegin(),
+ numbers.constEnd(),
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::blockingFilteredReduced(numbers,
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::blockingFilteredReduced(numbers.begin(),
+ numbers.end(),
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+ {
+ QList<Number> numbers;
+ numbers << 1 << 2 << 3 << 4;
+ QList<Number> list2 = QtConcurrent::blockingFilteredReduced(numbers.constBegin(),
+ numbers.constEnd(),
+ &Number::isEven,
+ push_back_number,
+ initialNumberVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<Number>() << 10 << 2 << 4);
+ }
+
+ // function-member
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(
+ list, keepEvenIntegers, push_back, initialIntVector, QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(list.begin(),
+ list.end(),
+ keepEvenIntegers,
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::filteredReduced(list.constBegin(),
+ list.constEnd(),
+ keepEvenIntegers,
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(
+ list, keepEvenIntegers, push_back, initialIntVector, QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(list.begin(),
+ list.end(),
+ keepEvenIntegers,
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFilteredReduced(list.constBegin(),
+ list.constEnd(),
+ keepEvenIntegers,
+ push_back,
+ initialIntVector,
+ QtConcurrent::OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 2 << 4);
+ }
+
+ // member-function
+ {
+ int sum = QtConcurrent::filteredReduced(numberList, &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::filteredReduced(
+ QList<Number>(numberList), &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(
+ numberList.begin(), numberList.end(), &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::filteredReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::isEven,
+ numberSumReduce,
+ 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ numberList, &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum, 16);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced(
+ QList<Number>(numberList), &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum2, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(
+ numberList.begin(), numberList.end(), &Number::isEven, numberSumReduce, 10);
+ QCOMPARE(sum, 16);
+ }
+ {
+ int sum = QtConcurrent::blockingFilteredReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::isEven,
+ numberSumReduce,
+ 10);
+ QCOMPARE(sum, 16);
+ }
+}
+
QTEST_MAIN(tst_QtConcurrentFilter)
#include "tst_qtconcurrentfilter.moc"
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index fbcac35fee..1a8978c7ea 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -58,6 +58,8 @@ private slots:
void qFutureAssignmentLeak();
void stressTest();
void persistentResultTest();
+ void mappedReducedInitialValue();
+ void blocking_mappedReducedInitialValue();
public slots:
void throttling();
};
@@ -1084,8 +1086,6 @@ void tst_QtConcurrentMap::mappedReduced()
intSumReduce);
QCOMPARE(sum3, 6);
}
-
- // ### the same as above, with an initial result value
}
void tst_QtConcurrentMap::blocking_mappedReduced()
@@ -1271,8 +1271,6 @@ void tst_QtConcurrentMap::blocking_mappedReduced()
intSumReduce);
QCOMPARE(sum3, 6);
}
-
- // ### the same as above, with an initial result value
}
int sleeper(int val)
@@ -1767,5 +1765,369 @@ void tst_QtConcurrentMap::persistentResultTest()
QCOMPARE(ref.loadAcquire(), 3);
}
+void tst_QtConcurrentMap::mappedReducedInitialValue()
+{
+ // This is a copy of tst_QtConcurrentMap::mappedReduced with the initial value parameter added
+
+ QList<int> list;
+ list << 1 << 2 << 3;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3;
+
+ // test Q_DECLARE_OPERATORS_FOR_FLAGS
+ QtConcurrent::ReduceOptions opt =
+ (QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce);
+ QVERIFY(opt);
+
+ int initialValue = 10;
+ // functor-functor
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list, IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::mappedReduced<int>(
+ list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(
+ QList<int>(list), IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 24);
+
+ int sum4 = QtConcurrent::mappedReduced<int>(list, intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum4, 24);
+ int sum5 = QtConcurrent::mappedReduced<int>(
+ list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum5, 24);
+
+ int sum6 = QtConcurrent::mappedReduced<int>(
+ QList<int>(list), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum6, 24);
+ }
+
+ // function-functor
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list, intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::mappedReduced<int>(
+ list.constBegin(), list.constEnd(), intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(
+ QList<int>(list), intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ // functor-function
+ {
+ int sum = QtConcurrent::mappedReduced(list, IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::mappedReduced(
+ list.constBegin(), list.constEnd(), IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::mappedReduced(
+ QList<int>(list), IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ // function-function
+ {
+ int sum = QtConcurrent::mappedReduced(list, intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::mappedReduced(
+ list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::mappedReduced(
+ QList<int>(list), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+
+ QVector<int> initialIntVector;
+ initialIntVector.push_back(10);
+ // functor-member
+ {
+ QList<int> list2 = QtConcurrent::mappedReduced(
+ list, IntSquare(), push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::mappedReduced(list.constBegin(),
+ list.constEnd(),
+ IntSquare(),
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::mappedReduced(
+ QList<int>(list), IntSquare(), push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 4 << 9);
+ }
+
+ // member-functor
+ {
+ int sum = QtConcurrent::mappedReduced<int>(
+ numberList, &Number::toInt, IntSumReduce(), initialValue);
+ QCOMPARE(sum, 16);
+ int sum2 = QtConcurrent::mappedReduced<int>(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ IntSumReduce(),
+ initialValue);
+ QCOMPARE(sum2, 16);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(
+ QList<Number>(numberList), &Number::toInt, IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 16);
+ }
+
+ // member-member
+ {
+ QList<int> list2 = QtConcurrent::mappedReduced(
+ numberList, &Number::toInt, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 2 << 3);
+
+ QList<int> list3 = QtConcurrent::mappedReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 2 << 3);
+
+ QList<int> list4 = QtConcurrent::mappedReduced(QList<Number>(numberList),
+ &Number::toInt,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 2 << 3);
+ }
+
+ // function-member
+ {
+ QList<int> list2 = QtConcurrent::mappedReduced(
+ list, intSquare, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::mappedReduced(list.constBegin(),
+ list.constEnd(),
+ intSquare,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::mappedReduced(
+ QList<int>(list), intSquare, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 4 << 9);
+ }
+
+ // member-function
+ {
+ int sum =
+ QtConcurrent::mappedReduced(numberList, &Number::toInt, intSumReduce, initialValue);
+ QCOMPARE(sum, 16);
+ int sum2 = QtConcurrent::mappedReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ intSumReduce,
+ initialValue);
+ QCOMPARE(sum2, 16);
+
+ int sum3 = QtConcurrent::mappedReduced(
+ QList<Number>(numberList), &Number::toInt, intSumReduce, initialValue);
+ QCOMPARE(sum3, 16);
+ }
+}
+
+void tst_QtConcurrentMap::blocking_mappedReducedInitialValue()
+{
+ // This is a copy of tst_QtConcurrentMap::blocking_mappedReduced with the initial value
+ // parameter added
+
+ QList<int> list;
+ list << 1 << 2 << 3;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3;
+
+ int initialValue = 10;
+ // functor-functor
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(
+ list, IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(
+ list.constBegin(), list.constEnd(), IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(
+ QList<int>(list), IntSquare(), IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 24);
+
+ int sum4 = QtConcurrent::blockingMappedReduced<int>(
+ list, intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum4, 24);
+ int sum5 = QtConcurrent::blockingMappedReduced<int>(
+ list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum5, 24);
+
+ int sum6 = QtConcurrent::blockingMappedReduced<int>(
+ QList<int>(list), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum6, 24);
+ }
+
+ // function-functor
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(
+ list, intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(
+ list.constBegin(), list.constEnd(), intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(
+ QList<int>(list), intSquare, IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ // functor-function
+ {
+ int sum =
+ QtConcurrent::blockingMappedReduced(list, IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::blockingMappedReduced(
+ list.constBegin(), list.constEnd(), IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::blockingMappedReduced(
+ QList<int>(list), IntSquare(), intSumReduce, initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ // function-function
+ {
+ int sum = QtConcurrent::blockingMappedReduced(list, intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum, 24);
+ int sum2 = QtConcurrent::blockingMappedReduced(
+ list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum2, 24);
+
+ int sum3 = QtConcurrent::blockingMappedReduced(
+ QList<int>(list), intSquare, intSumReduce, initialValue);
+ QCOMPARE(sum3, 24);
+ }
+
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+
+ QVector<int> initialIntVector;
+ initialIntVector.push_back(10);
+ // functor-member
+ {
+ QList<int> list2 = QtConcurrent::blockingMappedReduced(
+ list, IntSquare(), push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::blockingMappedReduced(list.constBegin(),
+ list.constEnd(),
+ IntSquare(),
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::blockingMappedReduced(
+ QList<int>(list), IntSquare(), push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 4 << 9);
+ }
+
+ // member-functor
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(
+ numberList, &Number::toInt, IntSumReduce(), initialValue);
+ QCOMPARE(sum, 16);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ IntSumReduce(),
+ initialValue);
+ QCOMPARE(sum2, 16);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(
+ QList<Number>(numberList), &Number::toInt, IntSumReduce(), initialValue);
+ QCOMPARE(sum3, 16);
+ }
+
+ // member-member
+ {
+ QList<int> list2 = QtConcurrent::blockingMappedReduced(
+ numberList, &Number::toInt, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 2 << 3);
+
+ QList<int> list3 = QtConcurrent::blockingMappedReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 2 << 3);
+
+ QList<int> list4 = QtConcurrent::blockingMappedReduced(QList<Number>(numberList),
+ &Number::toInt,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 2 << 3);
+ }
+
+ // function-member
+ {
+ QList<int> list2 = QtConcurrent::blockingMappedReduced(
+ list, intSquare, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::blockingMappedReduced(list.constBegin(),
+ list.constEnd(),
+ intSquare,
+ push_back,
+ initialIntVector,
+ OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 10 << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::blockingMappedReduced(
+ QList<int>(list), intSquare, push_back, initialIntVector, OrderedReduce);
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 10 << 1 << 4 << 9);
+ }
+
+ // member-function
+ {
+ int sum = QtConcurrent::blockingMappedReduced(
+ numberList, &Number::toInt, intSumReduce, initialValue);
+ QCOMPARE(sum, 16);
+ int sum2 = QtConcurrent::blockingMappedReduced(numberList.constBegin(),
+ numberList.constEnd(),
+ &Number::toInt,
+ intSumReduce,
+ initialValue);
+ QCOMPARE(sum2, 16);
+
+ int sum3 = QtConcurrent::blockingMappedReduced(
+ QList<Number>(numberList), &Number::toInt, intSumReduce, initialValue);
+ QCOMPARE(sum3, 16);
+ }
+}
+
QTEST_MAIN(tst_QtConcurrentMap)
#include "tst_qtconcurrentmap.moc"