summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentfilter.cpp56
-rw-r--r--src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp37
-rw-r--r--src/concurrent/qtconcurrentcompilertest.h28
-rw-r--r--src/concurrent/qtconcurrentfilter.cpp23
-rw-r--r--src/concurrent/qtconcurrentfilter.h79
-rw-r--r--src/concurrent/qtconcurrentfilterkernel.h20
-rw-r--r--src/concurrent/qtconcurrentfunctionwrappers.h272
-rw-r--r--src/concurrent/qtconcurrentmap.cpp51
-rw-r--r--src/concurrent/qtconcurrentmap.h132
-rw-r--r--src/concurrent/qtconcurrentmapkernel.h25
-rw-r--r--src/concurrent/qtconcurrentreducekernel.h2
-rw-r--r--tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp343
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp675
-rw-r--r--tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp6
14 files changed, 1344 insertions, 405 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));
}
}
diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
index 1b52f52038..e89e5cf2e3 100644
--- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
+++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
@@ -38,12 +38,16 @@ class tst_QtConcurrentFilter : public QObject
private slots:
void filter();
+ void filterLambda();
void filtered();
+ void filteredLambda();
void filteredReduced();
+ void filteredReduceLambda();
void resultAt();
void incrementalResults();
void noDetach();
void stlContainers();
+ void stlContainersLambda();
void filteredReduceInitialValue();
};
@@ -118,6 +122,22 @@ void tst_QtConcurrentFilter::filter()
}
}
+void tst_QtConcurrentFilter::filterLambda()
+{
+ {
+ QList<Number> list;
+ list << 1 << 2 << 3 << 4;
+ QtConcurrent::filter(list, [](const Number &number) { return number.isEven(); }).waitForFinished();
+ QCOMPARE(list, QList<Number>() << 2 << 4);
+ }
+ {
+ QList<Number> list;
+ list << 1 << 2 << 3 << 4;
+ QtConcurrent::blockingFilter(list, [](const Number &number) { return number.isEven(); });
+ QCOMPARE(list, QList<Number>() << 2 << 4);
+ }
+}
+
void tst_QtConcurrentFilter::filtered()
{
QList<int> list;
@@ -292,6 +312,64 @@ void tst_QtConcurrentFilter::filtered()
}
}
+void tst_QtConcurrentFilter::filteredLambda()
+{
+ QList<int> list;
+ list << 1 << 2 << 3 << 4;
+
+ {
+ QFuture<int> f = QtConcurrent::filtered(list,
+ [](int x) {
+ return (x & 1) == 0;
+ }
+ );
+ QList<int> list2 = f.results();
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+ {
+ QFuture<int> f = QtConcurrent::filtered(list.begin(), list.end(),
+ [](const int &x) {
+ return (x & 1) == 0;
+ }
+ );
+ QList<int> list2 = f.results();
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+ {
+ QFuture<int> f = QtConcurrent::filtered(list.constBegin(), list.constEnd(),
+ [](const int &x) {
+ return (x & 1) == 0;
+ }
+ );
+ QList<int> list2 = f.results();
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFiltered(list,
+ [](const int &x) {
+ return (x & 1) == 0;
+ }
+ );
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFiltered<QList<int> >(list.begin(), list.end(),
+ [](const int &x) {
+ return (x & 1) == 0;
+ }
+ );
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+ {
+ QList<int> list2 = QtConcurrent::blockingFiltered<QList<int> >(list.constBegin(), list.constEnd(),
+ [](const int &x) {
+ return (x & 1) == 0;
+ }
+ );
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+ }
+}
+
void tst_QtConcurrentFilter::filteredReduced()
{
QList<int> list;
@@ -728,7 +806,221 @@ void tst_QtConcurrentFilter::filteredReduced()
numberSumReduce);
QCOMPARE(sum, 6);
}
+}
+
+void tst_QtConcurrentFilter::filteredReduceLambda()
+{
+ QList<int> list;
+ list << 1 << 2 << 3 << 4;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3 << 4;
+
+ // lambda-lambda
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list,
+ [](const int &x) {
+ return (x & 1) == 0;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(list,
+ [](const int &x) {
+ return (x & 1) == 0;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 6);
+ }
+ // lambda-functor
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list,
+ [](const int &x) {
+ return (x & 1) == 0;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(list,
+ [](const int &x) {
+ return (x & 1) == 0;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum2, 6);
+ }
+
+ // functor-lambda
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list,
+ KeepEvenIntegers(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::blockingFilteredReduced<int>(list,
+ KeepEvenIntegers(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 6);
+ }
+
+ // lambda-function
+ {
+ int sum = QtConcurrent::filteredReduced(list,
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::filteredReduced(list.begin(), list.end(),
+ [](const int &x) {
+ return (x & 1) == 0;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum2, 6);
+
+ int sum3 = QtConcurrent::blockingFilteredReduced(list,
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum3, 6);
+
+ int sum4 = QtConcurrent::blockingFilteredReduced(list.begin(), list.end(),
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum4, 6);
+ }
+
+ // function-lambda
+ {
+ int sum = QtConcurrent::filteredReduced<int>(list,
+ keepEvenIntegers,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(list.begin(), list.end(),
+ keepEvenIntegers,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 6);
+
+ int sum3 = QtConcurrent::blockingFilteredReduced<int>(list,
+ keepEvenIntegers,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 6);
+
+ int sum4 = QtConcurrent::blockingFilteredReduced<int>(list.begin(), list.end(),
+ keepEvenIntegers,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum4, 6);
+ }
+
+ // lambda-member
+ {
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+
+ QList<int> list2 = QtConcurrent::filteredReduced(list,
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ push_back,
+ QtConcurrent::OrderedReduce
+ );
+ QCOMPARE(list2, QList<int>() << 2 << 4);
+
+ QList<int> list3 = QtConcurrent::filteredReduced(list.begin(), list.end(),
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ push_back,
+ QtConcurrent::OrderedReduce
+ );
+ QCOMPARE(list3, QList<int>() << 2 << 4);
+
+ QList<int> list4 = QtConcurrent::blockingFilteredReduced(list,
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ push_back,
+ QtConcurrent::OrderedReduce
+ );
+ QCOMPARE(list4, QList<int>() << 2 << 4);
+
+ QList<int> list5 = QtConcurrent::blockingFilteredReduced(list.begin(), list.end(),
+ [] (const int &x) {
+ return (x & 1) == 0;
+ },
+ push_back,
+ QtConcurrent::OrderedReduce
+ );
+ QCOMPARE(list5, QList<int>() << 2 << 4);
+ }
+
+ // member-lambda
+ {
+ int sum = QtConcurrent::filteredReduced<int>(numberList,
+ &Number::isEven,
+ [](int &sum, const Number &x) {
+ sum += x.toInt();
+ }
+ );
+ QCOMPARE(sum, 6);
+
+ int sum2 = QtConcurrent::filteredReduced<int>(numberList.begin(), numberList.end(),
+ &Number::isEven,
+ [](int &sum, const Number &x) {
+ sum += x.toInt();
+ }
+ );
+ QCOMPARE(sum2, 6);
+
+ int sum3 = QtConcurrent::blockingFilteredReduced<int>(numberList,
+ &Number::isEven,
+ [](int &sum, const Number &x) {
+ sum += x.toInt();
+ }
+ );
+ QCOMPARE(sum3, 6);
+
+ int sum4 = QtConcurrent::blockingFilteredReduced<int>(numberList.begin(), numberList.end(),
+ &Number::isEven,
+ [](int &sum, const Number &x) {
+ sum += x.toInt();
+ }
+ );
+ QCOMPARE(sum4, 6);
+ }
}
bool filterfn(int i)
@@ -857,6 +1149,57 @@ void tst_QtConcurrentFilter::stlContainers()
QCOMPARE(*list2.begin(), 1);
}
+void tst_QtConcurrentFilter::stlContainersLambda()
+{
+ std::vector<int> vector;
+ vector.push_back(1);
+ vector.push_back(2);
+
+ std::vector<int> vector2 = QtConcurrent::blockingFiltered(vector,
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ );
+ QCOMPARE(vector2.size(), (std::vector<int>::size_type)(1));
+ QCOMPARE(vector2[0], 1);
+
+ std::list<int> list;
+ list.push_back(1);
+ list.push_back(2);
+
+ std::list<int> list2 = QtConcurrent::blockingFiltered(list,
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ );
+ QCOMPARE(list2.size(), (std::list<int>::size_type)(1));
+ QCOMPARE(*list2.begin(), 1);
+
+ QtConcurrent::filtered(list,
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ ).waitForFinished();
+ QtConcurrent::filtered(vector,
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ ).waitForFinished();
+ QtConcurrent::filtered(vector.begin(), vector.end(),
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ ).waitForFinished();
+
+ QtConcurrent::blockingFilter(list,
+ [](const int &i) {
+ return waitFilterfn(i);
+ }
+ );
+ QCOMPARE(list.size(), (std::list<int>::size_type)(1));
+ QCOMPARE(*list.begin(), 1);
+}
+
void tst_QtConcurrentFilter::filteredReduceInitialValue()
{
// This test's the same as filteredReduce, but with an initial value on all calls
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index 1a8978c7ea..85acc6f729 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -36,7 +36,7 @@
#include "functions.h"
-class tst_QtConcurrentMap: public QObject
+class tst_QtConcurrentMap : public QObject
{
Q_OBJECT
private slots:
@@ -45,7 +45,9 @@ private slots:
void mapped();
void blocking_mapped();
void mappedReduced();
+ void mappedReducedLambda();
void blocking_mappedReduced();
+ void blocking_mappedReducedLambda();
void assignResult();
void functionOverloads();
void noExceptFunctionOverloads();
@@ -55,6 +57,7 @@ private slots:
void incrementalResults();
void noDetach();
void stlContainers();
+ void stlContainersLambda();
void qFutureAssignmentLeak();
void stressTest();
void persistentResultTest();
@@ -240,6 +243,12 @@ void tst_QtConcurrentMap::blocking_map()
QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6);
QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2);
QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12);
+
+ // lambda
+ QtConcurrent::blockingMap(list, [](int &x) { x *= 2; });
+ QCOMPARE(list, QList<int>() << 128 << 256 << 384);
+ QtConcurrent::blockingMap(list.begin(), list.end(), [](int &x) { x *= 2; });
+ QCOMPARE(list, QList<int>() << 256 << 512 << 768);
}
// functors don't take arguments by reference, making these no-ops
@@ -264,6 +273,12 @@ void tst_QtConcurrentMap::blocking_map()
QCOMPARE(list, QList<int>() << 1 << 2 << 3);
QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable);
QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+
+ // lambda
+ QtConcurrent::blockingMap(list, [](int x) { x *= 2; });
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QtConcurrent::blockingMap(list.begin(), list.end(), [](int x) { x *= 2; });
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
}
#if 0
@@ -317,8 +332,6 @@ int multiplyBy2(int x)
class MultiplyBy2
{
public:
- typedef int result_type;
-
int operator()(int x) const
{
int y = x * 2;
@@ -334,8 +347,6 @@ double intToDouble(int x)
class IntToDouble
{
public:
- typedef double result_type;
-
double operator()(int x) const
{
return double(x);
@@ -350,8 +361,6 @@ int stringToInt(const QString &string)
class StringToInt
{
public:
- typedef int result_type;
-
int operator()(const QString &string) const
{
return string.toInt();
@@ -437,6 +446,32 @@ void tst_QtConcurrentMap::mapped()
QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
}
+ {
+ QList<Number> numberList2 = QtConcurrent::mapped(numberList,
+ [](const Number &num) {
+ return num.multipliedBy2();
+ }
+ ).results();
+ QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
+ QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6);
+
+ QList<Number> numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(),
+ [](const Number &num) {
+ return num.multipliedBy2();
+ }
+ ).results();
+ QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
+ QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6);
+
+ QList<Number> numberList4 = QtConcurrent::mapped(QList<Number>(numberList),
+ [](const Number &num) {
+ return num.multipliedBy2();
+ }
+ ).results();
+ QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
+ QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
+ }
+
// change the value_type, same container
// functor
@@ -517,6 +552,33 @@ void tst_QtConcurrentMap::mapped()
QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
}
+ // lambda
+ {
+ QList<double> list2 = QtConcurrent::mapped(list,
+ [](int x) {
+ return double(x);
+ }
+ ).results();
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
+
+ QList<double> list3 = QtConcurrent::mapped(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return double(x);
+ }
+ ).results();
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
+
+ QList<double> list4 = QtConcurrent::mapped(QList<int>(list),
+ [](int x) {
+ return double(x);
+ }
+ ).results();
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
+ }
+
// change the value_type
{
QList<QString> strings = QStringList() << "1" << "2" << "3";
@@ -551,6 +613,22 @@ void tst_QtConcurrentMap::mapped()
QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
}
+ {
+ QList<int> numberList2 = QtConcurrent::mapped(numberList,
+ [] (const Number number) {
+ return number.toInt();
+ }
+ ).results();
+ QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3);
+
+ QList<int> numberList3 = QtConcurrent::mapped(numberList.constBegin(), numberList.constEnd(),
+ [](const Number number) {
+ return number.toInt();
+ }
+ ).results();
+ QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
+ }
+
// change the value_type from QStringList
{
QStringList strings = QStringList() << "1" << "2" << "3";
@@ -574,6 +652,22 @@ void tst_QtConcurrentMap::mapped()
.results();
QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
}
+ {
+ QStringList strings = QStringList() << "1" << "2" << "3";
+ QList<int> list = QtConcurrent::mapped(strings,
+ [](const QString &string) {
+ return string.toInt();
+ }
+ ).results();
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+
+ QList<int> list2 = QtConcurrent::mapped(strings.constBegin(), strings.constEnd(),
+ [](const QString &string) {
+ return string.toInt();
+ }
+ ).results();
+ QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
+ }
}
void tst_QtConcurrentMap::blocking_mapped()
@@ -652,6 +746,33 @@ void tst_QtConcurrentMap::blocking_mapped()
QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
}
+ // lambda
+ {
+ QList<int> list2 = QtConcurrent::blockingMapped(list,
+ [](int x) {
+ return x * 2;
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
+
+ QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * 2;
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
+
+ QList<int> list4 = QtConcurrent::blockingMapped(QList<int>(list),
+ [](int x) {
+ return x * 2;
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
+ }
+
// change the value_type, same container
// functor
@@ -727,6 +848,34 @@ void tst_QtConcurrentMap::blocking_mapped()
QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
}
+ // lambda
+ {
+ QList<QString> list2 = QtConcurrent::blockingMapped<QList<QString> >(numberList,
+ [] (const Number &number) {
+ return number.toString();
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<QString>() << "1" << "2" << "3");
+
+ QList<QString> list3 = QtConcurrent::blockingMapped<QList<QString> >(numberList.constBegin(),
+ numberList.constEnd(),
+ [](const Number &number) {
+ return number.toString();
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<QString>() << "1" << "2" << "3");
+
+ QList<QString> list4 = QtConcurrent::blockingMapped<QList<QString> >(QList<Number>(numberList),
+ [](const Number &number) {
+ return number.toString();
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
+ }
+
// change the value_type
{
QList<QString> strings = QStringList() << "1" << "2" << "3";
@@ -759,6 +908,23 @@ void tst_QtConcurrentMap::blocking_mapped()
QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
}
+ {
+ QList<int> numberList2 = QtConcurrent::blockingMapped(numberList,
+ [] (const Number &number) {
+ return number.toInt();
+ }
+ );
+ QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3);
+
+ QList<int> numberList3 = QtConcurrent::blockingMapped<QList<int> >(numberList.constBegin(),
+ numberList.constEnd(),
+ [](const Number &number) {
+ return number.toInt();
+ }
+ );
+ QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
+ }
+
// change the value_type from QStringList
{
QStringList strings = QStringList() << "1" << "2" << "3";
@@ -780,6 +946,23 @@ void tst_QtConcurrentMap::blocking_mapped()
stringToInt);
QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
}
+ {
+ QStringList strings = QStringList() << "1" << "2" << "3";
+ QList<int> list = QtConcurrent::blockingMapped(strings,
+ [](const QString &string) {
+ return string.toInt();
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+
+ QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(strings.constBegin(),
+ strings.constEnd(),
+ [](const QString &string) {
+ return string.toInt();
+ }
+ );
+ QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
+ }
// functor
{
@@ -882,6 +1065,40 @@ void tst_QtConcurrentMap::blocking_mapped()
QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
#endif
}
+
+ // lambda
+ {
+ QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(list,
+ [](int x) {
+ return double(x);
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0);
+
+ QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(QList<int>(list),
+ [](int x) {
+ return double(x);
+ }
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0);
+
+ QStringList strings = QStringList() << "1" << "2" << "3";
+ QVector<int> list4 = QtConcurrent::blockingMapped<QVector<int> >(strings,
+ [](const QString &string) {
+ return string.toInt();
+ }
+ );
+ QCOMPARE(list4, QVector<int>() << 1 << 2 << 3);
+
+ QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings),
+ [](const QString &string) {
+ return string.toInt();
+ }
+ );
+ QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
+ }
}
int intSquare(int x)
@@ -892,8 +1109,6 @@ int intSquare(int x)
class IntSquare
{
public:
- typedef int result_type;
-
int operator()(int x)
{
return x * x;
@@ -1088,6 +1303,211 @@ void tst_QtConcurrentMap::mappedReduced()
}
}
+void tst_QtConcurrentMap::mappedReducedLambda()
+{
+ QList<int> list;
+ list << 1 << 2 << 3;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3;
+
+ // lambda-lambda
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list,
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-functor
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list,
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // functor-lambda
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list,
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), list.constEnd(),
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list),
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-function
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list,
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // function-lambda
+ {
+ int sum = QtConcurrent::mappedReduced<int>(list,
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::mappedReduced<int>(list.constBegin(), list.constEnd(),
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<int>(list),
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-member
+ {
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+
+ QList<int> list2 = QtConcurrent::mappedReduced(list,
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::mappedReduced(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::mappedReduced(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
+ }
+
+ // member-lambda
+ {
+ int sum = QtConcurrent::mappedReduced<int>(numberList,
+ &Number::toInt,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 6);
+ int sum2 = QtConcurrent::mappedReduced<int>(numberList.constBegin(), numberList.constEnd(),
+ &Number::toInt,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 6);
+
+ int sum3 = QtConcurrent::mappedReduced<int>(QList<Number>(numberList),
+ &Number::toInt,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 6);
+ }
+}
+
void tst_QtConcurrentMap::blocking_mappedReduced()
{
QList<int> list;
@@ -1273,6 +1693,213 @@ void tst_QtConcurrentMap::blocking_mappedReduced()
}
}
+void tst_QtConcurrentMap::blocking_mappedReducedLambda()
+{
+ QList<int> list;
+ list << 1 << 2 << 3;
+ QList<Number> numberList;
+ numberList << 1 << 2 << 3;
+
+ // lambda-lambda
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(list,
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-functor
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(list,
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ IntSumReduce()
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // functor-lambda
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(list,
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), list.constEnd(),
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list),
+ IntSquare(),
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-function
+ {
+ int sum = QtConcurrent::blockingMappedReduced(list,
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::blockingMappedReduced(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ intSumReduce
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // function-lambda
+ {
+ int sum = QtConcurrent::blockingMappedReduced<int>(list,
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum, 14);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(list.constBegin(), list.constEnd(),
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 14);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<int>(list),
+ intSquare,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 14);
+ }
+
+ // lambda-member
+ {
+ auto push_back = static_cast<void (QVector<int>::*)(const int &)>(&QVector<int>::push_back);
+
+ QList<int> list2 = QtConcurrent::blockingMappedReduced(list,
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
+
+ QList<int> list3 = QtConcurrent::blockingMappedReduced(list.constBegin(), list.constEnd(),
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
+
+ QList<int> list4 = QtConcurrent::blockingMappedReduced(QList<int>(list),
+ [](int x) {
+ return x * x;
+ },
+ push_back,
+ OrderedReduce
+ );
+ QCOMPARE(list, QList<int>() << 1 << 2 << 3);
+ QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
+ }
+
+ // member-lambda
+ {
+ std::function<void(int&, int)> sumRecuce = [](int &sum, int x) {
+ sum += x;
+ };
+
+ int sum = QtConcurrent::blockingMappedReduced(numberList,
+ &Number::toInt,
+ sumRecuce
+ );
+ QCOMPARE(sum, 6);
+ int sum2 = QtConcurrent::blockingMappedReduced<int>(numberList.constBegin(), numberList.constEnd(),
+ &Number::toInt,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum2, 6);
+
+ int sum3 = QtConcurrent::blockingMappedReduced<int>(QList<Number>(numberList),
+ &Number::toInt,
+ [](int &sum, int x) {
+ sum += x;
+ }
+ );
+ QCOMPARE(sum3, 6);
+ }
+}
+
int sleeper(int val)
{
QTest::qSleep(100);
@@ -1646,6 +2273,35 @@ void tst_QtConcurrentMap::stlContainers()
QtConcurrent::blockingMap(list, multiplyBy2Immutable);
}
+void tst_QtConcurrentMap::stlContainersLambda()
+{
+ std::vector<int> vector;
+ vector.push_back(1);
+ vector.push_back(2);
+
+ std::vector<int> vector2 = QtConcurrent::blockingMapped<std::vector<int> >(vector,
+ [](const int &i) {
+ return mapper(i);
+ }
+ );
+ QCOMPARE(vector2.size(), (std::vector<int>::size_type)(2));
+
+ std::list<int> list;
+ list.push_back(1);
+ list.push_back(2);
+
+ std::list<int> list2 = QtConcurrent::blockingMapped<std::list<int> >(list,
+ [](const int &i) {
+ return mapper(i);
+ }
+ );
+ QCOMPARE(list2.size(), (std::vector<int>::size_type)(2));
+
+ QtConcurrent::mapped(list, [](const int &i) { return mapper(i); }).waitForFinished();
+
+ QtConcurrent::blockingMap(list, [](int x) { x *= 2; });
+}
+
InstanceCounter ic_fn(const InstanceCounter & ic)
{
return InstanceCounter(ic);
@@ -1730,7 +2386,6 @@ struct LockedCounter
: mtx(mutex),
ref(ai) {}
- typedef int result_type;
int operator()(int x)
{
QMutexLocker locker(mtx);
diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
index c0782d8483..8f50329ec5 100644
--- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
+++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
@@ -104,7 +104,6 @@ public:
int member0() { return 10; }
int member1(int in) { return in; }
- typedef int result_type;
int operator()() { return 10; }
int operator()(int in) { return in; }
};
@@ -115,7 +114,6 @@ public:
int member0() const { return 10; }
int member1(int in) const { return in; }
- typedef int result_type;
int operator()() const { return 10; }
int operator()(int in) const { return in; }
};
@@ -126,7 +124,6 @@ public:
int member0() noexcept { return 10; }
int member1(int in) noexcept { return in; }
- typedef int result_type;
int operator()() noexcept { return 10; }
int operator()(int in) noexcept { return in; }
};
@@ -137,7 +134,6 @@ public:
int member0() const noexcept { return 10; }
int member1(int in) const noexcept { return in; }
- typedef int result_type;
int operator()() const noexcept { return 10; }
int operator()(int in) const noexcept { return in; }
};
@@ -320,7 +316,6 @@ void tst_QtConcurrentRun::returnValue()
struct TestClass
{
void foo() { }
- typedef void result_type;
void operator()() { }
void operator()(int) { }
void fooInt(int){ };
@@ -329,7 +324,6 @@ struct TestClass
struct TestConstClass
{
void foo() const { }
- typedef void result_type;
void operator()() const { }
void operator()(int) const { }
void fooInt(int) const { };