diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index 606a9dbe038..bac8ac59fc7 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: @@ -266,6 +266,27 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture 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 QFuture QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -284,6 +305,27 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture 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 void QtConcurrent::blockingFilter(Sequence &sequence, KeepFunctor filterFunction) @@ -343,6 +385,29 @@ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template 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 ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -364,6 +429,30 @@ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template 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::value_type> QtConcurrent::startFiltered(Iterator begin, Iterator end, KeepFunctor functor) \internal @@ -384,3 +473,12 @@ \internal */ +/*! + \fn [QtConcurrent-6] ThreadEngineStarter QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType initialValue, ReduceOptions options) + \internal +*/ + +/*! + \fn [QtConcurrent-7] ThreadEngineStarter 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 d01b351ad04..4c7d1ee7e52 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -76,6 +76,20 @@ QFuture filteredReduced(const Sequence &sequence, return startFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } +template , int> = 0> +QFuture filteredReduced(const Sequence &sequence, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + sequence, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} + #ifndef Q_CLANG_QDOC template QFuture::ResultType> filteredReduced(const Sequence &sequence, @@ -89,6 +103,21 @@ QFuture::ResultType> filtere QtPrivate::createFunctionWrapper(reduce), options); } + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture filteredReduced(const Sequence &sequence, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + sequence, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} #endif // filteredReduced() on iterators @@ -102,6 +131,20 @@ QFuture filteredReduced(Iterator begin, return startFilteredReduced(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } +template , int> = 0> +QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + begin, end, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} + #ifndef Q_CLANG_QDOC template QFuture::ResultType> filteredReduced(Iterator begin, @@ -116,6 +159,21 @@ QFuture::ResultType> filtere QtPrivate::createFunctionWrapper(reduce), options); } + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + begin, end, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} #endif // filtered() on sequences @@ -150,6 +208,21 @@ ResultType blockingFilteredReduced(const Sequence &sequence, .startBlocking(); } +template , int> = 0> +ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + sequence, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + #ifndef Q_CLANG_QDOC template typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(const Sequence &sequence, @@ -163,6 +236,21 @@ typename QtPrivate::ReduceResultType::ResultType blockingFiltered QtPrivate::createFunctionWrapper(reduce), options); } + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return blockingFilteredReduced( + sequence, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} #endif // blocking filteredReduced() on iterators @@ -181,6 +269,21 @@ ResultType blockingFilteredReduced(Iterator begin, .startBlocking(); } +template , int> = 0> +ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + begin, end, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + #ifndef Q_CLANG_QDOC template typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(Iterator begin, @@ -196,6 +299,22 @@ typename QtPrivate::ReduceResultType::ResultType blockingFiltered options) .startBlocking(); } + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced( + begin, end, QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} #endif // blocking filtered() on sequences diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h index e921a3d51ac..8ec551eeb2d 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(initialValue)), + keep(_keep), + reduce(_reduce), + reducer(reduceOption) + { + } bool runIteration(Iterator it, int index, ReducedResultType *) override { @@ -337,6 +338,33 @@ inline ThreadEngineStarter 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 +inline ThreadEngineStarter startFilteredReduced(const Sequence & sequence, + MapFunctor mapFunctor, ReduceFunctor reduceFunctor, + ResultType &&initialValue, + ReduceOptions options) +{ + typedef typename Sequence::const_iterator Iterator; + typedef ReduceKernel::value_type > Reducer; + typedef FilteredReducedKernel FilteredReduceType; + typedef SequenceHolder2 SequenceHolderType; + return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, std::forward(initialValue), options)); +} + +//! [QtConcurrent-7] +template +inline ThreadEngineStarter startFilteredReduced(Iterator begin, Iterator end, + MapFunctor mapFunctor, ReduceFunctor reduceFunctor, + ResultType &&initialValue, + ReduceOptions options) +{ + typedef ReduceKernel::value_type> Reducer; + typedef FilteredReducedKernel FilteredReduceType; + return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, std::forward(initialValue), options)); +} + } // namespace QtConcurrent diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp index 157ea14b326..eff381c5677 100644 --- a/src/concurrent/qtconcurrentmap.cpp +++ b/src/concurrent/qtconcurrentmap.cpp @@ -118,6 +118,16 @@ \internal */ +/*! + \fn [qtconcurrentmapkernel-6] ThreadEngineStarter QtConcurrent::startMappedReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType &&initialValue, ReduceOptions options) + \internal +*/ + +/*! + \fn [qtconcurrentmapkernel-7] ThreadEngineStarter 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 @@ -343,6 +353,22 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture 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 QFuture QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -358,6 +384,24 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture 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 void QtConcurrent::blockingMap(Sequence &sequence, MapFunctor function) @@ -426,6 +470,24 @@ \sa mapped(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template 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 ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -442,6 +504,25 @@ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template 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 diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index 151f03cf564..a1e7cf10440 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -83,6 +83,21 @@ QFuture mappedReduced(const Sequence &sequence, options); } +template , int> = 0> +QFuture mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced::ResultType, + ResultType>(sequence, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), + options); +} + template QFuture::ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, @@ -96,6 +111,22 @@ QFuture::ResultType> mappedR options); } +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced::ResultType, + typename QtPrivate::ReduceResultType::ResultType>( + sequence, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} + // mappedReduced() for iterators template QFuture mappedReduced(Iterator begin, @@ -111,6 +142,21 @@ QFuture mappedReduced(Iterator begin, options); } +template , int> = 0> +QFuture mappedReduced(Iterator begin, Iterator end, MapFunctor map, + ReduceFunctor reduce, InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced::ResultType, + ResultType>(begin, end, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), + options); +} + template QFuture::ResultType> mappedReduced(Iterator begin, Iterator end, @@ -125,6 +171,22 @@ QFuture::ResultType> mappedR options); } +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture::ResultType> mappedReduced( + Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) +{ + return startMappedReduced::ResultType, + typename QtPrivate::ReduceResultType::ResultType>( + begin, end, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options); +} + // mapped() for sequences template QFuture::ResultType> mapped(const Sequence &sequence, MapFunctor map) @@ -168,6 +230,22 @@ ResultType blockingMappedReduced(const Sequence &sequence, .startBlocking(); } +template , int> = 0> +ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced< + typename QtPrivate::MapResultType::ResultType, ResultType>( + sequence, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + template typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, @@ -182,6 +260,24 @@ typename QtPrivate::ReduceResultType::ResultType blockingMappedRe .startBlocking(); } +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( + const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced< + typename QtPrivate::MapResultType::ResultType, + typename QtPrivate::ReduceResultType::ResultType>( + sequence, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + // blockingMappedReduced() for iterator ranges template ResultType blockingMappedReduced(Iterator begin, @@ -198,6 +294,23 @@ ResultType blockingMappedReduced(Iterator begin, .startBlocking(); } +template , 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::ResultType, ResultType>( + begin, end, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + template typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced(Iterator begin, Iterator end, @@ -213,6 +326,25 @@ typename QtPrivate::ReduceResultType::ResultType blockingMappedRe .startBlocking(); } +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +typename QtPrivate::ReduceResultType::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::ResultType, + typename QtPrivate::ReduceResultType::ResultType>( + begin, end, QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + ResultType(std::forward(initialValue)), options) + .startBlocking(); +} + // mapped() for sequences with a different putput sequence type. template OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h index 7c9538a015d..3de275a1927 100644 --- a/src/concurrent/qtconcurrentmapkernel.h +++ b/src/concurrent/qtconcurrentmapkernel.h @@ -101,11 +101,15 @@ public: : IterateKernel(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(begin, end), + reducedResult(std::forward(initialValue)), + map(_map), + reduce(_reduce), + reducer(reduceOptions) + { + } bool runIteration(Iterator it, int index, ReducedResultType *) override { @@ -261,6 +265,41 @@ inline ThreadEngineStarter startMappedReduced(Iterator begin, Iterat return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, options)); } +//! [qtconcurrentmapkernel-6] +template +inline ThreadEngineStarter startMappedReduced(const Sequence &sequence, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + ResultType &&initialValue, + ReduceOptions options) +{ + typedef typename Sequence::const_iterator Iterator; + typedef ReduceKernel Reducer; + typedef MappedReducedKernel + MappedReduceType; + typedef SequenceHolder2 + SequenceHolderType; + return startThreadEngine(new SequenceHolderType( + sequence, mapFunctor, reduceFunctor, std::forward(initialValue), options)); +} + +//! [qtconcurrentmapkernel-7] +template +inline ThreadEngineStarter startMappedReduced(Iterator begin, Iterator end, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + ResultType &&initialValue, + ReduceOptions options) +{ + typedef ReduceKernel Reducer; + typedef MappedReducedKernel + MappedReduceType; + return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, + std::forward(initialValue), options)); +} + } // namespace QtConcurrent diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index 8f9a9389526..eabc4323745 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -232,6 +232,16 @@ struct SequenceHolder2 : public Base sequence(_sequence) { } + template + SequenceHolder2(const Sequence &_sequence, + Functor1 functor1, + Functor2 functor2, + InitialValueType &&initialValue, + ReduceOptions reduceOptions) + : Base(_sequence.begin(), _sequence.end(), functor1, functor2, std::forward(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 e6ac8292302..1b52f520387 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 list; + list << 1 << 2 << 3 << 4; + QList numberList; + numberList << 1 << 2 << 3 << 4; + + // functor-functor + { + int sum = QtConcurrent::filteredReduced(list, KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::filteredReduced(list, keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + { + QVector vector; + vector << 1 << 2 << 3 << 4; + int sum = + QtConcurrent::filteredReduced(vector, KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + } + { + int sum = QtConcurrent::filteredReduced( + list.begin(), list.end(), KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::filteredReduced( + list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + { + int sum = QtConcurrent::filteredReduced( + list.constBegin(), list.constEnd(), KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::filteredReduced( + list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + { + int sum = QtConcurrent::blockingFilteredReduced( + list, KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::blockingFilteredReduced( + list, keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + { + int sum = QtConcurrent::blockingFilteredReduced( + list.begin(), list.end(), KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::blockingFilteredReduced( + list.begin(), list.end(), keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + { + int sum = QtConcurrent::blockingFilteredReduced( + list.constBegin(), list.constEnd(), KeepEvenIntegers(), IntSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::blockingFilteredReduced( + list.constBegin(), list.constEnd(), keepEvenIntegers, intSumReduce, 10); + QCOMPARE(sum2, 16); + } + + // function-functor + { + 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); + } + + // 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::*)(const int &)>(&QVector::push_back); + // functor-member + QVector initialIntVector; + initialIntVector.push_back(10); + { + QList list2 = QtConcurrent::filteredReduced( + list, KeepEvenIntegers(), push_back, initialIntVector, QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::filteredReduced(list.begin(), + list.end(), + KeepEvenIntegers(), + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::filteredReduced(list.constBegin(), + list.constEnd(), + KeepEvenIntegers(), + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced( + list, KeepEvenIntegers(), push_back, initialIntVector, QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced(list.begin(), + list.end(), + KeepEvenIntegers(), + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced(list.constBegin(), + list.constEnd(), + KeepEvenIntegers(), + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + + // member-functor + { + int sum = QtConcurrent::filteredReduced( + numberList, &Number::isEven, NumberSumReduce(), 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::filteredReduced( + QList(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(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); + } + + // member-member + + auto push_back_number = + static_cast::*)(const Number &)>(&QVector::push_back); + QVector initialNumberVector { 10 }; + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::filteredReduced(numbers, + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::filteredReduced(numbers.begin(), + numbers.end(), + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::filteredReduced(numbers.constBegin(), + numbers.constEnd(), + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::blockingFilteredReduced(numbers, + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::blockingFilteredReduced(numbers.begin(), + numbers.end(), + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList numbers; + numbers << 1 << 2 << 3 << 4; + QList list2 = QtConcurrent::blockingFilteredReduced(numbers.constBegin(), + numbers.constEnd(), + &Number::isEven, + push_back_number, + initialNumberVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + + // function-member + { + QList list2 = QtConcurrent::filteredReduced( + list, keepEvenIntegers, push_back, initialIntVector, QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::filteredReduced(list.begin(), + list.end(), + keepEvenIntegers, + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::filteredReduced(list.constBegin(), + list.constEnd(), + keepEvenIntegers, + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced( + list, keepEvenIntegers, push_back, initialIntVector, QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced(list.begin(), + list.end(), + keepEvenIntegers, + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + { + QList list2 = QtConcurrent::blockingFilteredReduced(list.constBegin(), + list.constEnd(), + keepEvenIntegers, + push_back, + initialIntVector, + QtConcurrent::OrderedReduce); + QCOMPARE(list2, QList() << 10 << 2 << 4); + } + + // member-function + { + int sum = QtConcurrent::filteredReduced(numberList, &Number::isEven, numberSumReduce, 10); + QCOMPARE(sum, 16); + + int sum2 = QtConcurrent::filteredReduced( + QList(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(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 fbcac35feec..1a8978c7eae 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 list; + list << 1 << 2 << 3; + QList 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(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(list), IntSquare(), IntSumReduce(), initialValue); + QCOMPARE(sum3, 24); + + int sum4 = QtConcurrent::mappedReduced(list, intSquare, intSumReduce, initialValue); + QCOMPARE(sum4, 24); + int sum5 = QtConcurrent::mappedReduced( + list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue); + QCOMPARE(sum5, 24); + + int sum6 = QtConcurrent::mappedReduced( + QList(list), intSquare, intSumReduce, initialValue); + QCOMPARE(sum6, 24); + } + + // function-functor + { + 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(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(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(list), intSquare, intSumReduce, initialValue); + QCOMPARE(sum3, 24); + } + + auto push_back = static_cast::*)(const int &)>(&QVector::push_back); + + QVector initialIntVector; + initialIntVector.push_back(10); + // functor-member + { + QList list2 = QtConcurrent::mappedReduced( + list, IntSquare(), push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 10 << 1 << 4 << 9); + + QList list3 = QtConcurrent::mappedReduced(list.constBegin(), + list.constEnd(), + IntSquare(), + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 10 << 1 << 4 << 9); + + QList list4 = QtConcurrent::mappedReduced( + QList(list), IntSquare(), push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 10 << 1 << 4 << 9); + } + + // member-functor + { + 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(numberList), &Number::toInt, IntSumReduce(), initialValue); + QCOMPARE(sum3, 16); + } + + // member-member + { + QList list2 = QtConcurrent::mappedReduced( + numberList, &Number::toInt, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list2, QList() << 10 << 1 << 2 << 3); + + QList list3 = QtConcurrent::mappedReduced(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list3, QList() << 10 << 1 << 2 << 3); + + QList list4 = QtConcurrent::mappedReduced(QList(numberList), + &Number::toInt, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list4, QList() << 10 << 1 << 2 << 3); + } + + // function-member + { + QList list2 = QtConcurrent::mappedReduced( + list, intSquare, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 10 << 1 << 4 << 9); + + QList list3 = QtConcurrent::mappedReduced(list.constBegin(), + list.constEnd(), + intSquare, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 10 << 1 << 4 << 9); + + QList list4 = QtConcurrent::mappedReduced( + QList(list), intSquare, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 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(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 list; + list << 1 << 2 << 3; + QList numberList; + numberList << 1 << 2 << 3; + + int initialValue = 10; + // functor-functor + { + 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(list), IntSquare(), IntSumReduce(), initialValue); + QCOMPARE(sum3, 24); + + int sum4 = QtConcurrent::blockingMappedReduced( + list, intSquare, intSumReduce, initialValue); + QCOMPARE(sum4, 24); + int sum5 = QtConcurrent::blockingMappedReduced( + list.constBegin(), list.constEnd(), intSquare, intSumReduce, initialValue); + QCOMPARE(sum5, 24); + + int sum6 = QtConcurrent::blockingMappedReduced( + QList(list), intSquare, intSumReduce, initialValue); + QCOMPARE(sum6, 24); + } + + // function-functor + { + 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(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(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(list), intSquare, intSumReduce, initialValue); + QCOMPARE(sum3, 24); + } + + auto push_back = static_cast::*)(const int &)>(&QVector::push_back); + + QVector initialIntVector; + initialIntVector.push_back(10); + // functor-member + { + QList list2 = QtConcurrent::blockingMappedReduced( + list, IntSquare(), push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 10 << 1 << 4 << 9); + + QList list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), + list.constEnd(), + IntSquare(), + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 10 << 1 << 4 << 9); + + QList list4 = QtConcurrent::blockingMappedReduced( + QList(list), IntSquare(), push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 10 << 1 << 4 << 9); + } + + // member-functor + { + 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(numberList), &Number::toInt, IntSumReduce(), initialValue); + QCOMPARE(sum3, 16); + } + + // member-member + { + QList list2 = QtConcurrent::blockingMappedReduced( + numberList, &Number::toInt, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list2, QList() << 10 << 1 << 2 << 3); + + QList list3 = QtConcurrent::blockingMappedReduced(numberList.constBegin(), + numberList.constEnd(), + &Number::toInt, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list3, QList() << 10 << 1 << 2 << 3); + + QList list4 = QtConcurrent::blockingMappedReduced(QList(numberList), + &Number::toInt, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list4, QList() << 10 << 1 << 2 << 3); + } + + // function-member + { + QList list2 = QtConcurrent::blockingMappedReduced( + list, intSquare, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list2, QList() << 10 << 1 << 4 << 9); + + QList list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), + list.constEnd(), + intSquare, + push_back, + initialIntVector, + OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list3, QList() << 10 << 1 << 4 << 9); + + QList list4 = QtConcurrent::blockingMappedReduced( + QList(list), intSquare, push_back, initialIntVector, OrderedReduce); + QCOMPARE(list, QList() << 1 << 2 << 3); + QCOMPARE(list4, QList() << 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(numberList), &Number::toInt, intSumReduce, initialValue); + QCOMPARE(sum3, 16); + } +} + QTEST_MAIN(tst_QtConcurrentMap) #include "tst_qtconcurrentmap.moc"