diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index 789188911e7..6839de46415 100644 --- a/src/concurrent/qtconcurrentfilter.cpp +++ b/src/concurrent/qtconcurrentfilter.cpp @@ -235,6 +235,17 @@ \internal */ +/*! + \fn template QFuture QtConcurrent::filter(QThreadPool *pool, Sequence &sequence, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + If \a filterFunction returns \c true, the item is kept in \a sequence; + otherwise, the item is removed from \a sequence. + + \sa {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template QFuture QtConcurrent::filter(Sequence &sequence, KeepFunctor filterFunction) @@ -245,6 +256,18 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture QtConcurrent::filtered(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item in \a sequence and returns a + new Sequence of kept items. All calls to \a filterFunction are invoked from the threads + taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a copy of + the item is put in the new Sequence. Otherwise, the item will \e not + appear in the new Sequence. + + \sa {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template QFuture QtConcurrent::filtered(const Sequence &sequence, KeepFunctor filterFunction) @@ -256,6 +279,18 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture::value_type> QtConcurrent::filtered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item from \a begin to \a end and + returns a new Sequence of kept items. All calls to \a filterFunction are invoked from the threads + taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a + copy of the item is put in the new Sequence. Otherwise, the item will + \e not appear in the new Sequence. + + \sa {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template QFuture::value_type> QtConcurrent::filtered(Iterator begin, Iterator end, KeepFunctor filterFunction) @@ -267,6 +302,25 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture QtConcurrent::filteredReduced(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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. + + 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(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -285,6 +339,28 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture QtConcurrent::filteredReduced(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -306,6 +382,25 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture QtConcurrent::filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item from \a begin to \a end. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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. + + 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 QFuture QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -324,6 +419,28 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template QFuture QtConcurrent::filteredReduced(QThreadPool *pool, 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. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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 QFuture QtConcurrent::filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -345,6 +462,19 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template void QtConcurrent::blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + If \a filterFunction returns \c true, the item is kept in \a sequence; + otherwise, the item is removed from \a sequence. + + \note This function will block until all items in the sequence have been processed. + + \sa {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template void QtConcurrent::blockingFilter(Sequence &sequence, KeepFunctor filterFunction) @@ -357,6 +487,20 @@ \sa {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template Sequence QtConcurrent::blockingFiltered(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item in \a sequence and returns a + new Sequence of kept items. All calls to \a filterFunction are invoked from the threads + taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a copy of + the item is put in the new Sequence. Otherwise, the item will \e not + appear in the new Sequence. + + \note This function will block until all items in the sequence have been processed. + + \sa filtered(), {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template Sequence QtConcurrent::blockingFiltered(const Sequence &sequence, KeepFunctor filterFunction) @@ -370,6 +514,21 @@ \sa filtered(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template OutputSequence QtConcurrent::blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor filterFunction) + + Calls \a filterFunction once for each item from \a begin to \a end and + returns a new Sequence of kept items. All calls to \a filterFunction are invoked from the threads + taken from the QThreadPool \a pool. If \a filterFunction returns \c true, a + copy of the item is put in the new Sequence. Otherwise, the item will + \e not appear in the new Sequence. + + \note This function will block until the iterator reaches the end of the + sequence being processed. + + \sa filtered(), {Concurrent Filter and Filter-Reduce} +*/ + /*! \fn template OutputSequence QtConcurrent::blockingFiltered(Iterator begin, Iterator end, KeepFunctor filterFunction) @@ -384,6 +543,27 @@ \sa filtered(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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. + + 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(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -404,6 +584,30 @@ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item in \a sequence. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -427,6 +631,28 @@ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a filterFunction once for each item from \a begin to \a end. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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. + + 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 template ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -448,6 +674,31 @@ \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingFilteredReduced(QThreadPool *pool, 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. + All calls to \a filterFunction are invoked from the threads taken from the QThreadPool \a pool. + 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 template ResultType QtConcurrent::blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -473,31 +724,31 @@ */ /*! - \fn [QtConcurrent-2] ThreadEngineStarter::value_type> QtConcurrent::startFiltered(Iterator begin, Iterator end, KeepFunctor functor) + \fn [QtConcurrent-2] ThreadEngineStarter::value_type> QtConcurrent::startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor functor) \internal */ /*! - \fn [QtConcurrent-3] ThreadEngineStarter QtConcurrent::startFiltered(const Sequence &sequence, KeepFunctor functor) + \fn [QtConcurrent-3] ThreadEngineStarter QtConcurrent::startFiltered(QThreadPool *pool, const Sequence &sequence, KeepFunctor functor) \internal */ /*! - \fn [QtConcurrent-4] ThreadEngineStarter QtConcurrent::startFilteredReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options) + \fn [QtConcurrent-4] ThreadEngineStarter QtConcurrent::startFilteredReduced(QThreadPool *pool, const Sequence &sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options) \internal */ /*! - \fn [QtConcurrent-5] ThreadEngineStarter QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options) + \fn [QtConcurrent-5] ThreadEngineStarter QtConcurrent::startFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options) \internal */ /*! - \fn [QtConcurrent-6] ThreadEngineStarter QtConcurrent::startFilteredReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType initialValue, ReduceOptions options) + \fn [QtConcurrent-6] ThreadEngineStarter QtConcurrent::startFilteredReduced(QThreadPool *pool, const Sequence &sequence, 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) + \fn [QtConcurrent-7] ThreadEngineStarter QtConcurrent::startFilteredReduced(QThreadPool *pool, 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 df4c9ed384f..5feedec7512 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -53,286 +53,560 @@ namespace QtConcurrent { //! [QtConcurrent-1] template -ThreadEngineStarter filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce) +ThreadEngineStarter filterInternal(QThreadPool *pool, Sequence &sequence, + KeepFunctor keep, ReduceFunctor reduce) { typedef FilterKernel KernelType; - return startThreadEngine(new KernelType(sequence, keep, reduce)); + return startThreadEngine(new KernelType(pool, sequence, keep, reduce)); } // filter() on sequences +template +QFuture filter(QThreadPool *pool, Sequence &sequence, KeepFunctor keep) +{ + return filterInternal(pool, sequence, keep, QtPrivate::PushBackWrapper()); +} + template QFuture filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, keep, QtPrivate::PushBackWrapper()); + return filterInternal(QThreadPool::globalInstance(), + sequence, keep, QtPrivate::PushBackWrapper()); } // filteredReduced() on sequences +template +QFuture filteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(pool, sequence, keep, reduce, options); +} + template QFuture filteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return startFilteredReduced(sequence, keep, reduce, options); + return startFilteredReduced(QThreadPool::globalInstance(), + sequence, keep, reduce, options); } template , int> = 0> -QFuture filteredReduced(const Sequence &sequence, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +QFuture filteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - sequence, keep, - reduce, - ResultType(std::forward(initialValue)), options); + return startFilteredReduced(pool, sequence, keep, reduce, + ResultType(std::forward(initialValue)), options); +} + +template , int> = 0> +QFuture filteredReduced(const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(QThreadPool::globalInstance(), sequence, keep, reduce, + ResultType(std::forward(initialValue)), options); } #ifndef Q_CLANG_QDOC template -QFuture::ResultType> filteredReduced(const Sequence &sequence, +QFuture::ResultType> filteredReduced( + QThreadPool *pool, + const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startFilteredReduced::ResultType> - (sequence, - keep, - reduce, - options); + (pool, sequence, keep, reduce, options); +} + +template +QFuture::ResultType> filteredReduced( + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced::ResultType> + (QThreadPool::globalInstance(), sequence, keep, reduce, options); } template ::ResultType, typename InitialValueType, std::enable_if_t, int> = 0> -QFuture filteredReduced(const Sequence &sequence, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +QFuture filteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - sequence, keep, - reduce, - ResultType(std::forward(initialValue)), options); + return startFilteredReduced(pool, sequence, keep, reduce, + ResultType(std::forward(initialValue)), 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(QThreadPool::globalInstance(), sequence, keep, reduce, + ResultType(std::forward(initialValue)), options); } #endif // filteredReduced() on iterators +template +QFuture filteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(pool, begin, end, keep, reduce, options); +} + template QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return startFilteredReduced(begin, end, keep, reduce, options); + return startFilteredReduced(QThreadPool::globalInstance(), begin, end, keep, reduce, + options); } template , int> = 0> -QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +QFuture filteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - begin, end, keep, - reduce, - ResultType(std::forward(initialValue)), options); + return startFilteredReduced(pool, begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options); +} + +template , int> = 0> +QFuture filteredReduced(Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(QThreadPool::globalInstance(), begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options); } #ifndef Q_CLANG_QDOC template -QFuture::ResultType> filteredReduced(Iterator begin, +QFuture::ResultType> filteredReduced( + QThreadPool *pool, + Iterator begin, Iterator end, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startFilteredReduced::ResultType> - (begin, end, - keep, - reduce, - options); + (pool, begin, end, keep, reduce, options); +} + +template +QFuture::ResultType> filteredReduced( + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced::ResultType> + (QThreadPool::globalInstance(), begin, end, keep, reduce, options); } template ::ResultType, typename InitialValueType, std::enable_if_t, int> = 0> -QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +QFuture filteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - begin, end, keep, - reduce, - ResultType(std::forward(initialValue)), options); + return startFilteredReduced(pool, begin, end, keep, reduce, + ResultType(std::forward(initialValue)), 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(QThreadPool::globalInstance(), begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options); } #endif // filtered() on sequences +template +QFuture filtered(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep) +{ + return startFiltered(pool, sequence, keep); +} + template QFuture filtered(const Sequence &sequence, KeepFunctor keep) { - return startFiltered(sequence, keep); + return startFiltered(QThreadPool::globalInstance(), sequence, keep); } // filtered() on iterators template -QFuture::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep) +QFuture::value_type> filtered(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep) { - return startFiltered(begin, end, keep); + return startFiltered(pool, begin, end, keep); +} + +template +QFuture::value_type> filtered(Iterator begin, + Iterator end, + KeepFunctor keep) +{ + return startFiltered(QThreadPool::globalInstance(), begin, end, keep); } // blocking filter() on sequences +template +void blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor keep) +{ + filterInternal(pool, sequence, keep, QtPrivate::PushBackWrapper()).startBlocking(); +} + template void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, keep, QtPrivate::PushBackWrapper()).startBlocking(); + filterInternal(QThreadPool::globalInstance(), sequence, keep, QtPrivate::PushBackWrapper()) + .startBlocking(); } // blocking filteredReduced() on sequences +template +ResultType blockingFilteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(pool, sequence, keep, reduce, options) + .startBlocking(); +} + template ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return startFilteredReduced(sequence, keep, reduce, options) - .startBlocking(); + return startFilteredReduced(QThreadPool::globalInstance(), + sequence, keep, reduce, options).startBlocking(); } template , int> = 0> -ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, +ResultType blockingFilteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - sequence, keep, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return startFilteredReduced(pool, sequence, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); +} + +template , int> = 0> +ResultType blockingFilteredReduced(const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(QThreadPool::globalInstance(), sequence, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } #ifndef Q_CLANG_QDOC template -typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(const Sequence &sequence, +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced( + QThreadPool *pool, + const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startFilteredReduced::ResultType> - (sequence, - keep, - reduce, - options).startBlocking(); + (pool, sequence, keep, reduce, options).startBlocking(); +} + +template +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced( + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced::ResultType> + (QThreadPool::globalInstance(), sequence, keep, reduce, options).startBlocking(); } template ::ResultType, typename InitialValueType, std::enable_if_t, int> = 0> -ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce, +ResultType blockingFilteredReduced(QThreadPool *pool, + const Sequence &sequence, + KeepFunctor keep, + ReduceFunctor reduce, InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - sequence, keep, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return startFilteredReduced(pool, sequence, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); +} + +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 startFilteredReduced(QThreadPool::globalInstance(), sequence, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } #endif // blocking filteredReduced() on iterators +template +ResultType blockingFilteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(pool, begin, end, keep, reduce, options) + .startBlocking(); +} + template ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return startFilteredReduced - (begin, end, - keep, - reduce, - options) - .startBlocking(); + return startFilteredReduced(QThreadPool::globalInstance(), begin, end, keep, + reduce, options).startBlocking(); +} + + +template , int> = 0> +ResultType blockingFilteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced(pool, begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } template , int> = 0> -ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +ResultType blockingFilteredReduced(Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - begin, end, keep, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return startFilteredReduced(QThreadPool::globalInstance(), begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } #ifndef Q_CLANG_QDOC template -typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced(Iterator begin, +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced( + QThreadPool *pool, + Iterator begin, Iterator end, KeepFunctor keep, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startFilteredReduced::ResultType> - (begin, end, - keep, - reduce, - options) - .startBlocking(); + (pool, begin, end, keep, reduce, options).startBlocking(); +} + +template +typename QtPrivate::ReduceResultType::ResultType blockingFilteredReduced( + Iterator begin, + Iterator end, + KeepFunctor keep, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startFilteredReduced::ResultType> + (QThreadPool::globalInstance(), begin, end, keep, reduce, options).startBlocking(); } template ::ResultType, typename InitialValueType, std::enable_if_t, int> = 0> -ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor keep, - ReduceFunctor reduce, InitialValueType &&initialValue, +ResultType blockingFilteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, KeepFunctor keep, + ReduceFunctor reduce, + InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced( - begin, end, keep, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return startFilteredReduced(pool, begin, end, keep, reduce, + ResultType(std::forward(initialValue)), 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(QThreadPool::globalInstance(), begin, end, keep, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } #endif // blocking filtered() on sequences +template +Sequence blockingFiltered(QThreadPool *pool, const Sequence &sequence, KeepFunctor keep) +{ + return startFilteredReduced(pool, sequence, keep, QtPrivate::PushBackWrapper(), + OrderedReduce).startBlocking(); +} + template Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return startFilteredReduced(sequence, keep, QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); + return startFilteredReduced(QThreadPool::globalInstance(), sequence, keep, + QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } // blocking filtered() on iterators +template +OutputSequence blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor keep) +{ + return startFilteredReduced(pool, begin, end, keep, + QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); +} + template OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { - return startFilteredReduced(begin, end, - keep, - QtPrivate::PushBackWrapper(), - OrderedReduce).startBlocking(); + return startFilteredReduced(QThreadPool::globalInstance(), begin, end, keep, + QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } } // namespace QtConcurrent diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h index babd173ff8c..90d5b9aa770 100644 --- a/src/concurrent/qtconcurrentfilterkernel.h +++ b/src/concurrent/qtconcurrentfilterkernel.h @@ -87,8 +87,9 @@ class FilterKernel : public IterateKernel(_sequence).begin(), const_cast(_sequence).end()), reducedResult(), + FilterKernel(QThreadPool *pool, Sequence &_sequence, KeepFunctor _keep, ReduceFunctor _reduce) + : IterateKernelType(pool, const_cast(_sequence).begin(), + const_cast(_sequence).end()), reducedResult(), sequence(_sequence), keep(_keep), reduce(_reduce), @@ -165,17 +166,20 @@ class FilteredReducedKernel : public IterateKernel typedef IterateKernel IterateKernelType; public: - FilteredReducedKernel(Iterator begin, + FilteredReducedKernel(QThreadPool *pool, + Iterator begin, Iterator end, KeepFunctor _keep, ReduceFunctor _reduce, ReduceOptions reduceOption) - : IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption) + : IterateKernelType(pool, begin, end), reducedResult(), keep(_keep), reduce(_reduce), + reducer(reduceOption) { } - FilteredReducedKernel(Iterator begin, Iterator end, KeepFunctor _keep, ReduceFunctor _reduce, - ReducedResultType &&initialValue, ReduceOptions reduceOption) - : IterateKernelType(begin, end), + FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor _keep, + ReduceFunctor _reduce, ReducedResultType &&initialValue, + ReduceOptions reduceOption) + : IterateKernelType(pool, begin, end), reducedResult(std::forward(initialValue)), keep(_keep), reduce(_reduce), @@ -251,8 +255,8 @@ public: typedef T ReturnType; typedef T ResultType; - FilteredEachKernel(Iterator begin, Iterator end, KeepFunctor _keep) - : IterateKernelType(begin, end), keep(_keep) + FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor _keep) + : IterateKernelType(pool, begin, end), keep(_keep) { } void start() override @@ -296,73 +300,98 @@ public: template inline ThreadEngineStarter::value_type> -startFiltered(Iterator begin, Iterator end, KeepFunctor functor) +startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor functor) { - return startThreadEngine(new FilteredEachKernel(begin, end, functor)); + return startThreadEngine(new FilteredEachKernel + (pool, begin, end, functor)); } //! [QtConcurrent-3] template inline ThreadEngineStarter -startFiltered(const Sequence &sequence, KeepFunctor functor) +startFiltered(QThreadPool *pool, const Sequence &sequence, KeepFunctor functor) { typedef SequenceHolder1, KeepFunctor> SequenceHolderType; - return startThreadEngine(new SequenceHolderType(sequence, functor)); + return startThreadEngine(new SequenceHolderType(pool, sequence, functor)); } //! [QtConcurrent-4] template -inline ThreadEngineStarter startFilteredReduced(const Sequence & sequence, - MapFunctor mapFunctor, ReduceFunctor reduceFunctor, - ReduceOptions options) +inline ThreadEngineStarter startFilteredReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + 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, options)); + typedef ReduceKernel::value_type > + Reducer; + typedef FilteredReducedKernel + FilteredReduceType; + typedef SequenceHolder2 + SequenceHolderType; + return startThreadEngine(new SequenceHolderType(pool, sequence, mapFunctor, + reduceFunctor, options)); } //! [QtConcurrent-5] template -inline ThreadEngineStarter startFilteredReduced(Iterator begin, Iterator end, - MapFunctor mapFunctor, ReduceFunctor reduceFunctor, - ReduceOptions options) +inline ThreadEngineStarter startFilteredReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + ReduceOptions options) { - typedef ReduceKernel::value_type> Reducer; - typedef FilteredReducedKernel FilteredReduceType; - return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options)); + typedef ReduceKernel::value_type> + Reducer; + typedef FilteredReducedKernel + FilteredReduceType; + return startThreadEngine(new FilteredReduceType(pool, 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) +inline ThreadEngineStarter startFilteredReduced(QThreadPool *pool, + 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)); + typedef ReduceKernel::value_type > + Reducer; + typedef FilteredReducedKernel + FilteredReduceType; + typedef SequenceHolder2 + SequenceHolderType; + return startThreadEngine(new SequenceHolderType(pool, 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) +inline ThreadEngineStarter startFilteredReduced(QThreadPool *pool, + 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)); + typedef ReduceKernel::value_type> + Reducer; + typedef FilteredReducedKernel + FilteredReduceType; + return startThreadEngine(new FilteredReduceType(pool, begin, end, mapFunctor, reduceFunctor, + std::forward(initialValue), options)); } diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h index 09009efedcc..efe679ccf24 100644 --- a/src/concurrent/qtconcurrentiteratekernel.h +++ b/src/concurrent/qtconcurrentiteratekernel.h @@ -158,8 +158,8 @@ class IterateKernel : public ThreadEngine public: typedef T ResultType; - IterateKernel(Iterator _begin, Iterator _end) - : begin(_begin), end(_end), current(_begin), currentIndex(0), + IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end) + : ThreadEngine(pool), begin(_begin), end(_end), current(_begin), currentIndex(0), forIteration(selectIteration(typename std::iterator_traits::iterator_category())), progressReportingEnabled(true) { iterationCount = forIteration ? std::distance(_begin, _end) : 0; diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp index 2ad54835409..e60e35af328 100644 --- a/src/concurrent/qtconcurrentmap.cpp +++ b/src/concurrent/qtconcurrentmap.cpp @@ -319,26 +319,59 @@ \snippet code/src_concurrent_qtconcurrentmap.cpp 13 */ +/*! + \fn template QFuture QtConcurrent::map(QThreadPool *pool, Sequence &sequence, MapFunctor function) + + Calls \a function once for each item in \a sequence. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The \a function takes a reference to the item, so that any modifications done to the item + will appear in \a sequence. + + \sa {Concurrent Map and Map-Reduce} +*/ + /*! \fn template QFuture QtConcurrent::map(Sequence &sequence, MapFunctor function) - Calls \a function once for each item in \a sequence. The \a function is - passed a reference to the item, so that any modifications done to the item + Calls \a function once for each item in \a sequence. The \a function takes + a reference to the item, so that any modifications done to the item will appear in \a sequence. \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture QtConcurrent::map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor function) + + Calls \a function once for each item from \a begin to \a end. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The \a function takes a reference to the item, so that any modifications + done to the item will appear in the sequence which the iterators belong to. + + \sa {Concurrent Map and Map-Reduce} +*/ + /*! \fn template QFuture QtConcurrent::map(Iterator begin, Iterator end, MapFunctor function) Calls \a function once for each item from \a begin to \a end. The - \a function is passed a reference to the item, so that any modifications + \a function takes a reference to the item, so that any modifications done to the item will appear in the sequence which the iterators belong to. \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture> QtConcurrent::mapped(QThreadPool *pool, const Sequence &sequence, MapFunctor function) + + Calls \a function once for each item in \a sequence and returns a future + with each mapped item as a result. All calls to \a function are invoked from the + threads taken from the QThreadPool \a pool. You can use QFuture::const_iterator or + QFutureIterator to iterate through the results. + + \sa {Concurrent Map and Map-Reduce} +*/ + /*! \fn template QFuture> QtConcurrent::mapped(const Sequence &sequence, MapFunctor function) @@ -349,6 +382,17 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture> QtConcurrent::mapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor function) + + Calls \a function once for each item from \a begin to \a end and returns a + future with each mapped item as a result. All calls to \a function are invoked from the + threads taken from the QThreadPool \a pool. You can use + QFuture::const_iterator or QFutureIterator to iterate through the results. + + \sa {Concurrent Map and Map-Reduce} +*/ + /*! \fn template QFuture> QtConcurrent::mapped(Iterator begin, Iterator end, MapFunctor function) @@ -359,6 +403,20 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture QtConcurrent::mappedReduced(QThreadPool *pool, const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item in \a sequence. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The return value of each \a mapFunction is passed to \a reduceFunction. + + 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(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -372,6 +430,23 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture QtConcurrent::mappedReduced(QThreadPool *pool, const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item in \a sequence. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + 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(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -388,6 +463,22 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture QtConcurrent::mappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item from \a begin to \a end. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The return value of each \a mapFunction is passed to \a reduceFunction. + + 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 QFuture QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -403,6 +494,25 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template QFuture QtConcurrent::mappedReduced(QThreadPool *pool, 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. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + 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 QFuture QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -421,11 +531,24 @@ \sa {Concurrent Map and Map-Reduce} */ +/*! + \fn template void QtConcurrent::blockingMap(QThreadPool *pool, Sequence &sequence, MapFunctor function) + + Calls \a function once for each item in \a sequence. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The \a function takes a reference to the item, so that any modifications done to the item + will appear in \a sequence. + + \note This function will block until all items in the sequence have been processed. + + \sa map(), {Concurrent Map and Map-Reduce} +*/ + /*! \fn template void QtConcurrent::blockingMap(Sequence &sequence, MapFunctor function) - Calls \a function once for each item in \a sequence. The \a function is - passed a reference to the item, so that any modifications done to the item + Calls \a function once for each item in \a sequence. The \a function takes + a reference to the item, so that any modifications done to the item will appear in \a sequence. \note This function will block until all items in the sequence have been processed. @@ -433,11 +556,25 @@ \sa map(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template void QtConcurrent::blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor function) + + Calls \a function once for each item from \a begin to \a end. + All calls to \a function are invoked from the threads taken from the QThreadPool \a pool. + The \a function takes a reference to the item, so that any modifications + done to the item will appear in the sequence which the iterators belong to. + + \note This function will block until the iterator reaches the end of the + sequence being processed. + + \sa map(), {Concurrent Map and Map-Reduce} +*/ + /*! \fn template void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunctor function) Calls \a function once for each item from \a begin to \a end. The - \a function is passed a reference to the item, so that any modifications + \a function takes a reference to the item, so that any modifications done to the item will appear in the sequence which the iterators belong to. \note This function will block until the iterator reaches the end of the @@ -446,6 +583,18 @@ \sa map(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template OutputSequence QtConcurrent::blockingMapped(QThreadPool *pool, const InputSequence &sequence, MapFunctor function) + + Calls \a function once for each item in \a sequence and returns an OutputSequence containing + the results. All calls to \a function are invoked from the threads taken from the QThreadPool + \a pool. The type of the results will match the type returned my the MapFunctor. + + \note This function will block until all items in the sequence have been processed. + + \sa mapped(), {Concurrent Map and Map-Reduce} +*/ + /*! \fn template OutputSequence QtConcurrent::blockingMapped(const InputSequence &sequence, MapFunctor function) @@ -457,11 +606,29 @@ \sa mapped(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template Sequence QtConcurrent::blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor function) + + Calls \a function once for each item from \a begin to \a end and returns a + container with the results. All calls to \a function are invoked from the threads + taken from the QThreadPool \a pool. You can specify the type of container as the a template + argument, like this: + + \code + QList ints = QtConcurrent::blockingMapped >(beginIterator, endIterator, fn); + \endcode + + \note This function will block until the iterator reaches the end of the + sequence being processed. + + \sa mapped(), {Concurrent Map and Map-Reduce} +*/ + /*! \fn template Sequence QtConcurrent::blockingMapped(Iterator begin, Iterator end, MapFunctor function) Calls \a function once for each item from \a begin to \a end and returns a - container with the results. Specify the type of container as the a template + container with the results. You can specify the type of container as the a template argument, like this: \code @@ -474,6 +641,22 @@ \sa mapped(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item in \a sequence. + All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool. + The return value of each \a mapFunction is passed to \a reduceFunction. + + 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(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -489,6 +672,25 @@ \sa mapped(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item in \a sequence. + All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool. + 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(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) @@ -507,6 +709,23 @@ \sa mapped(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) + + Calls \a mapFunction once for each item from \a begin to \a end. + All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool. + The return value of each \a mapFunction is passed to \a reduceFunction. + + 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} +*/ + /*! \fn template ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions) @@ -523,6 +742,26 @@ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce} */ +/*! + \fn template ResultType QtConcurrent::blockingMappedReduced(QThreadPool *pool, 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. + All calls to \a mapFunction are invoked from the threads taken from the QThreadPool \a pool. + 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} +*/ + /*! \fn template ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, InitialValueType &&initialValue, QtConcurrent::ReduceOptions reduceOptions) diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index 9b8ccc3eafb..7076d9ecdee 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -56,59 +56,128 @@ QT_BEGIN_NAMESPACE namespace QtConcurrent { // map() on sequences +template +QFuture map(QThreadPool *pool, Sequence &sequence, MapFunctor map) +{ + return startMap(pool, sequence.begin(), sequence.end(), map); +} + template QFuture map(Sequence &sequence, MapFunctor map) { - return startMap(sequence.begin(), sequence.end(), map); + return startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(), map); } // map() on iterators +template +QFuture map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor map) +{ + return startMap(pool, begin, end, map); +} + template QFuture map(Iterator begin, Iterator end, MapFunctor map) { - return startMap(begin, end, map); + return startMap(QThreadPool::globalInstance(), begin, end, map); } // mappedReduced() for sequences. +template +QFuture mappedReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (pool, sequence, map, reduce, options); +} + template QFuture mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startMappedReduced, ResultType> - (sequence, - map, - reduce, + (QThreadPool::globalInstance(), sequence, map, reduce, options); +} + +template , int> = 0> +QFuture mappedReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (pool, sequence, map, reduce, ResultType(std::forward(initialValue)), options); } template , int> = 0> -QFuture mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, +QFuture mappedReduced(const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, + ResultType(std::forward(initialValue)), options); +} + +template +QFuture::ResultType> mappedReduced( + QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, + typename QtPrivate::ReduceResultType::ResultType> + (pool, sequence, map, reduce, options); +} + +template +QFuture::ResultType> mappedReduced( + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, options); +} + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture mappedReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced, - ResultType>(sequence, map, - reduce, - ResultType(std::forward(initialValue)), - options); -} - -template -QFuture::ResultType> mappedReduced(const Sequence &sequence, - MapFunctor map, - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { return startMappedReduced, typename QtPrivate::ReduceResultType::ResultType> - (sequence, - map, - reduce, + (pool, sequence, map, reduce, ResultType(std::forward(initialValue)), options); } @@ -116,60 +185,126 @@ template ::ResultType, typename InitialValueType, std::enable_if_t, int> = 0> -QFuture mappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, +QFuture mappedReduced(const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced, - typename QtPrivate::ReduceResultType::ResultType>( - sequence, map, - reduce, - ResultType(std::forward(initialValue)), options); + return startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, + ResultType(std::forward(initialValue)), options); } // mappedReduced() for iterators +template +QFuture mappedReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (pool, begin, end, map, reduce, options); +} + template QFuture mappedReduced(Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startMappedReduced, ResultType> - (begin, end, - map, - reduce, - options); + (QThreadPool::globalInstance(), begin, end, map, reduce, options); } template , int> = 0> -QFuture mappedReduced(Iterator begin, Iterator end, MapFunctor map, - ReduceFunctor reduce, InitialValueType &&initialValue, +QFuture mappedReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (pool, begin, end, map, reduce, + ResultType(std::forward(initialValue)), options); +} + +template , int> = 0> +QFuture mappedReduced(Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced, ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, + ResultType(std::forward(initialValue)), options); +} + +template +QFuture::ResultType> mappedReduced( + QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { return startMappedReduced, - ResultType>(begin, end, map, - reduce, - ResultType(std::forward(initialValue)), - options); + typename QtPrivate::ReduceResultType::ResultType> + (pool, begin, end, map, reduce, options); } template -QFuture::ResultType> mappedReduced(Iterator begin, +QFuture::ResultType> mappedReduced( + Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { return startMappedReduced, typename QtPrivate::ReduceResultType::ResultType> - (begin, end, - map, - reduce, + (QThreadPool::globalInstance(), begin, end, map, reduce, options); +} + +template ::ResultType, + typename InitialValueType, + std::enable_if_t, int> = 0> +QFuture::ResultType> mappedReduced( + QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (pool, begin, end, map, reduce, ResultType(std::forward(initialValue)), options); } @@ -178,89 +313,174 @@ template , int> = 0> QFuture::ResultType> mappedReduced( - Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, - InitialValueType &&initialValue, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return startMappedReduced, - typename QtPrivate::ReduceResultType::ResultType>( - begin, end, map, - reduce, - ResultType(std::forward(initialValue)), options); + return startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, + ResultType(std::forward(initialValue)), options); } // mapped() for sequences template -QFuture> mapped(const Sequence &sequence, MapFunctor map) +QFuture> mapped( + QThreadPool *pool, + const Sequence &sequence, + MapFunctor map) { - return startMapped>(sequence, map); + return startMapped>(pool, sequence, map); +} + +template +QFuture> mapped( + const Sequence &sequence, + MapFunctor map) +{ + return startMapped> + (QThreadPool::globalInstance(), sequence, map); } // mapped() for iterator ranges. template -QFuture> mapped(Iterator begin, Iterator end, MapFunctor map) +QFuture> mapped( + QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map) { - return startMapped>(begin, end, map); + return startMapped>(pool, begin, end, map); +} + +template +QFuture> mapped( + Iterator begin, + Iterator end, + MapFunctor map) +{ + return startMapped> + (QThreadPool::globalInstance(), begin, end, map); } // blockingMap() for sequences +template +void blockingMap(QThreadPool *pool, Sequence &sequence, MapFunctor map) +{ + startMap(pool, sequence.begin(), sequence.end(), map).startBlocking(); +} + template void blockingMap(Sequence &sequence, MapFunctor map) { - startMap(sequence.begin(), sequence.end(), map).startBlocking(); + startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(), map).startBlocking(); } // blockingMap() for iterator ranges +template +void blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor map) +{ + startMap(pool, begin, end, map).startBlocking(); +} + template void blockingMap(Iterator begin, Iterator end, MapFunctor map) { - startMap(begin, end, map).startBlocking(); + startMap(QThreadPool::globalInstance(), begin, end, map).startBlocking(); } // blockingMappedReduced() for sequences +template +ResultType blockingMappedReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , ResultType> + (pool, sequence, map, reduce, options).startBlocking(); +} + template ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced, ResultType> - (sequence, - map, - reduce, - options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, options).startBlocking(); } template , int> = 0> -ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, +ResultType blockingMappedReduced(QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return QtConcurrent::startMappedReduced< - QtPrivate::MapResultType, ResultType>( - sequence, map, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , ResultType> + (pool, sequence, map, reduce, ResultType(std::forward(initialValue)), + options).startBlocking(); +} + +template , int> = 0> +ResultType blockingMappedReduced(const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, + ResultType(std::forward(initialValue)), options) + .startBlocking(); } template -typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced(const Sequence &sequence, +typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( + QThreadPool *pool, + const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced, - typename QtPrivate::ReduceResultType::ResultType> - (sequence, - map, - reduce, - options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (pool, sequence, map, reduce, options).startBlocking(); +} + +template +typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, options).startBlocking(); } template , int> = 0> typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( - const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, - InitialValueType &&initialValue, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) + QThreadPool *pool, + const Sequence &sequence, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced< - QtPrivate::MapResultType, - typename QtPrivate::ReduceResultType::ResultType>( - sequence, map, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (pool, sequence, map, reduce, ResultType(std::forward(initialValue)), + options).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::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), sequence, map, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } // blockingMappedReduced() for iterator ranges +template +ResultType blockingMappedReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , ResultType> + (pool, begin, end, map, reduce, options).startBlocking(); +} + template ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced, ResultType> - (begin, end, - map, - reduce, - options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, options).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< - QtPrivate::MapResultType, ResultType>( - begin, end, map, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); -} - -template -typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced(Iterator begin, +ResultType blockingMappedReduced(QThreadPool *pool, + Iterator begin, Iterator end, MapFunctor map, ReduceFunctor reduce, - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced, - typename QtPrivate::ReduceResultType::ResultType> - (begin, end, - map, - reduce, - options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , ResultType> + (pool, begin, end, map, reduce, ResultType(std::forward(initialValue)), + options).startBlocking(); +} + +template , int> = 0> +ResultType blockingMappedReduced(Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); +} + +template +typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( + QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (pool, begin, end, map, reduce, options).startBlocking(); +} + +template +typename QtPrivate::ReduceResultType::ResultType blockingMappedReduced( + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, options).startBlocking(); } template , 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)) + QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor map, + ReduceFunctor reduce, + InitialValueType &&initialValue, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) { - return QtConcurrent::startMappedReduced< - QtPrivate::MapResultType, - typename QtPrivate::ReduceResultType::ResultType>( - begin, end, map, - reduce, - ResultType(std::forward(initialValue)), options) - .startBlocking(); + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (pool, begin, end, map, reduce, ResultType(std::forward(initialValue)), + options).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, + ReduceOptions options = ReduceOptions(UnorderedReduce + | SequentialReduce)) +{ + return QtConcurrent::startMappedReduced + , + typename QtPrivate::ReduceResultType::ResultType> + (QThreadPool::globalInstance(), begin, end, map, reduce, + ResultType(std::forward(initialValue)), options).startBlocking(); } // mapped() for sequences with a different putput sequence type. +template +OutputSequence blockingMapped(QThreadPool *pool, const InputSequence &sequence, MapFunctor map) +{ + return blockingMappedReduced(pool, sequence, map, + QtPrivate::PushBackWrapper(), OrderedReduce); +} + template OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) { - return blockingMappedReduced - (sequence, - map, - QtPrivate::PushBackWrapper(), - QtConcurrent::OrderedReduce); + return blockingMappedReduced(QThreadPool::globalInstance(), sequence, map, + QtPrivate::PushBackWrapper(), OrderedReduce); +} + +template +auto blockingMapped(QThreadPool *pool, const InputSequence &sequence, MapFunctor map) +{ + using OutputSequence = typename QtPrivate::MapSequenceResultType::ResultType; + return blockingMappedReduced(pool, sequence, map, QtPrivate::PushBackWrapper(), + OrderedReduce); } template auto blockingMapped(const InputSequence &sequence, MapFunctor map) { - using OutputSequence = typename QtPrivate::MapSequenceResultType::ResultType; - return blockingMappedReduced - (sequence, - map, - QtPrivate::PushBackWrapper(), - QtConcurrent::OrderedReduce); + using OutputSequence = typename QtPrivate::MapSequenceResultType::ResultType; + return blockingMappedReduced(QThreadPool::globalInstance(), sequence, map, + QtPrivate::PushBackWrapper(), OrderedReduce); } // mapped() for iterator ranges +template +Sequence blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor map) +{ + return blockingMappedReduced(pool, begin, end, map, + QtPrivate::PushBackWrapper(), OrderedReduce); +} + template Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map) { - return blockingMappedReduced - (begin, end, - map, - QtPrivate::PushBackWrapper(), - QtConcurrent::OrderedReduce); + return blockingMappedReduced(QThreadPool::globalInstance(), begin, end, map, + QtPrivate::PushBackWrapper(), OrderedReduce); +} + +template +auto blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor map) +{ + using OutputSequence = QtPrivate::MapResultType; + return blockingMappedReduced(pool, begin, end, map, + QtPrivate::PushBackWrapper(), OrderedReduce); } template auto blockingMapped(Iterator begin, Iterator end, MapFunctor map) { using OutputSequence = QtPrivate::MapResultType; - return blockingMappedReduced - (begin, end, - map, - QtPrivate::PushBackWrapper(), - QtConcurrent::OrderedReduce); + return blockingMappedReduced(QThreadPool::globalInstance(), begin, end, map, + QtPrivate::PushBackWrapper(), OrderedReduce); } } // namespace QtConcurrent diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h index 346ffbfc7f3..e882dbfa754 100644 --- a/src/concurrent/qtconcurrentmapkernel.h +++ b/src/concurrent/qtconcurrentmapkernel.h @@ -60,8 +60,8 @@ class MapKernel : public IterateKernel MapFunctor map; public: typedef void ReturnType; - MapKernel(Iterator begin, Iterator end, MapFunctor _map) - : IterateKernel(begin, end), map(_map) + MapKernel(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor _map) + : IterateKernel(pool, begin, end), map(_map) { } bool runIteration(Iterator it, int, void *) override @@ -100,13 +100,16 @@ class MappedReducedKernel : public IterateKernel public: typedef ReducedResultType ReturnType; - MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions) - : IterateKernel(begin, end), reducedResult(), map(_map), reduce(_reduce), reducer(reduceOptions) + MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor _map, + ReduceFunctor _reduce, ReduceOptions reduceOptions) + : IterateKernel(pool, begin, end), reducedResult(), + map(_map), reduce(_reduce), reducer(reduceOptions) { } - MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, - ReducedResultType &&initialValue, ReduceOptions reduceOptions) - : IterateKernel(begin, end), + MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor _map, + ReduceFunctor _reduce, ReducedResultType &&initialValue, + ReduceOptions reduceOptions) + : IterateKernel(pool, begin, end), reducedResult(std::forward(initialValue)), map(_map), reduce(_reduce), @@ -172,8 +175,8 @@ class MappedEachKernel : public IterateKernel; public: - MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map) - : IterateKernel(begin, end), map(_map) { } + MappedEachKernel(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor _map) + : IterateKernel(pool, begin, end), map(_map) { } bool runIteration(Iterator it, int, T *result) override { @@ -197,16 +200,18 @@ public: //! [qtconcurrentmapkernel-1] template -inline ThreadEngineStarter startMap(Iterator begin, Iterator end, Functor functor) +inline ThreadEngineStarter startMap(QThreadPool *pool, Iterator begin, + Iterator end, Functor functor) { - return startThreadEngine(new MapKernel(begin, end, functor)); + return startThreadEngine(new MapKernel(pool, begin, end, functor)); } //! [qtconcurrentmapkernel-2] template -inline ThreadEngineStarter startMapped(Iterator begin, Iterator end, Functor functor) +inline ThreadEngineStarter startMapped(QThreadPool *pool, Iterator begin, + Iterator end, Functor functor) { - return startThreadEngine(new MappedEachKernel(begin, end, functor)); + return startThreadEngine(new MappedEachKernel(pool, begin, end, functor)); } /* @@ -216,8 +221,8 @@ inline ThreadEngineStarter startMapped(Iterator begin, Iterator end, Functor template struct SequenceHolder1 : public Base { - SequenceHolder1(const Sequence &_sequence, Functor functor) - : Base(_sequence.begin(), _sequence.end(), functor), sequence(_sequence) + SequenceHolder1(QThreadPool *pool, const Sequence &_sequence, Functor functor) + : Base(pool, _sequence.begin(), _sequence.end(), functor), sequence(_sequence) { } Sequence sequence; @@ -233,43 +238,57 @@ struct SequenceHolder1 : public Base //! [qtconcurrentmapkernel-3] template -inline ThreadEngineStarter startMapped(const Sequence &sequence, Functor functor) +inline ThreadEngineStarter startMapped(QThreadPool *pool, const Sequence &sequence, + Functor functor) { typedef SequenceHolder1, Functor> SequenceHolderType; - return startThreadEngine(new SequenceHolderType(sequence, functor)); + return startThreadEngine(new SequenceHolderType(pool, sequence, functor)); } //! [qtconcurrentmapkernel-4] -template -inline ThreadEngineStarter startMappedReduced(const Sequence & sequence, - MapFunctor mapFunctor, ReduceFunctor reduceFunctor, - ReduceOptions options) +template +inline ThreadEngineStarter startMappedReduced(QThreadPool *pool, + const Sequence & sequence, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + ReduceOptions options) { typedef typename Sequence::const_iterator Iterator; typedef ReduceKernel Reducer; - typedef MappedReducedKernel MappedReduceType; - typedef SequenceHolder2 SequenceHolderType; - return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options)); + typedef MappedReducedKernel + MappedReduceType; + typedef SequenceHolder2 + SequenceHolderType; + return startThreadEngine(new SequenceHolderType(pool, sequence, mapFunctor, reduceFunctor, + options)); } //! [qtconcurrentmapkernel-5] -template -inline ThreadEngineStarter startMappedReduced(Iterator begin, Iterator end, - MapFunctor mapFunctor, ReduceFunctor reduceFunctor, - ReduceOptions options) +template +inline ThreadEngineStarter startMappedReduced(QThreadPool *pool, + Iterator begin, + Iterator end, + MapFunctor mapFunctor, + ReduceFunctor reduceFunctor, + ReduceOptions options) { typedef ReduceKernel Reducer; - typedef MappedReducedKernel MappedReduceType; - return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, options)); + typedef MappedReducedKernel + MappedReduceType; + return startThreadEngine(new MappedReduceType(pool, begin, end, mapFunctor, reduceFunctor, + options)); } //! [qtconcurrentmapkernel-6] template -inline ThreadEngineStarter startMappedReduced(const Sequence &sequence, +inline ThreadEngineStarter startMappedReduced(QThreadPool *pool, + const Sequence &sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType &&initialValue, @@ -282,13 +301,16 @@ inline ThreadEngineStarter startMappedReduced(const Sequence &sequen typedef SequenceHolder2 SequenceHolderType; return startThreadEngine(new SequenceHolderType( - sequence, mapFunctor, reduceFunctor, std::forward(initialValue), options)); + pool, sequence, mapFunctor, reduceFunctor, std::forward(initialValue), + options)); } //! [qtconcurrentmapkernel-7] template -inline ThreadEngineStarter startMappedReduced(Iterator begin, Iterator end, +inline ThreadEngineStarter startMappedReduced(QThreadPool *pool, + Iterator begin, + Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ResultType &&initialValue, @@ -297,7 +319,7 @@ inline ThreadEngineStarter startMappedReduced(Iterator begin, Iterat typedef ReduceKernel Reducer; typedef MappedReducedKernel MappedReduceType; - return startThreadEngine(new MappedReduceType(begin, end, mapFunctor, reduceFunctor, + return startThreadEngine(new MappedReduceType(pool, begin, end, mapFunctor, reduceFunctor, std::forward(initialValue), options)); } diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index a487ec26a2c..4c023ebb4af 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -224,21 +224,24 @@ public: template struct SequenceHolder2 : public Base { - SequenceHolder2(const Sequence &_sequence, + SequenceHolder2(QThreadPool *pool, + const Sequence &_sequence, Functor1 functor1, Functor2 functor2, ReduceOptions reduceOptions) - : Base(_sequence.begin(), _sequence.end(), functor1, functor2, reduceOptions), + : Base(pool, _sequence.begin(), _sequence.end(), functor1, functor2, reduceOptions), sequence(_sequence) { } template - SequenceHolder2(const Sequence &_sequence, + SequenceHolder2(QThreadPool *pool, + const Sequence &_sequence, Functor1 functor1, Functor2 functor2, InitialValueType &&initialValue, ReduceOptions reduceOptions) - : Base(_sequence.begin(), _sequence.end(), functor1, functor2, std::forward(initialValue), reduceOptions), + : Base(pool, _sequence.begin(), _sequence.end(), functor1, functor2, + std::forward(initialValue), reduceOptions), sequence(_sequence) { } diff --git a/src/concurrent/qtconcurrentthreadengine.cpp b/src/concurrent/qtconcurrentthreadengine.cpp index cf424912b37..7dfc29c68f0 100644 --- a/src/concurrent/qtconcurrentthreadengine.cpp +++ b/src/concurrent/qtconcurrentthreadengine.cpp @@ -160,8 +160,8 @@ bool ThreadEngineBarrier::releaseUnlessLast() } } -ThreadEngineBase::ThreadEngineBase() -:futureInterface(0), threadPool(QThreadPool::globalInstance()) +ThreadEngineBase::ThreadEngineBase(QThreadPool *pool) + : futureInterface(0), threadPool(pool) { setAutoDelete(false); } diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h index a04f69f8e4a..eb11c34c069 100644 --- a/src/concurrent/qtconcurrentthreadengine.h +++ b/src/concurrent/qtconcurrentthreadengine.h @@ -88,7 +88,7 @@ class Q_CONCURRENT_EXPORT ThreadEngineBase: public QRunnable { public: // Public API: - ThreadEngineBase(); + ThreadEngineBase(QThreadPool *pool); virtual ~ThreadEngineBase(); void startSingleThreaded(); void startBlocking(); @@ -131,6 +131,8 @@ class ThreadEngine : public ThreadEngineBase public: typedef T ResultType; + ThreadEngine(QThreadPool *pool) : ThreadEngineBase(pool) {} + virtual T *result() { return nullptr; } QFutureInterface *futureInterfaceTyped() diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp index 6e01542a577..dbcb0a1e9ad 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp +++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp @@ -38,10 +38,14 @@ class tst_QtConcurrentFilter : public QObject private slots: void filter(); + void filterThreadPool(); void filtered(); + void filteredThreadPool(); void filteredReduced(); + void filteredReducedThreadPool(); void filteredReducedDifferentType(); void filteredReducedInitialValue(); + void filteredReducedInitialValueThreadPool(); void filteredReducedDifferentTypeInitialValue(); void resultAt(); void incrementalResults(); @@ -96,6 +100,85 @@ void tst_QtConcurrentFilter::filter() CHECK_FAIL("lambda"); } +static QSemaphore semaphore(1); +static QSet workingThreads; + +void storeCurrentThread() +{ + semaphore.acquire(); + workingThreads.insert(QThread::currentThread()); + semaphore.release(); +} + +int threadCount() +{ + semaphore.acquire(); + const int count = workingThreads.size(); + semaphore.release(); + return count; +} + +template +void testFilterThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const QList &expectedResult, + FilterObject filterObject) +{ + QList copy1 = sourceObjectList; +// QList copy2 = sourceObjectList; + + QtConcurrent::filter(pool, copy1, filterObject).waitForFinished(); + QCOMPARE(copy1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// QtConcurrent::blockingFilter(pool, copy2, filterObject); +// QCOMPARE(copy2, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +class KeepOddIntegers +{ +public: + bool operator()(const int &x) + { + storeCurrentThread(); + return x & 1; + } +}; + +bool keepOddIntegers(const int &x) +{ + storeCurrentThread(); + return x & 1; +} + +void tst_QtConcurrentFilter::filterThreadPool() +{ + const QList intList {1, 2, 3, 4}; + const QList intListEven {1, 3}; + + auto lambdaIsOdd = [](const int &x) { + storeCurrentThread(); + return x & 1; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + testFilterThreadPool(&pool, intList, intListEven, KeepOddIntegers()); + CHECK_FAIL("functor"); + testFilterThreadPool(&pool, intList, intListEven, keepOddIntegers); + CHECK_FAIL("function"); + testFilterThreadPool(&pool, intList, intListEven, lambdaIsOdd); + CHECK_FAIL("lambda"); +} + template @@ -142,6 +225,61 @@ void tst_QtConcurrentFilter::filtered() CHECK_FAIL("lambda"); } +template +void testFilteredThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const QList &expectedResult, + FilterObject filterObject) +{ + const QList result1 = QtConcurrent::filtered( + pool, sourceObjectList, filterObject).results(); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const QList result2 = QtConcurrent::filtered( + pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), + filterObject).results(); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const QList result3 = QtConcurrent::blockingFiltered( +// pool, sourceObjectList, filterObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const QList result4 = QtConcurrent::blockingFiltered>( +// pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), filterObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +void tst_QtConcurrentFilter::filteredThreadPool() +{ + const QList intList {1, 2, 3, 4}; + const QList intListEven {1, 3}; + + auto lambdaIsOdd = [](const int &x) { + storeCurrentThread(); + return x & 1; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + testFilteredThreadPool(&pool, intList, intListEven, KeepOddIntegers()); + CHECK_FAIL("functor"); + testFilteredThreadPool(&pool, intList, intListEven, keepOddIntegers); + CHECK_FAIL("function"); + testFilteredThreadPool(&pool, intList, intListEven, lambdaIsOdd); + CHECK_FAIL("lambda"); +} + template +void testFilteredReducedThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const ResultObject &expectedResult, + FilterObject filterObject, + ReduceObject reduceObject) +{ + const ResultObject result1 = QtConcurrent::filteredReduced( + pool, sourceObjectList, filterObject, reduceObject); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const ResultObject result2 = QtConcurrent::filteredReduced( + pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), + filterObject, reduceObject); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const ResultObject result3 = QtConcurrent::blockingFilteredReduced( +// pool, sourceObjectList, filterObject, reduceObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const ResultObject result4 = QtConcurrent::blockingFilteredReduced( +// pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), +// filterObject, reduceObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +void tst_QtConcurrentFilter::filteredReducedThreadPool() +{ + const QList intList {1, 2, 3, 4}; + const int intSum = 4; // sum of even values + + auto lambdaIsOdd = [](const int &x) { + storeCurrentThread(); + return x & 1; + }; + auto lambdaSumReduce = [](int &sum, const int &x) { + sum += x; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + // FUNCTOR-other + testFilteredReducedThreadPool(&pool, intList, intSum, KeepOddIntegers(), IntSumReduce()); + CHECK_FAIL("functor-functor"); + testFilteredReducedThreadPool(&pool, intList, intSum, KeepOddIntegers(), intSumReduce); + CHECK_FAIL("functor-function"); + testFilteredReducedThreadPool(&pool, intList, intSum, KeepOddIntegers(), lambdaSumReduce); + CHECK_FAIL("functor-lambda"); + + // FUNCTION-other + testFilteredReducedThreadPool(&pool, intList, intSum, keepOddIntegers, IntSumReduce()); + CHECK_FAIL("function-functor"); + testFilteredReducedThreadPool(&pool, intList, intSum, keepOddIntegers, intSumReduce); + CHECK_FAIL("function-function"); + testFilteredReducedThreadPool(&pool, intList, intSum, keepOddIntegers, lambdaSumReduce); + CHECK_FAIL("function-lambda"); + + // LAMBDA-other + testFilteredReducedThreadPool(&pool, intList, intSum, lambdaIsOdd, IntSumReduce()); + CHECK_FAIL("lambda-functor"); + testFilteredReducedThreadPool(&pool, intList, intSum, lambdaIsOdd, intSumReduce); + CHECK_FAIL("lambda-function"); + testFilteredReducedThreadPool(&pool, intList, intSum, lambdaIsOdd, lambdaSumReduce); + CHECK_FAIL("lambda-lambda"); +} + void tst_QtConcurrentFilter::filteredReducedDifferentType() { const QList numberList {1, 2, 3, 4}; @@ -472,6 +688,96 @@ void tst_QtConcurrentFilter::filteredReducedInitialValue() CHECK_FAIL("lambda-lambda"); } +template +void testFilteredReducedInitialValueThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const ResultObject &expectedResult, + FilterObject filterObject, + ReduceObject reduceObject, + InitialObject &&initialObject) +{ + const ResultObject result1 = QtConcurrent::filteredReduced( + pool, sourceObjectList, filterObject, reduceObject, initialObject); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const ResultObject result2 = QtConcurrent::filteredReduced( + pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), + filterObject, reduceObject, initialObject); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const ResultObject result3 = QtConcurrent::blockingFilteredReduced( +// pool, sourceObjectList, filterObject, reduceObject, initialObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const ResultObject result4 = QtConcurrent::blockingFilteredReduced( +// pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), +// filterObject, reduceObject, initialObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +void tst_QtConcurrentFilter::filteredReducedInitialValueThreadPool() +{ + const QList intList {1, 2, 3, 4}; + const int intInitial = 10; + const int intSum = 14; // sum of even values and initial value + + auto lambdaIsOdd = [](const int &x) { + storeCurrentThread(); + return x & 1; + }; + auto lambdaSumReduce = [](int &sum, const int &x) { + sum += x; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + // FUNCTOR-other + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, KeepOddIntegers(), + IntSumReduce(), intInitial); + CHECK_FAIL("functor-functor"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, KeepOddIntegers(), + intSumReduce, intInitial); + CHECK_FAIL("functor-function"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, KeepOddIntegers(), + lambdaSumReduce, intInitial); + CHECK_FAIL("functor-lambda"); + + // FUNCTION-other + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, keepOddIntegers, + IntSumReduce(), intInitial); + CHECK_FAIL("function-functor"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, keepOddIntegers, + intSumReduce, intInitial); + CHECK_FAIL("function-function"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, keepOddIntegers, + lambdaSumReduce, intInitial); + CHECK_FAIL("function-lambda"); + + // LAMBDA-other + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, lambdaIsOdd, + IntSumReduce(), intInitial); + CHECK_FAIL("lambda-functor"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, lambdaIsOdd, + intSumReduce, intInitial); + CHECK_FAIL("lambda-function"); + testFilteredReducedInitialValueThreadPool(&pool, intList, intSum, lambdaIsOdd, + lambdaSumReduce, intInitial); + CHECK_FAIL("lambda-lambda"); +} + void tst_QtConcurrentFilter::filteredReducedDifferentTypeInitialValue() { const QList numberList {1, 2, 3, 4}; diff --git a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp index 3c77b1ba0bd..3dd77ed3d05 100644 --- a/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp +++ b/tests/auto/concurrent/qtconcurrentiteratekernel/tst_qtconcurrentiteratekernel.cpp @@ -88,7 +88,7 @@ QAtomicInt iterations; class PrintFor : public IterateKernel { public: - PrintFor(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { iterations.storeRelaxed(0); } + PrintFor(TestIterator begin, TestIterator end) : IterateKernel(QThreadPool::globalInstance(), begin, end) { iterations.storeRelaxed(0); } bool runIterations(TestIterator/*beginIterator*/, int begin, int end, void *) { iterations.fetchAndAddRelaxed(end - begin); @@ -107,7 +107,7 @@ public: class SleepPrintFor : public IterateKernel { public: - SleepPrintFor(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { iterations.storeRelaxed(0); } + SleepPrintFor(TestIterator begin, TestIterator end) : IterateKernel(QThreadPool::globalInstance(), begin, end) { iterations.storeRelaxed(0); } inline bool runIterations(TestIterator/*beginIterator*/, int begin, int end, void *) { QTest::qSleep(200); @@ -147,7 +147,7 @@ QAtomicInt counter; class CountFor : public IterateKernel { public: - CountFor(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { iterations.storeRelaxed(0); } + CountFor(TestIterator begin, TestIterator end) : IterateKernel(QThreadPool::globalInstance(), begin, end) { iterations.storeRelaxed(0); } inline bool runIterations(TestIterator/*beginIterator*/, int begin, int end, void *) { counter.fetchAndAddRelaxed(end - begin); @@ -175,7 +175,7 @@ void tst_QtConcurrentIterateKernel::noIterations() { const int times = 20000; for (int i = 0; i < times; ++i) - startThreadEngine(new IterateKernel(0, 0)).startBlocking(); + startThreadEngine(new IterateKernel(QThreadPool::globalInstance(), 0, 0)).startBlocking(); } QMutex threadsMutex; @@ -186,7 +186,7 @@ public: // this class throttles between iterations 100 and 200, // and then records how many threads that run between // iterations 140 and 160. - ThrottleFor(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { iterations.storeRelaxed(0); throttling = false; } + ThrottleFor(TestIterator begin, TestIterator end) : IterateKernel(QThreadPool::globalInstance(), begin, end) { iterations.storeRelaxed(0); throttling = false; } inline bool runIterations(TestIterator/*beginIterator*/, int begin, int end, void *) { if (200 >= begin && 200 < end) { @@ -242,7 +242,7 @@ void tst_QtConcurrentIterateKernel::throttling() class MultipleResultsFor : public IterateKernel { public: - MultipleResultsFor(TestIterator begin, TestIterator end) : IterateKernel(begin, end) { } + MultipleResultsFor(TestIterator begin, TestIterator end) : IterateKernel(QThreadPool::globalInstance(), begin, end) { } inline bool runIterations(TestIterator, int begin, int end, int *results) { for (int i = begin; i < end; ++i) diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index 111bc7fdad3..9d904b6984b 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -43,9 +43,12 @@ private slots: void map(); void blocking_map(); void mapped(); + void mappedThreadPool(); void mappedReduced(); + void mappedReducedThreadPool(); void mappedReducedDifferentType(); void mappedReducedInitialValue(); + void mappedReducedInitialValueThreadPool(); void mappedReducedDifferentTypeInitialValue(); void assignResult(); void functionOverloads(); @@ -446,6 +449,92 @@ void tst_QtConcurrentMap::mapped() #endif } +static QSemaphore semaphore(1); +static QSet workingThreads; + +void storeCurrentThread() +{ + semaphore.acquire(); + workingThreads.insert(QThread::currentThread()); + semaphore.release(); +} + +int threadCount() +{ + semaphore.acquire(); + const int count = workingThreads.size(); + semaphore.release(); + return count; +} + +template +void testMappedThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const QList &expectedResult, + MapObject mapObject) +{ + const QList result1 = QtConcurrent::mapped(pool, + sourceObjectList, mapObject).results(); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const QList result2 = QtConcurrent::mapped(pool, + sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject).results(); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const QList result3 = QtConcurrent::blockingMapped(pool, +// sourceObjectList, mapObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const QList result4 = QtConcurrent::blockingMapped>(pool, +// sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +int multiplyBy3(int x) +{ + storeCurrentThread(); + return x * 3; +} + +class MultiplyBy3 +{ +public: + int operator()(int x) const + { + storeCurrentThread(); + return x * 3; + } +}; + +void tst_QtConcurrentMap::mappedThreadPool() +{ + const QList intList {1, 2, 3}; + const QList intListMultipiedBy3 {3, 6, 9}; + + auto lambdaMultiplyBy3 = [](int x) { + storeCurrentThread(); + return x * 3; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + testMappedThreadPool(&pool, intList, intListMultipiedBy3, MultiplyBy3()); + CHECK_FAIL("functor"); + testMappedThreadPool(&pool, intList, intListMultipiedBy3, multiplyBy3); + CHECK_FAIL("function"); + testMappedThreadPool(&pool, intList, intListMultipiedBy3, lambdaMultiplyBy3); + CHECK_FAIL("lambda"); +} + int intSquare(int x) { return x * x; @@ -572,6 +661,94 @@ void tst_QtConcurrentMap::mappedReduced() CHECK_FAIL("lambda-lambda"); } +template +void testMappedReducedThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const ResultObject &expectedResult, + MapObject mapObject, + ReduceObject reduceObject) +{ + const ResultObject result1 = QtConcurrent::mappedReduced(pool, + sourceObjectList, mapObject, reduceObject); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const ResultObject result2 = QtConcurrent::mappedReduced(pool, + sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const ResultObject result3 = QtConcurrent::blockingMappedReduced(pool, +// sourceObjectList, mapObject, reduceObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const ResultObject result4 = QtConcurrent::blockingMappedReduced(pool, +// sourceObjectList.constBegin(), sourceObjectList.constEnd(), mapObject, reduceObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +int intCube(int x) +{ + storeCurrentThread(); + return x * x * x; +} + +class IntCube +{ +public: + int operator()(int x) + { + storeCurrentThread(); + return x * x * x; + } +}; + +void tst_QtConcurrentMap::mappedReducedThreadPool() +{ + const QList intList {1, 2, 3}; + const int sumOfCubes = 36; + + auto lambdaCube = [](int x) { + return x * x * x; + }; + auto lambdaSumReduce = [](int &sum, int x) { + sum += x; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + // FUNCTOR-other + testMappedReducedThreadPool(&pool, intList, sumOfCubes, IntCube(), IntSumReduce()); + CHECK_FAIL("functor-functor"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, IntCube(), intSumReduce); + CHECK_FAIL("functor-function"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, IntCube(), lambdaSumReduce); + CHECK_FAIL("functor-lambda"); + + // FUNCTION-other + testMappedReducedThreadPool(&pool, intList, sumOfCubes, intCube, IntSumReduce()); + CHECK_FAIL("function-functor"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, intCube, intSumReduce); + CHECK_FAIL("function-function"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, intCube, lambdaSumReduce); + CHECK_FAIL("function-lambda"); + + // LAMBDA-other + testMappedReducedThreadPool(&pool, intList, sumOfCubes, lambdaCube, IntSumReduce()); + CHECK_FAIL("lambda-functor"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, lambdaCube, intSumReduce); + CHECK_FAIL("lambda-function"); + testMappedReducedThreadPool(&pool, intList, sumOfCubes, lambdaCube, lambdaSumReduce); + CHECK_FAIL("lambda-lambda"); +} + void tst_QtConcurrentMap::mappedReducedDifferentType() { const QList intList {1, 2, 3}; @@ -734,6 +911,93 @@ void tst_QtConcurrentMap::mappedReducedInitialValue() CHECK_FAIL("lambda-lambda"); } +template +void testMappedReducedInitialValueThreadPool(QThreadPool *pool, + const QList &sourceObjectList, + const ResultObject &expectedResult, + MapObject mapObject, + ReduceObject reduceObject, + InitialObject &&initialObject) +{ + const ResultObject result1 = QtConcurrent::mappedReduced( + pool, sourceObjectList, mapObject, reduceObject, initialObject); + QCOMPARE(result1, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + + const ResultObject result2 = QtConcurrent::mappedReduced( + pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), + mapObject, reduceObject, initialObject); + QCOMPARE(result2, expectedResult); + QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// TODO: enable when QTBUG-83918 is fixed + +// const ResultObject result3 = QtConcurrent::blockingMappedReduced( +// pool, sourceObjectList, mapObject, reduceObject, initialObject); +// QCOMPARE(result3, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working + +// const ResultObject result4 = QtConcurrent::blockingMappedReduced( +// pool, sourceObjectList.constBegin(), sourceObjectList.constEnd(), +// mapObject, reduceObject, initialObject); +// QCOMPARE(result4, expectedResult); +// QCOMPARE(threadCount(), 1); // ensure the only one thread was working +} + +void tst_QtConcurrentMap::mappedReducedInitialValueThreadPool() +{ + // This is a copy of tst_QtConcurrentMap::mappedReduced with the initial value parameter added + + const QList intList {1, 2, 3}; + const int sumOfCubes = 46; + const int intInitial = 10; + + auto lambdaCube = [](int x) { + return x * x * x; + }; + auto lambdaSumReduce = [](int &sum, int x) { + sum += x; + }; + + QThreadPool pool; + pool.setMaxThreadCount(1); + QCOMPARE(semaphore.available(), 1); + workingThreads.clear(); + + // FUNCTOR-other + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, IntCube(), + IntSumReduce(), intInitial); + CHECK_FAIL("functor-functor"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, IntCube(), + intSumReduce, intInitial); + CHECK_FAIL("functor-function"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, IntCube(), + lambdaSumReduce, intInitial); + CHECK_FAIL("functor-lambda"); + + // FUNCTION-other + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, intCube, + IntSumReduce(), intInitial); + CHECK_FAIL("function-functor"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, intCube, + intSumReduce, intInitial); + CHECK_FAIL("function-function"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, intCube, + lambdaSumReduce, intInitial); + CHECK_FAIL("function-lambda"); + + // LAMBDA-other + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, lambdaCube, + IntSumReduce(), intInitial); + CHECK_FAIL("lambda-functor"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, lambdaCube, + intSumReduce, intInitial); + CHECK_FAIL("lambda-function"); + testMappedReducedInitialValueThreadPool(&pool, intList, sumOfCubes, lambdaCube, + lambdaSumReduce, intInitial); + CHECK_FAIL("lambda-lambda"); +} + void tst_QtConcurrentMap::mappedReducedDifferentTypeInitialValue() { // This is a copy of tst_QtConcurrentMap::mappedReducedDifferentType diff --git a/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp index d4c669cddcc..e192dad3bd1 100644 --- a/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp +++ b/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp @@ -55,6 +55,7 @@ private slots: class PrintUser : public ThreadEngine { public: + PrintUser() : ThreadEngine(QThreadPool::globalInstance()) {} ThreadFunctionResult threadFunction() { QTest::qSleep(50); @@ -82,7 +83,8 @@ class StringResultUser : public ThreadEngine public: typedef QString ResultType; StringResultUser() - : done(false) { } + : ThreadEngine(QThreadPool::globalInstance()) + , done(false) { } bool shouldStartThread() { @@ -113,6 +115,8 @@ void tst_QtConcurrentThreadEngine::result() class VoidResultUser : public ThreadEngine { public: + VoidResultUser() : ThreadEngine(QThreadPool::globalInstance()) {} + bool shouldStartThread() { return !done; @@ -149,6 +153,8 @@ void tst_QtConcurrentThreadEngine::runThroughStarter() class CancelUser : public ThreadEngine { public: + CancelUser() : ThreadEngine(QThreadPool::globalInstance()) {} + void *result() { return 0; @@ -186,6 +192,7 @@ class ThrottleAlwaysUser : public ThreadEngine { public: ThrottleAlwaysUser() + : ThreadEngine(QThreadPool::globalInstance()) { count.storeRelaxed(initialCount = 100); finishing = false; @@ -240,6 +247,7 @@ class ThreadCountUser : public ThreadEngine { public: ThreadCountUser(bool finishImmediately = false) + : ThreadEngine(QThreadPool::globalInstance()) { threads.clear(); finishing = finishImmediately; @@ -306,6 +314,7 @@ void tst_QtConcurrentThreadEngine::threadCount() class MultipleResultsUser : public ThreadEngine { public: + MultipleResultsUser() : ThreadEngine(QThreadPool::globalInstance()) {} bool shouldStartThread() { return false; @@ -375,6 +384,7 @@ const int sleepTime = 20; class SlowUser : public ThreadEngine { public: + SlowUser() : ThreadEngine(QThreadPool::globalInstance()) {} bool shouldStartThread() { return false; } ThreadFunctionResult threadFunction() { QTest::qSleep(sleepTime); return ThreadFinished; } }; @@ -406,6 +416,7 @@ class QtConcurrentExceptionThrower : public ThreadEngine { public: QtConcurrentExceptionThrower(QThread *blockThread = 0) + : ThreadEngine(QThreadPool::globalInstance()) { this->blockThread = blockThread; } @@ -423,6 +434,7 @@ class UnrelatedExceptionThrower : public ThreadEngine { public: UnrelatedExceptionThrower(QThread *blockThread = 0) + : ThreadEngine(QThreadPool::globalInstance()) { this->blockThread = blockThread; }