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>
This commit is contained in:
parent
678b9f78a5
commit
786b48878f
@ -158,8 +158,6 @@ struct StartsWith
|
|||||||
StartsWith(const QString &string)
|
StartsWith(const QString &string)
|
||||||
: m_string(string) { }
|
: m_string(string) { }
|
||||||
|
|
||||||
typedef bool result_type;
|
|
||||||
|
|
||||||
bool operator()(const QString &testString)
|
bool operator()(const QString &testString)
|
||||||
{
|
{
|
||||||
return testString.startsWith(m_string);
|
return testString.startsWith(m_string);
|
||||||
@ -183,3 +181,57 @@ QFuture<QString> fooString =
|
|||||||
StartsWith(QLatin1String("Foo")),
|
StartsWith(QLatin1String("Foo")),
|
||||||
StringTransform());
|
StringTransform());
|
||||||
//! [14]
|
//! [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]
|
||||||
|
@ -130,7 +130,8 @@ QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);
|
|||||||
|
|
||||||
// Swap the rgb values of all pixels on a list of images.
|
// Swap the rgb values of all pixels on a list of images.
|
||||||
QList<QImage> 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.
|
// Create a set of the lengths of all strings in a list.
|
||||||
QStringList strings = ...;
|
QStringList strings = ...;
|
||||||
@ -197,3 +198,37 @@ struct Scaled
|
|||||||
QList<QImage> images = ...;
|
QList<QImage> images = ...;
|
||||||
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));
|
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));
|
||||||
//! [14]
|
//! [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]
|
||||||
|
@ -48,16 +48,26 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
namespace QtPrivate {
|
namespace QtPrivate {
|
||||||
|
|
||||||
|
template <class T, typename = void>
|
||||||
|
struct IsIterable : std::false_type {};
|
||||||
template <class T>
|
template <class T>
|
||||||
class HasResultType {
|
struct IsIterable<T, std::void_t<decltype(std::begin(std::declval<T>())),
|
||||||
typedef char Yes;
|
decltype(std::end(std::declval<T>()))>>
|
||||||
typedef void *No;
|
: std::true_type
|
||||||
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>
|
||||||
|
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
|
QT_END_NAMESPACE
|
||||||
|
@ -144,8 +144,7 @@
|
|||||||
QtConcurrent::filter(), QtConcurrent::filtered(), and
|
QtConcurrent::filter(), QtConcurrent::filtered(), and
|
||||||
QtConcurrent::filteredReduced() accept function objects
|
QtConcurrent::filteredReduced() accept function objects
|
||||||
for the filter function. These function objects can be used to
|
for the filter function. These function objects can be used to
|
||||||
add state to a function call. The result_type typedef must define the
|
add state to a function call:
|
||||||
result type of the function call operator:
|
|
||||||
|
|
||||||
\snippet code/src_concurrent_qtconcurrentfilter.cpp 13
|
\snippet code/src_concurrent_qtconcurrentfilter.cpp 13
|
||||||
|
|
||||||
@ -155,6 +154,26 @@
|
|||||||
|
|
||||||
\snippet code/src_concurrent_qtconcurrentfilter.cpp 14
|
\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
|
\section2 Wrapping Functions that Take Multiple Arguments
|
||||||
|
|
||||||
If you want to use a filter function takes more than one argument, you can
|
If you want to use a filter function takes more than one argument, you can
|
||||||
|
@ -63,7 +63,7 @@ ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, R
|
|||||||
template <typename Sequence, typename KeepFunctor>
|
template <typename Sequence, typename KeepFunctor>
|
||||||
QFuture<void> filter(Sequence &sequence, KeepFunctor keep)
|
QFuture<void> filter(Sequence &sequence, KeepFunctor keep)
|
||||||
{
|
{
|
||||||
return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper());
|
return filterInternal(sequence, keep, QtPrivate::PushBackWrapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
// filteredReduced() on sequences
|
// filteredReduced() on sequences
|
||||||
@ -73,7 +73,7 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
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,
|
template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
|
||||||
@ -85,8 +85,8 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep,
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(keep),
|
sequence, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +99,8 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere
|
|||||||
{
|
{
|
||||||
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor keep,
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(keep),
|
sequence, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -128,7 +128,7 @@ QFuture<ResultType> filteredReduced(Iterator begin,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
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,
|
template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
|
||||||
@ -140,8 +140,8 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(keep),
|
begin, end, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,8 +155,8 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filtere
|
|||||||
{
|
{
|
||||||
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +170,8 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(keep),
|
begin, end, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -180,21 +180,21 @@ QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor ke
|
|||||||
template <typename Sequence, typename KeepFunctor>
|
template <typename Sequence, typename KeepFunctor>
|
||||||
QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor keep)
|
QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor keep)
|
||||||
{
|
{
|
||||||
return startFiltered(sequence, QtPrivate::createFunctionWrapper(keep));
|
return startFiltered(sequence, keep);
|
||||||
}
|
}
|
||||||
|
|
||||||
// filtered() on iterators
|
// filtered() on iterators
|
||||||
template <typename Iterator, typename KeepFunctor>
|
template <typename Iterator, typename KeepFunctor>
|
||||||
QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep)
|
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
|
// blocking filter() on sequences
|
||||||
template <typename Sequence, typename KeepFunctor>
|
template <typename Sequence, typename KeepFunctor>
|
||||||
void blockingFilter(Sequence &sequence, KeepFunctor keep)
|
void blockingFilter(Sequence &sequence, KeepFunctor keep)
|
||||||
{
|
{
|
||||||
filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking();
|
filterInternal(sequence, keep, QtPrivate::PushBackWrapper()).startBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
// blocking filteredReduced() on sequences
|
// blocking filteredReduced() on sequences
|
||||||
@ -204,7 +204,7 @@ ResultType blockingFilteredReduced(const Sequence &sequence,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options)
|
return startFilteredReduced<ResultType>(sequence, keep, reduce, options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,8 +217,8 @@ ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, R
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(keep),
|
sequence, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -230,11 +230,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return blockingFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options).startBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
|
template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
|
||||||
@ -246,10 +246,11 @@ ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor keep, R
|
|||||||
ReduceOptions options = ReduceOptions(UnorderedReduce
|
ReduceOptions options = ReduceOptions(UnorderedReduce
|
||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return blockingFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(keep),
|
sequence, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
|
.startBlocking();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -263,8 +264,8 @@ ResultType blockingFilteredReduced(Iterator begin,
|
|||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>
|
return startFilteredReduced<ResultType>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -278,8 +279,8 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(keep),
|
begin, end, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -294,8 +295,8 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered
|
|||||||
{
|
{
|
||||||
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -310,8 +311,8 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startFilteredReduced<ResultType>(
|
return startFilteredReduced<ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(keep),
|
begin, end, keep,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -321,7 +322,7 @@ ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor kee
|
|||||||
template <typename Sequence, typename KeepFunctor>
|
template <typename Sequence, typename KeepFunctor>
|
||||||
Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep)
|
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
|
// blocking filtered() on iterators
|
||||||
@ -329,7 +330,7 @@ template <typename OutputSequence, typename Iterator, typename KeepFunctor>
|
|||||||
OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep)
|
OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep)
|
||||||
{
|
{
|
||||||
return startFilteredReduced<OutputSequence>(begin, end,
|
return startFilteredReduced<OutputSequence>(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(keep),
|
keep,
|
||||||
QtPrivate::PushBackWrapper(),
|
QtPrivate::PushBackWrapper(),
|
||||||
OrderedReduce).startBlocking();
|
OrderedReduce).startBlocking();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ class FilterKernel : public IterateKernel<typename Sequence::const_iterator, voi
|
|||||||
{
|
{
|
||||||
typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
|
typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
|
||||||
typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
|
typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
|
||||||
typedef typename ReduceFunctor::result_type T;
|
typedef void T;
|
||||||
|
|
||||||
Sequence reducedResult;
|
Sequence reducedResult;
|
||||||
Sequence &sequence;
|
Sequence &sequence;
|
||||||
@ -101,7 +101,7 @@ public:
|
|||||||
results.begin = index;
|
results.begin = index;
|
||||||
results.end = index + 1;
|
results.end = index + 1;
|
||||||
|
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
results.vector.append(*it);
|
results.vector.append(*it);
|
||||||
|
|
||||||
reducer.runReduce(reduce, reducedResult, results);
|
reducer.runReduce(reduce, reducedResult, results);
|
||||||
@ -119,7 +119,7 @@ public:
|
|||||||
typename Sequence::const_iterator it = sequenceBeginIterator;
|
typename Sequence::const_iterator it = sequenceBeginIterator;
|
||||||
std::advance(it, begin);
|
std::advance(it, begin);
|
||||||
for (int i = begin; i < end; ++i) {
|
for (int i = begin; i < end; ++i) {
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
results.vector.append(*it);
|
results.vector.append(*it);
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ public:
|
|||||||
results.begin = index;
|
results.begin = index;
|
||||||
results.end = index + 1;
|
results.end = index + 1;
|
||||||
|
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
results.vector.append(*it);
|
results.vector.append(*it);
|
||||||
|
|
||||||
reducer.runReduce(reduce, reducedResult, results);
|
reducer.runReduce(reduce, reducedResult, results);
|
||||||
@ -206,7 +206,7 @@ public:
|
|||||||
Iterator it = sequenceBeginIterator;
|
Iterator it = sequenceBeginIterator;
|
||||||
std::advance(it, begin);
|
std::advance(it, begin);
|
||||||
for (int i = begin; i < end; ++i) {
|
for (int i = begin; i < end; ++i) {
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
results.vector.append(*it);
|
results.vector.append(*it);
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ public:
|
|||||||
|
|
||||||
bool runIteration(Iterator it, int index, T *) override
|
bool runIteration(Iterator it, int index, T *) override
|
||||||
{
|
{
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
this->reportResult(&(*it), index);
|
this->reportResult(&(*it), index);
|
||||||
else
|
else
|
||||||
this->reportResult(nullptr, index);
|
this->reportResult(nullptr, index);
|
||||||
@ -282,7 +282,7 @@ public:
|
|||||||
Iterator it = sequenceBeginIterator;
|
Iterator it = sequenceBeginIterator;
|
||||||
std::advance(it, begin);
|
std::advance(it, begin);
|
||||||
for (int i = begin; i < end; ++i) {
|
for (int i = begin; i < end; ++i) {
|
||||||
if (keep(*it))
|
if (std::invoke(keep, *it))
|
||||||
results.vector.append(*it);
|
results.vector.append(*it);
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
}
|
}
|
||||||
|
@ -43,148 +43,16 @@
|
|||||||
#include <QtConcurrent/qtconcurrentcompilertest.h>
|
#include <QtConcurrent/qtconcurrentcompilertest.h>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
|
#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace QtConcurrent {
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
class FunctionWrapper1
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef T (*FunctionPointerType)(U u);
|
|
||||||
typedef T result_type;
|
|
||||||
inline FunctionWrapper1(FunctionPointerType _functionPointer)
|
|
||||||
:functionPointer(_functionPointer) { }
|
|
||||||
|
|
||||||
inline T operator()(U u)
|
|
||||||
{
|
|
||||||
return functionPointer(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)
|
|
||||||
{
|
|
||||||
return (c.*functionPointer)();
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename C>
|
|
||||||
class ConstMemberFunctionWrapper
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace QtConcurrent.
|
|
||||||
|
|
||||||
namespace QtPrivate {
|
namespace QtPrivate {
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
const T& createFunctionWrapper(const T& t)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename C>
|
|
||||||
QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() noexcept)
|
|
||||||
{
|
|
||||||
return QtConcurrent::MemberFunctionWrapper<T, C>(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 <typename T, typename C>
|
|
||||||
QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const noexcept)
|
|
||||||
{
|
|
||||||
return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct PushBackWrapper
|
struct PushBackWrapper
|
||||||
{
|
{
|
||||||
typedef void result_type;
|
|
||||||
|
|
||||||
template <class C, class U>
|
template <class C, class U>
|
||||||
inline void operator()(C &c, const U &u) const
|
inline void operator()(C &c, const U &u) const
|
||||||
{
|
{
|
||||||
@ -198,10 +66,41 @@ struct PushBackWrapper
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Functor, bool foo = HasResultType<Functor>::Value>
|
// -- MapResultType
|
||||||
struct LazyResultType { typedef typename Functor::result_type Type; };
|
|
||||||
template <typename Functor>
|
template <class T, class Enable = void>
|
||||||
struct LazyResultType<Functor, false> { typedef void Type; };
|
struct Argument
|
||||||
|
{
|
||||||
|
using Type = void;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Sequence>
|
||||||
|
struct Argument<Sequence, typename std::enable_if<IsIterableValue<Sequence>>::type>
|
||||||
|
{
|
||||||
|
using Type = std::decay_t<decltype(*std::begin(std::declval<Sequence>()))>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
struct Argument<Iterator, typename std::enable_if<IsDereferenceableValue<Iterator>>::type>
|
||||||
|
{
|
||||||
|
using Type = std::decay_t<decltype(*std::declval<Iterator>())>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using ArgumentType = typename Argument<T>::Type;
|
||||||
|
|
||||||
|
template <class T, class MapFunctor>
|
||||||
|
struct MapResult
|
||||||
|
{
|
||||||
|
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 <class T, class MapFunctor>
|
||||||
|
using MapResultType = typename MapResult<T, MapFunctor>::Type;
|
||||||
|
|
||||||
|
// -- ReduceResultType
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct ReduceResultType;
|
struct ReduceResultType;
|
||||||
@ -218,6 +117,18 @@ struct ReduceResultType<T(C::*)(U)>
|
|||||||
typedef C ResultType;
|
typedef C ResultType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class U, class V>
|
||||||
|
struct ReduceResultType<std::function<void(U&, V)>>
|
||||||
|
{
|
||||||
|
typedef U ResultType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R, typename ...A>
|
||||||
|
struct ReduceResultType<R(*)(A...)>
|
||||||
|
{
|
||||||
|
using ResultType = typename std::tuple_element<0, std::tuple<A...>>::type;
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
|
#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
|
||||||
template <class U, class V>
|
template <class U, class V>
|
||||||
struct ReduceResultType<void(*)(U&,V) noexcept>
|
struct ReduceResultType<void(*)(U&,V) noexcept>
|
||||||
@ -232,108 +143,27 @@ struct ReduceResultType<T(C::*)(U) noexcept>
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// -- MapSequenceResultType
|
||||||
|
|
||||||
template <class InputSequence, class MapFunctor>
|
template <class InputSequence, class MapFunctor>
|
||||||
struct MapResultType
|
struct MapSequenceResultType;
|
||||||
{
|
|
||||||
typedef typename LazyResultType<MapFunctor>::Type ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class U, class V>
|
template <class MapFunctor>
|
||||||
struct MapResultType<void, U (*)(V)>
|
struct MapSequenceResultType<QStringList, MapFunctor>
|
||||||
{
|
{
|
||||||
typedef U ResultType;
|
typedef QList<QtPrivate::MapResultType<QStringList, MapFunctor>> ResultType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class C>
|
|
||||||
struct MapResultType<void, T(C::*)() const>
|
|
||||||
{
|
|
||||||
typedef T ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
|
|
||||||
template <class U, class V>
|
|
||||||
struct MapResultType<void, U (*)(V) noexcept>
|
|
||||||
{
|
|
||||||
typedef U ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class C>
|
|
||||||
struct MapResultType<void, T(C::*)() const noexcept>
|
|
||||||
{
|
|
||||||
typedef T ResultType;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
|
#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS
|
||||||
|
|
||||||
template <template <typename> class InputSequence, typename MapFunctor, typename T>
|
template <template <typename> class InputSequence, typename MapFunctor, typename T>
|
||||||
struct MapResultType<InputSequence<T>, MapFunctor>
|
struct MapSequenceResultType<InputSequence<T>, MapFunctor>
|
||||||
{
|
{
|
||||||
typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType;
|
typedef InputSequence<QtPrivate::MapResultType<InputSequence<T>, MapFunctor>> ResultType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename> class InputSequence, class T, class U, class V>
|
|
||||||
struct MapResultType<InputSequence<T>, U (*)(V)>
|
|
||||||
{
|
|
||||||
typedef InputSequence<U> ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER
|
||||||
|
|
||||||
template <class MapFunctor>
|
|
||||||
struct MapResultType<QStringList, MapFunctor>
|
|
||||||
{
|
|
||||||
typedef QList<typename LazyResultType<MapFunctor>::Type> 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
|
|
||||||
|
|
||||||
template <class U, class V>
|
|
||||||
struct MapResultType<QStringList, U (*)(V) noexcept>
|
|
||||||
{
|
|
||||||
typedef QList<U> ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class U, class C>
|
|
||||||
struct MapResultType<QStringList, U(C::*)() const noexcept>
|
|
||||||
{
|
|
||||||
typedef QList<U> ResultType;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace QtPrivate.
|
} // namespace QtPrivate.
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,8 +270,7 @@
|
|||||||
QtConcurrent::map(), QtConcurrent::mapped(), and
|
QtConcurrent::map(), QtConcurrent::mapped(), and
|
||||||
QtConcurrent::mappedReduced() accept function objects
|
QtConcurrent::mappedReduced() accept function objects
|
||||||
for the map function. These function objects can be used to
|
for the map function. These function objects can be used to
|
||||||
add state to a function call. The result_type typedef must define the
|
add state to a function call:
|
||||||
result type of the function call operator:
|
|
||||||
|
|
||||||
\snippet code/src_concurrent_qtconcurrentmap.cpp 14
|
\snippet code/src_concurrent_qtconcurrentmap.cpp 14
|
||||||
|
|
||||||
@ -281,6 +280,26 @@
|
|||||||
|
|
||||||
\snippet code/src_concurrent_qtconcurrentmap.cpp 11
|
\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
|
\section2 Wrapping Functions that Take Multiple Arguments
|
||||||
|
|
||||||
If you want to use a map function that takes more than one argument you can
|
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
|
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
|
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
|
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
|
future with each mapped item as a result. You can use
|
||||||
@ -522,27 +541,3 @@
|
|||||||
|
|
||||||
\sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
|
\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
|
|
||||||
*/
|
|
||||||
|
@ -59,14 +59,14 @@ namespace QtConcurrent {
|
|||||||
template <typename Sequence, typename MapFunctor>
|
template <typename Sequence, typename MapFunctor>
|
||||||
QFuture<void> map(Sequence &sequence, MapFunctor map)
|
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
|
// map() on iterators
|
||||||
template <typename Iterator, typename MapFunctor>
|
template <typename Iterator, typename MapFunctor>
|
||||||
QFuture<void> map(Iterator begin, Iterator end, MapFunctor map)
|
QFuture<void> map(Iterator begin, Iterator end, MapFunctor map)
|
||||||
{
|
{
|
||||||
return startMap(begin, end, QtPrivate::createFunctionWrapper(map));
|
return startMap(begin, end, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mappedReduced() for sequences.
|
// mappedReduced() for sequences.
|
||||||
@ -76,10 +76,10 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
|
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,9 +91,9 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, Redu
|
|||||||
ReduceOptions options = ReduceOptions(UnorderedReduce
|
ReduceOptions options = ReduceOptions(UnorderedReduce
|
||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>,
|
||||||
ResultType>(sequence, QtPrivate::createFunctionWrapper(map),
|
ResultType>(sequence, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)),
|
ResultType(std::forward<InitialValueType>(initialValue)),
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
@ -104,10 +104,11 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
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,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +121,10 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor map, Redu
|
|||||||
ReduceOptions options = ReduceOptions(UnorderedReduce
|
ReduceOptions options = ReduceOptions(UnorderedReduce
|
||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>,
|
||||||
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(map),
|
sequence, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,10 +136,10 @@ QFuture<ResultType> mappedReduced(Iterator begin,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
|
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,9 +151,9 @@ QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, MapFunctor map,
|
|||||||
ReduceOptions options = ReduceOptions(UnorderedReduce
|
ReduceOptions options = ReduceOptions(UnorderedReduce
|
||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>,
|
||||||
ResultType>(begin, end, QtPrivate::createFunctionWrapper(map),
|
ResultType>(begin, end, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)),
|
ResultType(std::forward<InitialValueType>(initialValue)),
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
@ -164,10 +165,11 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
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,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,39 +182,39 @@ QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedR
|
|||||||
InitialValueType &&initialValue,
|
InitialValueType &&initialValue,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>,
|
||||||
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(map),
|
begin, end, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
ResultType(std::forward<InitialValueType>(initialValue)), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapped() for sequences
|
// mapped() for sequences
|
||||||
template <typename Sequence, typename MapFunctor>
|
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.
|
// mapped() for iterator ranges.
|
||||||
template <typename Iterator, typename MapFunctor>
|
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
|
// blockingMap() for sequences
|
||||||
template <typename Sequence, typename MapFunctor>
|
template <typename Sequence, typename MapFunctor>
|
||||||
void blockingMap(Sequence &sequence, MapFunctor map)
|
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
|
// blockingMap() for iterator ranges
|
||||||
template <typename Iterator, typename MapFunctor>
|
template <typename Iterator, typename MapFunctor>
|
||||||
void blockingMap(Iterator begin, Iterator end, MapFunctor map)
|
void blockingMap(Iterator begin, Iterator end, MapFunctor map)
|
||||||
{
|
{
|
||||||
startMap(begin, end, QtPrivate::createFunctionWrapper(map)).startBlocking();
|
startMap(begin, end, map).startBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
// blockingMappedReduced() for sequences
|
// blockingMappedReduced() for sequences
|
||||||
@ -222,10 +224,10 @@ ResultType blockingMappedReduced(const Sequence &sequence,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>
|
return QtConcurrent::startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -239,9 +241,9 @@ ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, Reduc
|
|||||||
| SequentialReduce))
|
| SequentialReduce))
|
||||||
{
|
{
|
||||||
return QtConcurrent::startMappedReduced<
|
return QtConcurrent::startMappedReduced<
|
||||||
typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>(
|
QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(map),
|
sequence, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -252,10 +254,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
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,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -270,10 +273,10 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
|
|||||||
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce))
|
||||||
{
|
{
|
||||||
return QtConcurrent::startMappedReduced<
|
return QtConcurrent::startMappedReduced<
|
||||||
typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
QtPrivate::MapResultType<Sequence, MapFunctor>,
|
||||||
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
||||||
sequence, QtPrivate::createFunctionWrapper(map),
|
sequence, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -286,10 +289,10 @@ ResultType blockingMappedReduced(Iterator begin,
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
|
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,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -304,9 +307,9 @@ ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor map, R
|
|||||||
| QtConcurrent::SequentialReduce))
|
| QtConcurrent::SequentialReduce))
|
||||||
{
|
{
|
||||||
return QtConcurrent::startMappedReduced<
|
return QtConcurrent::startMappedReduced<
|
||||||
typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType>(
|
QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(map),
|
begin, end, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -318,10 +321,11 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
|
|||||||
ReduceFunctor reduce,
|
ReduceFunctor reduce,
|
||||||
QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
|
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,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
options)
|
options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -337,10 +341,10 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedRe
|
|||||||
QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
|
QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
|
||||||
{
|
{
|
||||||
return QtConcurrent::startMappedReduced<
|
return QtConcurrent::startMappedReduced<
|
||||||
typename QtPrivate::MapResultType<void, MapFunctor>::ResultType,
|
QtPrivate::MapResultType<Iterator, MapFunctor>,
|
||||||
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>(
|
||||||
begin, end, QtPrivate::createFunctionWrapper(map),
|
begin, end, map,
|
||||||
QtPrivate::createFunctionWrapper(reduce),
|
reduce,
|
||||||
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
ResultType(std::forward<InitialValueType>(initialValue)), options)
|
||||||
.startBlocking();
|
.startBlocking();
|
||||||
}
|
}
|
||||||
@ -351,18 +355,18 @@ OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map)
|
|||||||
{
|
{
|
||||||
return blockingMappedReduced<OutputSequence>
|
return blockingMappedReduced<OutputSequence>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::PushBackWrapper(),
|
QtPrivate::PushBackWrapper(),
|
||||||
QtConcurrent::OrderedReduce);
|
QtConcurrent::OrderedReduce);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename MapFunctor, typename InputSequence>
|
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>
|
return blockingMappedReduced<OutputSequence>
|
||||||
(sequence,
|
(sequence,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::PushBackWrapper(),
|
QtPrivate::PushBackWrapper(),
|
||||||
QtConcurrent::OrderedReduce);
|
QtConcurrent::OrderedReduce);
|
||||||
}
|
}
|
||||||
@ -373,18 +377,18 @@ Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map)
|
|||||||
{
|
{
|
||||||
return blockingMappedReduced<Sequence>
|
return blockingMappedReduced<Sequence>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::PushBackWrapper(),
|
QtPrivate::PushBackWrapper(),
|
||||||
QtConcurrent::OrderedReduce);
|
QtConcurrent::OrderedReduce);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator, typename MapFunctor>
|
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>
|
return blockingMappedReduced<OutputSequence>
|
||||||
(begin, end,
|
(begin, end,
|
||||||
QtPrivate::createFunctionWrapper(map),
|
map,
|
||||||
QtPrivate::PushBackWrapper(),
|
QtPrivate::PushBackWrapper(),
|
||||||
QtConcurrent::OrderedReduce);
|
QtConcurrent::OrderedReduce);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include <QtConcurrent/qtconcurrentiteratekernel.h>
|
#include <QtConcurrent/qtconcurrentiteratekernel.h>
|
||||||
#include <QtConcurrent/qtconcurrentreducekernel.h>
|
#include <QtConcurrent/qtconcurrentreducekernel.h>
|
||||||
|
#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ public:
|
|||||||
|
|
||||||
bool runIteration(Iterator it, int, void *) override
|
bool runIteration(Iterator it, int, void *) override
|
||||||
{
|
{
|
||||||
map(*it);
|
std::invoke(map, *it);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +89,15 @@ template <typename ReducedResultType,
|
|||||||
typename ReduceFunctor,
|
typename ReduceFunctor,
|
||||||
typename Reducer = ReduceKernel<ReduceFunctor,
|
typename Reducer = ReduceKernel<ReduceFunctor,
|
||||||
ReducedResultType,
|
ReducedResultType,
|
||||||
typename MapFunctor::result_type> >
|
QtPrivate::MapResultType<Iterator, MapFunctor>>>
|
||||||
class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
|
class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
|
||||||
{
|
{
|
||||||
ReducedResultType reducedResult;
|
ReducedResultType reducedResult;
|
||||||
MapFunctor map;
|
MapFunctor map;
|
||||||
ReduceFunctor reduce;
|
ReduceFunctor reduce;
|
||||||
Reducer reducer;
|
Reducer reducer;
|
||||||
|
using IntermediateResultsType = QtPrivate::MapResultType<Iterator, MapFunctor>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ReducedResultType ReturnType;
|
typedef ReducedResultType ReturnType;
|
||||||
MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions)
|
MappedReducedKernel(Iterator begin, Iterator end, MapFunctor _map, ReduceFunctor _reduce, ReduceOptions reduceOptions)
|
||||||
@ -113,18 +116,18 @@ public:
|
|||||||
|
|
||||||
bool runIteration(Iterator it, int index, ReducedResultType *) override
|
bool runIteration(Iterator it, int index, ReducedResultType *) override
|
||||||
{
|
{
|
||||||
IntermediateResults<typename MapFunctor::result_type> results;
|
IntermediateResults<IntermediateResultsType> results;
|
||||||
results.begin = index;
|
results.begin = index;
|
||||||
results.end = index + 1;
|
results.end = index + 1;
|
||||||
|
|
||||||
results.vector.append(map(*it));
|
results.vector.append(std::invoke(map, *it));
|
||||||
reducer.runReduce(reduce, reducedResult, results);
|
reducer.runReduce(reduce, reducedResult, results);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
|
bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
|
||||||
{
|
{
|
||||||
IntermediateResults<typename MapFunctor::result_type> results;
|
IntermediateResults<IntermediateResultsType> results;
|
||||||
results.begin = beginIndex;
|
results.begin = beginIndex;
|
||||||
results.end = endIndex;
|
results.end = endIndex;
|
||||||
results.vector.reserve(endIndex - beginIndex);
|
results.vector.reserve(endIndex - beginIndex);
|
||||||
@ -132,7 +135,7 @@ public:
|
|||||||
Iterator it = sequenceBeginIterator;
|
Iterator it = sequenceBeginIterator;
|
||||||
std::advance(it, beginIndex);
|
std::advance(it, beginIndex);
|
||||||
for (int i = beginIndex; i < endIndex; ++i) {
|
for (int i = beginIndex; i < endIndex; ++i) {
|
||||||
results.vector.append(map(*(it)));
|
results.vector.append(std::invoke(map, *it));
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,20 +166,18 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Iterator, typename MapFunctor>
|
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;
|
MapFunctor map;
|
||||||
typedef typename MapFunctor::result_type T;
|
using T = QtPrivate::MapResultType<Iterator, MapFunctor>;
|
||||||
public:
|
|
||||||
typedef T ReturnType;
|
|
||||||
typedef T ResultType;
|
|
||||||
|
|
||||||
|
public:
|
||||||
MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map)
|
MappedEachKernel(Iterator begin, Iterator end, MapFunctor _map)
|
||||||
: IterateKernel<Iterator, T>(begin, end), map(_map) { }
|
: IterateKernel<Iterator, T>(begin, end), map(_map) { }
|
||||||
|
|
||||||
bool runIteration(Iterator it, int, T *result) override
|
bool runIteration(Iterator it, int, T *result) override
|
||||||
{
|
{
|
||||||
*result = map(*it);
|
*result = std::invoke(map, *it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class ReduceKernel
|
|||||||
const IntermediateResults<T> &result)
|
const IntermediateResults<T> &result)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < result.vector.size(); ++i) {
|
for (int i = 0; i < result.vector.size(); ++i) {
|
||||||
reduce(r, result.vector.at(i));
|
std::invoke(reduce, r, result.vector.at(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,12 +38,16 @@ class tst_QtConcurrentFilter : public QObject
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void filter();
|
void filter();
|
||||||
|
void filterLambda();
|
||||||
void filtered();
|
void filtered();
|
||||||
|
void filteredLambda();
|
||||||
void filteredReduced();
|
void filteredReduced();
|
||||||
|
void filteredReduceLambda();
|
||||||
void resultAt();
|
void resultAt();
|
||||||
void incrementalResults();
|
void incrementalResults();
|
||||||
void noDetach();
|
void noDetach();
|
||||||
void stlContainers();
|
void stlContainers();
|
||||||
|
void stlContainersLambda();
|
||||||
void filteredReduceInitialValue();
|
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()
|
void tst_QtConcurrentFilter::filtered()
|
||||||
{
|
{
|
||||||
QList<int> list;
|
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()
|
void tst_QtConcurrentFilter::filteredReduced()
|
||||||
{
|
{
|
||||||
QList<int> list;
|
QList<int> list;
|
||||||
@ -728,7 +806,221 @@ void tst_QtConcurrentFilter::filteredReduced()
|
|||||||
numberSumReduce);
|
numberSumReduce);
|
||||||
QCOMPARE(sum, 6);
|
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)
|
bool filterfn(int i)
|
||||||
@ -857,6 +1149,57 @@ void tst_QtConcurrentFilter::stlContainers()
|
|||||||
QCOMPARE(*list2.begin(), 1);
|
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()
|
void tst_QtConcurrentFilter::filteredReduceInitialValue()
|
||||||
{
|
{
|
||||||
// This test's the same as filteredReduce, but with an initial value on all calls
|
// This test's the same as filteredReduce, but with an initial value on all calls
|
||||||
|
@ -45,7 +45,9 @@ private slots:
|
|||||||
void mapped();
|
void mapped();
|
||||||
void blocking_mapped();
|
void blocking_mapped();
|
||||||
void mappedReduced();
|
void mappedReduced();
|
||||||
|
void mappedReducedLambda();
|
||||||
void blocking_mappedReduced();
|
void blocking_mappedReduced();
|
||||||
|
void blocking_mappedReducedLambda();
|
||||||
void assignResult();
|
void assignResult();
|
||||||
void functionOverloads();
|
void functionOverloads();
|
||||||
void noExceptFunctionOverloads();
|
void noExceptFunctionOverloads();
|
||||||
@ -55,6 +57,7 @@ private slots:
|
|||||||
void incrementalResults();
|
void incrementalResults();
|
||||||
void noDetach();
|
void noDetach();
|
||||||
void stlContainers();
|
void stlContainers();
|
||||||
|
void stlContainersLambda();
|
||||||
void qFutureAssignmentLeak();
|
void qFutureAssignmentLeak();
|
||||||
void stressTest();
|
void stressTest();
|
||||||
void persistentResultTest();
|
void persistentResultTest();
|
||||||
@ -240,6 +243,12 @@ void tst_QtConcurrentMap::blocking_map()
|
|||||||
QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6);
|
QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6);
|
||||||
QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2);
|
QtConcurrent::blockingMap(numberList.begin(), numberList.end(), &Number::multiplyBy2);
|
||||||
QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12);
|
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
|
// 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);
|
QCOMPARE(list, QList<int>() << 1 << 2 << 3);
|
||||||
QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable);
|
QtConcurrent::blockingMap(list.begin(), list.end(), multiplyBy2Immutable);
|
||||||
QCOMPARE(list, QList<int>() << 1 << 2 << 3);
|
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
|
#if 0
|
||||||
@ -317,8 +332,6 @@ int multiplyBy2(int x)
|
|||||||
class MultiplyBy2
|
class MultiplyBy2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef int result_type;
|
|
||||||
|
|
||||||
int operator()(int x) const
|
int operator()(int x) const
|
||||||
{
|
{
|
||||||
int y = x * 2;
|
int y = x * 2;
|
||||||
@ -334,8 +347,6 @@ double intToDouble(int x)
|
|||||||
class IntToDouble
|
class IntToDouble
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef double result_type;
|
|
||||||
|
|
||||||
double operator()(int x) const
|
double operator()(int x) const
|
||||||
{
|
{
|
||||||
return double(x);
|
return double(x);
|
||||||
@ -350,8 +361,6 @@ int stringToInt(const QString &string)
|
|||||||
class StringToInt
|
class StringToInt
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef int result_type;
|
|
||||||
|
|
||||||
int operator()(const QString &string) const
|
int operator()(const QString &string) const
|
||||||
{
|
{
|
||||||
return string.toInt();
|
return string.toInt();
|
||||||
@ -437,6 +446,32 @@ void tst_QtConcurrentMap::mapped()
|
|||||||
QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
|
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
|
// change the value_type, same container
|
||||||
|
|
||||||
// functor
|
// functor
|
||||||
@ -517,6 +552,33 @@ void tst_QtConcurrentMap::mapped()
|
|||||||
QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
|
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
|
// change the value_type
|
||||||
{
|
{
|
||||||
QList<QString> strings = QStringList() << "1" << "2" << "3";
|
QList<QString> strings = QStringList() << "1" << "2" << "3";
|
||||||
@ -551,6 +613,22 @@ void tst_QtConcurrentMap::mapped()
|
|||||||
QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
|
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
|
// change the value_type from QStringList
|
||||||
{
|
{
|
||||||
QStringList strings = QStringList() << "1" << "2" << "3";
|
QStringList strings = QStringList() << "1" << "2" << "3";
|
||||||
@ -574,6 +652,22 @@ void tst_QtConcurrentMap::mapped()
|
|||||||
.results();
|
.results();
|
||||||
QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
|
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()
|
void tst_QtConcurrentMap::blocking_mapped()
|
||||||
@ -652,6 +746,33 @@ void tst_QtConcurrentMap::blocking_mapped()
|
|||||||
QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
|
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
|
// change the value_type, same container
|
||||||
|
|
||||||
// functor
|
// functor
|
||||||
@ -727,6 +848,34 @@ void tst_QtConcurrentMap::blocking_mapped()
|
|||||||
QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
|
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
|
// change the value_type
|
||||||
{
|
{
|
||||||
QList<QString> strings = QStringList() << "1" << "2" << "3";
|
QList<QString> strings = QStringList() << "1" << "2" << "3";
|
||||||
@ -759,6 +908,23 @@ void tst_QtConcurrentMap::blocking_mapped()
|
|||||||
QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
|
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
|
// change the value_type from QStringList
|
||||||
{
|
{
|
||||||
QStringList strings = QStringList() << "1" << "2" << "3";
|
QStringList strings = QStringList() << "1" << "2" << "3";
|
||||||
@ -780,6 +946,23 @@ void tst_QtConcurrentMap::blocking_mapped()
|
|||||||
stringToInt);
|
stringToInt);
|
||||||
QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
|
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
|
// functor
|
||||||
{
|
{
|
||||||
@ -882,6 +1065,40 @@ void tst_QtConcurrentMap::blocking_mapped()
|
|||||||
QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
|
QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
|
||||||
#endif
|
#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)
|
int intSquare(int x)
|
||||||
@ -892,8 +1109,6 @@ int intSquare(int x)
|
|||||||
class IntSquare
|
class IntSquare
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef int result_type;
|
|
||||||
|
|
||||||
int operator()(int x)
|
int operator()(int x)
|
||||||
{
|
{
|
||||||
return x * 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()
|
void tst_QtConcurrentMap::blocking_mappedReduced()
|
||||||
{
|
{
|
||||||
QList<int> list;
|
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)
|
int sleeper(int val)
|
||||||
{
|
{
|
||||||
QTest::qSleep(100);
|
QTest::qSleep(100);
|
||||||
@ -1646,6 +2273,35 @@ void tst_QtConcurrentMap::stlContainers()
|
|||||||
QtConcurrent::blockingMap(list, multiplyBy2Immutable);
|
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)
|
InstanceCounter ic_fn(const InstanceCounter & ic)
|
||||||
{
|
{
|
||||||
return InstanceCounter(ic);
|
return InstanceCounter(ic);
|
||||||
@ -1730,7 +2386,6 @@ struct LockedCounter
|
|||||||
: mtx(mutex),
|
: mtx(mutex),
|
||||||
ref(ai) {}
|
ref(ai) {}
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
int operator()(int x)
|
int operator()(int x)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(mtx);
|
QMutexLocker locker(mtx);
|
||||||
|
@ -104,7 +104,6 @@ public:
|
|||||||
int member0() { return 10; }
|
int member0() { return 10; }
|
||||||
int member1(int in) { return in; }
|
int member1(int in) { return in; }
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
int operator()() { return 10; }
|
int operator()() { return 10; }
|
||||||
int operator()(int in) { return in; }
|
int operator()(int in) { return in; }
|
||||||
};
|
};
|
||||||
@ -115,7 +114,6 @@ public:
|
|||||||
int member0() const { return 10; }
|
int member0() const { return 10; }
|
||||||
int member1(int in) const { return in; }
|
int member1(int in) const { return in; }
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
int operator()() const { return 10; }
|
int operator()() const { return 10; }
|
||||||
int operator()(int in) const { return in; }
|
int operator()(int in) const { return in; }
|
||||||
};
|
};
|
||||||
@ -126,7 +124,6 @@ public:
|
|||||||
int member0() noexcept { return 10; }
|
int member0() noexcept { return 10; }
|
||||||
int member1(int in) noexcept { return in; }
|
int member1(int in) noexcept { return in; }
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
int operator()() noexcept { return 10; }
|
int operator()() noexcept { return 10; }
|
||||||
int operator()(int in) noexcept { return in; }
|
int operator()(int in) noexcept { return in; }
|
||||||
};
|
};
|
||||||
@ -137,7 +134,6 @@ public:
|
|||||||
int member0() const noexcept { return 10; }
|
int member0() const noexcept { return 10; }
|
||||||
int member1(int in) const noexcept { return in; }
|
int member1(int in) const noexcept { return in; }
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
int operator()() const noexcept { return 10; }
|
int operator()() const noexcept { return 10; }
|
||||||
int operator()(int in) const noexcept { return in; }
|
int operator()(int in) const noexcept { return in; }
|
||||||
};
|
};
|
||||||
@ -320,7 +316,6 @@ void tst_QtConcurrentRun::returnValue()
|
|||||||
struct TestClass
|
struct TestClass
|
||||||
{
|
{
|
||||||
void foo() { }
|
void foo() { }
|
||||||
typedef void result_type;
|
|
||||||
void operator()() { }
|
void operator()() { }
|
||||||
void operator()(int) { }
|
void operator()(int) { }
|
||||||
void fooInt(int){ };
|
void fooInt(int){ };
|
||||||
@ -329,7 +324,6 @@ struct TestClass
|
|||||||
struct TestConstClass
|
struct TestConstClass
|
||||||
{
|
{
|
||||||
void foo() const { }
|
void foo() const { }
|
||||||
typedef void result_type;
|
|
||||||
void operator()() const { }
|
void operator()() const { }
|
||||||
void operator()(int) const { }
|
void operator()(int) const { }
|
||||||
void fooInt(int) const { };
|
void fooInt(int) const { };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user