diff options
author | Karsten Heimrich <karsten.heimrich@qt.io> | 2020-03-26 15:47:04 +0100 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@qt.io> | 2020-04-14 19:06:27 +0200 |
commit | 786b48878f37edafd5eb928ed0f4d046ee1d6bec (patch) | |
tree | 7dffd263964b1375dd9814d4edcfc675d7489e84 /src/concurrent | |
parent | 678b9f78a5af4513ed4e988de90148584a2ae90d (diff) |
Improve Map|Map-Reduce and Filter|Filter-Reduce implementation
* support lambda expressions
* remove the need to specify result_type
* use std::invoke to apply map|filter function
* remove usage of FunctionWrapper* and createFunctionWrapper
Task-number: QTBUG-33735
Task-number: QTBUG-82646
Change-Id: Ibcbe4278f0742c29182bd506081db0abb516f85f
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/concurrent')
-rw-r--r-- | src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp | 56 | ||||
-rw-r--r-- | src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp | 37 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentcompilertest.h | 28 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentfilter.cpp | 23 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentfilter.h | 79 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentfilterkernel.h | 20 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentfunctionwrappers.h | 272 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentmap.cpp | 51 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentmap.h | 132 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentmapkernel.h | 25 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentreducekernel.h | 2 |
11 files changed, 336 insertions, 389 deletions
diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp index 3cc1fe836c..ef87a60080 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp @@ -158,8 +158,6 @@ struct StartsWith StartsWith(const QString &string) : m_string(string) { } - typedef bool result_type; - bool operator()(const QString &testString) { return testString.startsWith(m_string); @@ -183,3 +181,57 @@ QFuture<QString> fooString = StartsWith(QLatin1String("Foo")), StringTransform()); //! [14] + +//! [15] +// keep only even integers +QVector<int> vector { 1, 2, 3, 4 }; +QtConcurrent::blockingFilter(vector, [](int n) { return (n & 1) == 0; }); + +// retrieve only even integers +QVector<int> vector2 { 1, 2, 3, 4 }; +QFuture<int> future = QtConcurrent::filtered(vector2, [](int x) { + return (x & 1) == 0; +}); +QVector<int> results = future.results(); + +// add up all even integers +QVector<int> vector3 { 1, 2, 3, 4 }; +int sum = QtConcurrent::filteredReduced<int>(vector3, + [](int x) { + return (x & 1) == 0; + }, + [](int &sum, int x) { + sum += x; + } +); +//! [15] + +//! [16] +void intSumReduce(int &sum, int x) +{ + sum += x; +} + +QVector<int> vector { 1, 2, 3, 4 }; +int sum = QtConcurrent::filteredReduced(vector, + [] (int x) { + return (x & 1) == 0; + }, + intSumReduce +); +//! [16] + +//! [17] +bool keepEvenIntegers(int x) +{ + return (x & 1) == 0; +} + +QVector<int> vector { 1, 2, 3, 4 }; +int sum = QtConcurrent::filteredReduced<int>(vector, + keepEvenIntegers, + [](int &sum, int x) { + sum += x; + } +); +//! [17] diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp index fc574302d2..dd3e0103bb 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp @@ -130,7 +130,8 @@ QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze); // Swap the rgb values of all pixels on a list of images. QList<QImage> images = ...; -QFuture<QImage> bgrImages = QtConcurrent::mapped(images, &QImage::rgbSwapped); +QFuture<QImage> bgrImages = QtConcurrent::mapped(images, + static_cast<QImage (QImage::*)() const &>(&QImage::rgbSwapped)); // Create a set of the lengths of all strings in a list. QStringList strings = ...; @@ -197,3 +198,37 @@ struct Scaled QList<QImage> images = ...; QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100)); //! [14] + +//! [15] +QVector<int> vector { 1, 2, 3, 4 }; +QtConcurrent::blockingMap(vector, [](int &x) { x *= 2; }); + +int size = 100; +QVector<QImage> images = ...; + +QVector<QImage> thumbnails = QtConcurrent::mapped(images, + [&size](const QImage &image) { + return image.scaled(size, size); + } + ).results(); +//! [15] + +//! [16] +QVector<QImage> collage = QtConcurrent::mappedReduced(images, + [&size](const QImage &image) { + return image.scaled(size, size); + }, + addToCollage + ).results(); +//! [16] + +//! [17] +QVector<QImage> collage = QtConcurrent::mappedReduced<QImage>(images, + [&size](const QImage &image) { + return image.scaled(size, size); + }, + [](QImage &result, const QImage &value) { + // do some transformation + } + ).results(); +//! [17] diff --git a/src/concurrent/qtconcurrentcompilertest.h b/src/concurrent/qtconcurrentcompilertest.h index 72cf1670a0..8292d5c504 100644 --- a/src/concurrent/qtconcurrentcompilertest.h +++ b/src/concurrent/qtconcurrentcompilertest.h @@ -48,16 +48,26 @@ QT_BEGIN_NAMESPACE namespace QtPrivate { -template<class T> -class HasResultType { - typedef char Yes; - typedef void *No; - template<typename U> static Yes test(int, const typename U::result_type * = nullptr); - template<typename U> static No test(double); -public: - enum { Value = (sizeof(test<T>(0)) == sizeof(Yes)) }; -}; + template <class T, typename = void> + struct IsIterable : std::false_type {}; + template <class T> + struct IsIterable<T, std::void_t<decltype(std::begin(std::declval<T>())), + decltype(std::end(std::declval<T>()))>> + : std::true_type + { }; + template <class T> + inline constexpr bool IsIterableValue = IsIterable<T>::value; + + template <class T, typename = void> + struct IsDereferenceable : std::false_type {}; + template <class T> + struct IsDereferenceable<T, std::void_t<decltype(*std::declval<T>())>> + : std::true_type + { }; + + template <class T> + inline constexpr bool IsDereferenceableValue = IsDereferenceable<T>::value; } QT_END_NAMESPACE diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index bac8ac59fc..789188911e 100644 --- a/src/concurrent/qtconcurrentfilter.cpp +++ b/src/concurrent/qtconcurrentfilter.cpp @@ -144,8 +144,7 @@ QtConcurrent::filter(), QtConcurrent::filtered(), and QtConcurrent::filteredReduced() accept function objects for the filter function. These function objects can be used to - add state to a function call. The result_type typedef must define the - result type of the function call operator: + add state to a function call: \snippet code/src_concurrent_qtconcurrentfilter.cpp 13 @@ -155,6 +154,26 @@ \snippet code/src_concurrent_qtconcurrentfilter.cpp 14 + \section2 Using Lambda Expressions + + QtConcurrent::filter(), QtConcurrent::filtered(), and + QtConcurrent::filteredReduced() accept lambda expressions for the filter and + reduce function: + + \snippet code/src_concurrent_qtconcurrentfilter.cpp 15 + + When using QtConcurrent::filteredReduced() or + QtConcurrent::blockingFilteredReduced(), you can mix the use of normal + functions, member functions and lambda expressions freely. + + \snippet code/src_concurrent_qtconcurrentfilter.cpp 16 + + For the reduce function, lambda expressions are not directly supported. + Lambda expressions can, however, be used when the type of the reduction + result is explicitly specified: + + \snippet code/src_concurrent_qtconcurrentfilter.cpp 17 + \section2 Wrapping Functions that Take Multiple Arguments If you want to use a filter function takes more than one argument, you can diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h index 4c7d1ee7e5..df4c9ed384 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -63,7 +63,7 @@ ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, R template <typename Sequence, typename KeepFunctor> QFuture<void> filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()); + return filterInternal(sequence, keep, QtPrivate::PushBackWrapper()); } // filteredReduced() on sequences @@ -73,7 +73,7 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); + return startFilteredReduced<ResultType>(sequence, keep, reduce, options); } template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor, @@ -85,8 +85,8 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep, | SequentialReduce)) { return startFilteredReduced<ResultType>( - sequence, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + sequence, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } @@ -99,8 +99,8 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere { return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + keep, + reduce, options); } @@ -114,8 +114,8 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep, | SequentialReduce)) { return startFilteredReduced<ResultType>( - sequence, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + sequence, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } #endif @@ -128,7 +128,7 @@ QFuture<ResultType> filteredReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); + return startFilteredReduced<ResultType>(begin, end, keep, reduce, options); } template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor, @@ -140,8 +140,8 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke | SequentialReduce)) { return startFilteredReduced<ResultType>( - begin, end, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + begin, end, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } @@ -155,8 +155,8 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere { return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (begin, end, - QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + keep, + reduce, options); } @@ -170,8 +170,8 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke | SequentialReduce)) { return startFilteredReduced<ResultType>( - begin, end, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + begin, end, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } #endif @@ -180,21 +180,21 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke template <typename Sequence, typename KeepFunctor> QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor keep) { - return startFiltered(sequence, QtPrivate::createFunctionWrapper(keep)); + return startFiltered(sequence, keep); } // filtered() on iterators template <typename Iterator, typename KeepFunctor> QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep) { - return startFiltered(begin, end, QtPrivate::createFunctionWrapper(keep)); + return startFiltered(begin, end, keep); } // blocking filter() on sequences template <typename Sequence, typename KeepFunctor> void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking(); + filterInternal(sequence, keep, QtPrivate::PushBackWrapper()).startBlocking(); } // blocking filteredReduced() on sequences @@ -204,7 +204,7 @@ ResultType blockingFilteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options) + return startFilteredReduced<ResultType>(sequence, keep, reduce, options) .startBlocking(); } @@ -217,8 +217,8 @@ ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, R | SequentialReduce)) { return startFilteredReduced<ResultType>( - sequence, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + sequence, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -230,11 +230,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), - options); + keep, + reduce, + options).startBlocking(); } template <typename Sequence, typename KeepFunctor, typename ReduceFunctor, @@ -246,10 +246,11 @@ ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, R ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced<ResultType>( - sequence, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), - ResultType(std::forward<InitialValueType>(initialValue)), options); + return startFilteredReduced<ResultType>( + sequence, keep, + reduce, + ResultType(std::forward<InitialValueType>(initialValue)), options) + .startBlocking(); } #endif @@ -263,8 +264,8 @@ ResultType blockingFilteredReduced(Iterator begin, { return startFilteredReduced<ResultType> (begin, end, - QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + keep, + reduce, options) .startBlocking(); } @@ -278,8 +279,8 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee | SequentialReduce)) { return startFilteredReduced<ResultType>( - begin, end, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + begin, end, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -294,8 +295,8 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered { return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (begin, end, - QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + keep, + reduce, options) .startBlocking(); } @@ -310,8 +311,8 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee | SequentialReduce)) { return startFilteredReduced<ResultType>( - begin, end, QtPrivate::createFunctionWrapper(keep), - QtPrivate::createFunctionWrapper(reduce), + begin, end, keep, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -321,7 +322,7 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee template <typename Sequence, typename KeepFunctor> Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return startFilteredReduced<Sequence>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); + return startFilteredReduced<Sequence>(sequence, keep, QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } // blocking filtered() on iterators @@ -329,7 +330,7 @@ template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { return startFilteredReduced<OutputSequence>(begin, end, - QtPrivate::createFunctionWrapper(keep), + keep, QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h index 8ec551eeb2..babd173ff8 100644 --- a/src/concurrent/qtconcurrentfilterkernel.h +++ b/src/concurrent/qtconcurrentfilterkernel.h @@ -78,7 +78,7 @@ class FilterKernel : public IterateKernel<typename Sequence::const_iterator, voi { typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer; typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType; - typedef typename ReduceFunctor::result_type T; + typedef void T; Sequence reducedResult; Sequence &sequence; @@ -101,11 +101,11 @@ public: results.begin = index; results.end = index + 1; - if (keep(*it)) - results.vector.append(*it); + if (std::invoke(keep, *it)) + results.vector.append(*it); - reducer.runReduce(reduce, reducedResult, results); - return false; + reducer.runReduce(reduce, reducedResult, results); + return false; } bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override @@ -119,7 +119,7 @@ public: typename Sequence::const_iterator it = sequenceBeginIterator; std::advance(it, begin); for (int i = begin; i < end; ++i) { - if (keep(*it)) + if (std::invoke(keep, *it)) results.vector.append(*it); std::advance(it, 1); } @@ -189,7 +189,7 @@ public: results.begin = index; results.end = index + 1; - if (keep(*it)) + if (std::invoke(keep, *it)) results.vector.append(*it); reducer.runReduce(reduce, reducedResult, results); @@ -206,7 +206,7 @@ public: Iterator it = sequenceBeginIterator; std::advance(it, begin); for (int i = begin; i < end; ++i) { - if (keep(*it)) + if (std::invoke(keep, *it)) results.vector.append(*it); std::advance(it, 1); } @@ -264,7 +264,7 @@ public: bool runIteration(Iterator it, int index, T *) override { - if (keep(*it)) + if (std::invoke(keep, *it)) this->reportResult(&(*it), index); else this->reportResult(nullptr, index); @@ -282,7 +282,7 @@ public: Iterator it = sequenceBeginIterator; std::advance(it, begin); for (int i = begin; i < end; ++i) { - if (keep(*it)) + if (std::invoke(keep, *it)) results.vector.append(*it); std::advance(it, 1); } diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h index 4731de77cc..34bbe89c86 100644 --- a/src/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/concurrent/qtconcurrentfunctionwrappers.h @@ -43,165 +43,64 @@ #include <QtConcurrent/qtconcurrentcompilertest.h> #include <QtCore/QStringList> +#include <tuple> + #if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) QT_BEGIN_NAMESPACE -namespace QtConcurrent { +namespace QtPrivate { -template <typename T, typename U> -class FunctionWrapper1 +struct PushBackWrapper { -public: - typedef T (*FunctionPointerType)(U u); - typedef T result_type; - inline FunctionWrapper1(FunctionPointerType _functionPointer) - :functionPointer(_functionPointer) { } - - inline T operator()(U u) + template <class C, class U> + inline void operator()(C &c, const U &u) const { - return functionPointer(u); + return c.push_back(u); } -private: - FunctionPointerType functionPointer; -}; - -template <typename T, typename C> -class MemberFunctionWrapper -{ -public: - typedef T (C::*FunctionPointerType)(); - typedef T result_type; - inline MemberFunctionWrapper(FunctionPointerType _functionPointer) - :functionPointer(_functionPointer) { } - - inline T operator()(C &c) + template <class C, class U> + inline void operator()(C &c, U &&u) const { - return (c.*functionPointer)(); + return c.push_back(u); } -private: - FunctionPointerType functionPointer; }; -template <typename T, typename C, typename U> -class MemberFunctionWrapper1 -{ -public: - typedef T (C::*FunctionPointerType)(U); - typedef T result_type; - - inline MemberFunctionWrapper1(FunctionPointerType _functionPointer) - : functionPointer(_functionPointer) - { } - - inline T operator()(C &c, U u) - { - return (c.*functionPointer)(u); - } - -private: - FunctionPointerType functionPointer; -}; +// -- MapResultType -template <typename T, typename C> -class ConstMemberFunctionWrapper +template <class T, class Enable = void> +struct Argument { -public: - typedef T (C::*FunctionPointerType)() const; - typedef T result_type; - inline ConstMemberFunctionWrapper(FunctionPointerType _functionPointer) - :functionPointer(_functionPointer) { } - - inline T operator()(const C &c) const - { - return (c.*functionPointer)(); - } -private: - FunctionPointerType functionPointer; + using Type = void; }; -} // namespace QtConcurrent. - -namespace QtPrivate { - -template <typename T> -const T& createFunctionWrapper(const T& t) +template <class Sequence> +struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type> { - return t; -} - -template <typename T, typename U> -QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U)) -{ - return QtConcurrent::FunctionWrapper1<T, U>(func); -} - -template <typename T, typename C> -QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)()) -{ - return QtConcurrent::MemberFunctionWrapper<T, C>(func); -} - -template <typename T, typename C, typename U> -QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U)) -{ - return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func); -} - -template <typename T, typename C> -QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const) -{ - return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); -} - -#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 -template <typename T, typename U> -QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U) noexcept) -{ - return QtConcurrent::FunctionWrapper1<T, U>(func); -} + using Type = std::decay_t<decltype(*std::begin(std::declval<Sequence>()))>; +}; -template <typename T, typename C> -QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() noexcept) +template <class Iterator> +struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type> { - return QtConcurrent::MemberFunctionWrapper<T, C>(func); -} + using Type = std::decay_t<decltype(*std::declval<Iterator>())>; +}; -template <typename T, typename C, typename U> -QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U) noexcept) -{ - return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func); -} +template <class T> +using ArgumentType = typename Argument<T>::Type; -template <typename T, typename C> -QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const noexcept) +template <class T, class MapFunctor> +struct MapResult { - return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); -} -#endif - -struct PushBackWrapper -{ - typedef void result_type; - - template <class C, class U> - inline void operator()(C &c, const U &u) const - { - return c.push_back(u); - } - - template <class C, class U> - inline void operator()(C &c, U &&u) const - { - return c.push_back(u); - } + static_assert(std::is_invocable_v<std::decay_t<MapFunctor>, ArgumentType<T>>, + "It's not possible to invoke the function with passed argument."); + using Type = std::invoke_result_t<std::decay_t<MapFunctor>, ArgumentType<T>>; }; -template <typename Functor, bool foo = HasResultType<Functor>::Value> -struct LazyResultType { typedef typename Functor::result_type Type; }; -template <typename Functor> -struct LazyResultType<Functor, false> { typedef void Type; }; +template <class T, class MapFunctor> +using MapResultType = typename MapResult<T, MapFunctor>::Type; + +// -- ReduceResultType template <class T> struct ReduceResultType; @@ -218,121 +117,52 @@ struct ReduceResultType<T(C::*)(U)> typedef C ResultType; }; -#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 -template <class U, class V> -struct ReduceResultType<void(*)(U&,V) noexcept> -{ - typedef U ResultType; -}; - -template <class T, class C, class U> -struct ReduceResultType<T(C::*)(U) noexcept> -{ - typedef C ResultType; -}; -#endif - -template <class InputSequence, class MapFunctor> -struct MapResultType -{ - typedef typename LazyResultType<MapFunctor>::Type ResultType; -}; - template <class U, class V> -struct MapResultType<void, U (*)(V)> +struct ReduceResultType<std::function<void(U&, V)>> { typedef U ResultType; }; -template <class T, class C> -struct MapResultType<void, T(C::*)() const> +template <typename R, typename ...A> +struct ReduceResultType<R(*)(A...)> { - typedef T ResultType; + using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type; }; #if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 template <class U, class V> -struct MapResultType<void, U (*)(V) noexcept> +struct ReduceResultType<void(*)(U&,V) noexcept> { typedef U ResultType; }; -template <class T, class C> -struct MapResultType<void, T(C::*)() const noexcept> +template <class T, class C, class U> +struct ReduceResultType<T(C::*)(U) noexcept> { - typedef T ResultType; + typedef C ResultType; }; #endif -#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS - -template <template <typename> class InputSequence, typename MapFunctor, typename T> -struct MapResultType<InputSequence<T>, MapFunctor> -{ - typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType; -}; - -template <template <typename> class InputSequence, class T, class U, class V> -struct MapResultType<InputSequence<T>, U (*)(V)> -{ - typedef InputSequence<U> ResultType; -}; +// -- MapSequenceResultType -template <template <typename> class InputSequence, class T, class U, class C> -struct MapResultType<InputSequence<T>, U(C::*)() const> -{ - typedef InputSequence<U> ResultType; -}; - -#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 - -template <template <typename> class InputSequence, class T, class U, class V> -struct MapResultType<InputSequence<T>, U (*)(V) noexcept> -{ - typedef InputSequence<U> ResultType; -}; - -template <template <typename> class InputSequence, class T, class U, class C> -struct MapResultType<InputSequence<T>, U(C::*)() const noexcept> -{ - typedef InputSequence<U> ResultType; -}; -#endif - -#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER +template <class InputSequence, class MapFunctor> +struct MapSequenceResultType; template <class MapFunctor> -struct MapResultType<QStringList, MapFunctor> +struct MapSequenceResultType<QStringList, MapFunctor> { - typedef QList<typename LazyResultType<MapFunctor>::Type> ResultType; + typedef QList<QtPrivate::MapResultType<QStringList, MapFunctor>> ResultType; }; -template <class U, class V> -struct MapResultType<QStringList, U (*)(V)> -{ - typedef QList<U> ResultType; -}; - -template <class U, class C> -struct MapResultType<QStringList, U(C::*)() const> -{ - typedef QList<U> ResultType; -}; - -#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 +#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS -template <class U, class V> -struct MapResultType<QStringList, U (*)(V) noexcept> +template <template <typename> class InputSequence, typename MapFunctor, typename T> +struct MapSequenceResultType<InputSequence<T>, MapFunctor> { - typedef QList<U> ResultType; + typedef InputSequence<QtPrivate::MapResultType<InputSequence<T>, MapFunctor>> ResultType; }; -template <class U, class C> -struct MapResultType<QStringList, U(C::*)() const noexcept> -{ - typedef QList<U> ResultType; -}; -#endif +#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER } // namespace QtPrivate. diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp index 92fe7a98f2..2ad5483540 100644 --- a/src/concurrent/qtconcurrentmap.cpp +++ b/src/concurrent/qtconcurrentmap.cpp @@ -270,8 +270,7 @@ QtConcurrent::map(), QtConcurrent::mapped(), and QtConcurrent::mappedReduced() accept function objects for the map function. These function objects can be used to - add state to a function call. The result_type typedef must define the - result type of the function call operator: + add state to a function call: \snippet code/src_concurrent_qtconcurrentmap.cpp 14 @@ -281,6 +280,26 @@ \snippet code/src_concurrent_qtconcurrentmap.cpp 11 + \section2 Using Lambda Expressions + + QtConcurrent::map(), QtConcurrent::mapped(), and + QtConcurrent::mappedReduced() accept lambda expressions for the map and + reduce function: + + \snippet code/src_concurrent_qtconcurrentmap.cpp 15 + + When using QtConcurrent::mappedReduced() or + QtConcurrent::blockingMappedReduced(), you can mix the use of normal + functions, member functions and lambda expressions freely. + + \snippet code/src_concurrent_qtconcurrentmap.cpp 16 + + For the reduce function, lambda expressions are not directly supported. + Lambda expressions can, however, be used when the type of the reduction + result is explicitly specified: + + \snippet code/src_concurrent_qtconcurrentmap.cpp 17 + \section2 Wrapping Functions that Take Multiple Arguments If you want to use a map function that takes more than one argument you can @@ -321,7 +340,7 @@ */ /*! - \fn template <typename Sequence, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(const Sequence &sequence, MapFunctor function) + \fn template <typename Sequence, typename MapFunctor> QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> QtConcurrent::mapped(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. You can use QFuture::const_iterator or @@ -331,7 +350,7 @@ */ /*! - \fn template <typename Iterator, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(Iterator begin, Iterator end, MapFunctor function) + \fn template <typename Iterator, typename MapFunctor> QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> QtConcurrent::mapped(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. You can use @@ -522,27 +541,3 @@ \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce} */ - -/*! - \class QtConcurrent::FunctionWrapper1 - \inmodule QtConcurrent - \internal -*/ - -/*! - \class QtConcurrent::MemberFunctionWrapper - \inmodule QtConcurrent - \internal -*/ - -/*! - \class QtConcurrent::MemberFunctionWrapper1 - \inmodule QtConcurrent - \internal -*/ - -/*! - \class QtConcurrent::ConstMemberFunctionWrapper - \inmodule QtConcurrent - \internal -*/ diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index a1e7cf1044..9b8ccc3eaf 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -59,14 +59,14 @@ namespace QtConcurrent { template <typename Sequence, typename MapFunctor> QFuture<void> map(Sequence &sequence, MapFunctor map) { - return startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map)); + return startMap(sequence.begin(), sequence.end(), map); } // map() on iterators template <typename Iterator, typename MapFunctor> QFuture<void> map(Iterator begin, Iterator end, MapFunctor map) { - return startMap(begin, end, QtPrivate::createFunctionWrapper(map)); + return startMap(begin, end, map); } // mappedReduced() for sequences. @@ -76,10 +76,10 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType> (sequence, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options); } @@ -91,9 +91,9 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, Redu ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, - ResultType>(sequence, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, + ResultType>(sequence, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } @@ -104,10 +104,11 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, + typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options); } @@ -120,10 +121,10 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, Redu ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, + return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>( - sequence, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + sequence, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } @@ -135,10 +136,10 @@ QFuture<ResultType> mappedReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType> (begin, end, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options); } @@ -150,9 +151,9 @@ QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, MapFunctor map, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, - ResultType>(begin, end, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, + ResultType>(begin, end, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } @@ -164,10 +165,11 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, + typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (begin, end, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options); } @@ -180,39 +182,39 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR InitialValueType &&initialValue, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, + return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>( - begin, end, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + begin, end, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options); } // mapped() for sequences template <typename Sequence, typename MapFunctor> -QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(const Sequence &sequence, MapFunctor map) +QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(const Sequence &sequence, MapFunctor map) { - return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(sequence, QtPrivate::createFunctionWrapper(map)); + return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>(sequence, map); } // mapped() for iterator ranges. template <typename Iterator, typename MapFunctor> -QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(Iterator begin, Iterator end, MapFunctor map) +QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(Iterator begin, Iterator end, MapFunctor map) { - return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(begin, end, QtPrivate::createFunctionWrapper(map)); + return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>(begin, end, map); } // blockingMap() for sequences template <typename Sequence, typename MapFunctor> void blockingMap(Sequence &sequence, MapFunctor map) { - startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map)).startBlocking(); + startMap(sequence.begin(), sequence.end(), map).startBlocking(); } // blockingMap() for iterator ranges template <typename Iterator, typename MapFunctor> void blockingMap(Iterator begin, Iterator end, MapFunctor map) { - startMap(begin, end, QtPrivate::createFunctionWrapper(map)).startBlocking(); + startMap(begin, end, map).startBlocking(); } // blockingMappedReduced() for sequences @@ -222,10 +224,10 @@ ResultType blockingMappedReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + return QtConcurrent::startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType> (sequence, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options) .startBlocking(); } @@ -239,9 +241,9 @@ ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, Reduc | SequentialReduce)) { return QtConcurrent::startMappedReduced< - typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>( - sequence, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>( + sequence, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -252,10 +254,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + return QtConcurrent::startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, + typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options) .startBlocking(); } @@ -270,10 +273,10 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { return QtConcurrent::startMappedReduced< - typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, + QtPrivate::MapResultType<Sequence, MapFunctor>, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>( - sequence, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + sequence, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -286,10 +289,10 @@ ResultType blockingMappedReduced(Iterator begin, ReduceFunctor reduce, QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + return QtConcurrent::startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType> (begin, end, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options) .startBlocking(); } @@ -304,9 +307,9 @@ ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor map, R | QtConcurrent::SequentialReduce)) { return QtConcurrent::startMappedReduced< - typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>( - begin, end, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>( + begin, end, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -318,10 +321,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe ReduceFunctor reduce, QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + return QtConcurrent::startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, + typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (begin, end, - QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + map, + reduce, options) .startBlocking(); } @@ -337,10 +341,10 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) { return QtConcurrent::startMappedReduced< - typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, + QtPrivate::MapResultType<Iterator, MapFunctor>, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>( - begin, end, QtPrivate::createFunctionWrapper(map), - QtPrivate::createFunctionWrapper(reduce), + begin, end, map, + reduce, ResultType(std::forward<InitialValueType>(initialValue)), options) .startBlocking(); } @@ -351,18 +355,18 @@ OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) { return blockingMappedReduced<OutputSequence> (sequence, - QtPrivate::createFunctionWrapper(map), + map, QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } template <typename MapFunctor, typename InputSequence> -typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType blockingMapped(const InputSequence &sequence, MapFunctor map) +auto blockingMapped(const InputSequence &sequence, MapFunctor map) { - typedef typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType OutputSequence; + using OutputSequence = typename QtPrivate::MapSequenceResultType<InputSequence, MapFunctor>::ResultType; return blockingMappedReduced<OutputSequence> (sequence, - QtPrivate::createFunctionWrapper(map), + map, QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -373,18 +377,18 @@ Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map) { return blockingMappedReduced<Sequence> (begin, end, - QtPrivate::createFunctionWrapper(map), + map, QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } template <typename Iterator, typename MapFunctor> -typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType blockingMapped(Iterator begin, Iterator end, MapFunctor map) +auto blockingMapped(Iterator begin, Iterator end, MapFunctor map) { - typedef typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType OutputSequence; + using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>; return blockingMappedReduced<OutputSequence> (begin, end, - QtPrivate::createFunctionWrapper(map), + map, QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h index 3de275a192..346ffbfc7f 100644 --- a/src/concurrent/qtconcurrentmapkernel.h +++ b/src/concurrent/qtconcurrentmapkernel.h @@ -46,6 +46,7 @@ #include <QtConcurrent/qtconcurrentiteratekernel.h> #include <QtConcurrent/qtconcurrentreducekernel.h> +#include <QtConcurrent/qtconcurrentfunctionwrappers.h> QT_BEGIN_NAMESPACE @@ -65,7 +66,7 @@ public: bool runIteration(Iterator it, int, void *) override { - map(*it); + std::invoke(map, *it); return false; } @@ -88,13 +89,15 @@ template <typename ReducedResultType, typename ReduceFunctor, typename Reducer = ReduceKernel<ReduceFunctor, ReducedResultType, - typename MapFunctor::result_type> > + QtPrivate::MapResultType<Iterator, MapFunctor>>> class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType> { ReducedResultType reducedResult; MapFunctor map; ReduceFunctor reduce; Reducer reducer; + using IntermediateResultsType = QtPrivate::MapResultType<Iterator, MapFunctor>; + public: typedef ReducedResultType ReturnType; MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions) @@ -113,18 +116,18 @@ public: bool runIteration(Iterator it, int index, ReducedResultType *) override { - IntermediateResults<typename MapFunctor::result_type> results; + IntermediateResults<IntermediateResultsType> results; results.begin = index; results.end = index + 1; - results.vector.append(map(*it)); + results.vector.append(std::invoke(map, *it)); reducer.runReduce(reduce, reducedResult, results); return false; } bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override { - IntermediateResults<typename MapFunctor::result_type> results; + IntermediateResults<IntermediateResultsType> results; results.begin = beginIndex; results.end = endIndex; results.vector.reserve(endIndex - beginIndex); @@ -132,7 +135,7 @@ public: Iterator it = sequenceBeginIterator; std::advance(it, beginIndex); for (int i = beginIndex; i < endIndex; ++i) { - results.vector.append(map(*(it))); + results.vector.append(std::invoke(map, *it)); std::advance(it, 1); } @@ -163,20 +166,18 @@ public: }; template <typename Iterator, typename MapFunctor> -class MappedEachKernel : public IterateKernel<Iterator, typename MapFunctor::result_type> +class MappedEachKernel : public IterateKernel<Iterator, QtPrivate::MapResultType<Iterator, MapFunctor>> { MapFunctor map; - typedef typename MapFunctor::result_type T; -public: - typedef T ReturnType; - typedef T ResultType; + using T = QtPrivate::MapResultType<Iterator, MapFunctor>; +public: MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map) : IterateKernel<Iterator, T>(begin, end), map(_map) { } bool runIteration(Iterator it, int, T *result) override { - *result = map(*it); + *result = std::invoke(map, *it); return true; } diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index eabc432374..a487ec26a2 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -124,7 +124,7 @@ class ReduceKernel const IntermediateResults<T> &result) { for (int i = 0; i < result.vector.size(); ++i) { - reduce(r, result.vector.at(i)); + std::invoke(reduce, r, result.vector.at(i)); } } |