Fix perfect forwarding of callables in QFuture's continuations
Use universal references instead of rvalue references for passing callables in the implementations of QFuture's continuations. Change-Id: I1288c78f78f84f30c6607e505e7f9807a9272071 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> (cherry picked from commit b002722dabef794da0e80010b115b2c6cd6dc6b8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
a9ba5fe7aa
commit
bc46c7b8ea
@ -347,7 +347,7 @@ QFuture<typename QFuture<T>::template ResultType<Function>>
|
|||||||
QFuture<T>::then(QtFuture::Launch policy, Function &&function)
|
QFuture<T>::then(QtFuture::Launch policy, Function &&function)
|
||||||
{
|
{
|
||||||
QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
|
QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
|
||||||
QtPrivate::Continuation<Function, ResultType<Function>, T>::create(
|
QtPrivate::Continuation<std::decay_t<Function>, ResultType<Function>, T>::create(
|
||||||
std::forward<Function>(function), this, promise, policy);
|
std::forward<Function>(function), this, promise, policy);
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
@ -358,7 +358,7 @@ QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QTh
|
|||||||
Function &&function)
|
Function &&function)
|
||||||
{
|
{
|
||||||
QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
|
QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
|
||||||
QtPrivate::Continuation<Function, ResultType<Function>, T>::create(
|
QtPrivate::Continuation<std::decay_t<Function>, ResultType<Function>, T>::create(
|
||||||
std::forward<Function>(function), this, promise, pool);
|
std::forward<Function>(function), this, promise, pool);
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
@ -370,7 +370,8 @@ template<class Function, typename>
|
|||||||
QFuture<T> QFuture<T>::onFailed(Function &&handler)
|
QFuture<T> QFuture<T>::onFailed(Function &&handler)
|
||||||
{
|
{
|
||||||
QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
|
QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
|
||||||
QtPrivate::FailureHandler<Function, T>::create(std::forward<Function>(handler), this, promise);
|
QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
|
||||||
|
this, promise);
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +382,8 @@ template<class Function, typename>
|
|||||||
QFuture<T> QFuture<T>::onCanceled(Function &&handler)
|
QFuture<T> QFuture<T>::onCanceled(Function &&handler)
|
||||||
{
|
{
|
||||||
QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
|
QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
|
||||||
QtPrivate::CanceledHandler<Function, T>::create(std::forward<Function>(handler), this, promise);
|
QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
|
||||||
|
this, promise);
|
||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,20 +247,23 @@ template<typename Function, typename ResultType, typename ParentResultType>
|
|||||||
class Continuation
|
class Continuation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Continuation(Function &&func, const QFuture<ParentResultType> &f,
|
template<typename F = Function>
|
||||||
|
Continuation(F &&func, const QFuture<ParentResultType> &f,
|
||||||
const QFutureInterface<ResultType> &p)
|
const QFutureInterface<ResultType> &p)
|
||||||
: promise(p), parentFuture(f), function(std::forward<Function>(func))
|
: promise(p), parentFuture(f), function(std::forward<F>(func))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~Continuation() = default;
|
virtual ~Continuation() = default;
|
||||||
|
|
||||||
bool execute();
|
bool execute();
|
||||||
|
|
||||||
static void create(Function &&func, QFuture<ParentResultType> *f,
|
template<typename F = Function>
|
||||||
QFutureInterface<ResultType> &p, QtFuture::Launch policy);
|
static void create(F &&func, QFuture<ParentResultType> *f, QFutureInterface<ResultType> &p,
|
||||||
|
QtFuture::Launch policy);
|
||||||
|
|
||||||
static void create(Function &&func, QFuture<ParentResultType> *f,
|
template<typename F = Function>
|
||||||
QFutureInterface<ResultType> &p, QThreadPool *pool);
|
static void create(F &&func, QFuture<ParentResultType> *f, QFutureInterface<ResultType> &p,
|
||||||
|
QThreadPool *pool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fulfillPromiseWithResult();
|
void fulfillPromiseWithResult();
|
||||||
@ -285,9 +288,10 @@ template<typename Function, typename ResultType, typename ParentResultType>
|
|||||||
class SyncContinuation final : public Continuation<Function, ResultType, ParentResultType>
|
class SyncContinuation final : public Continuation<Function, ResultType, ParentResultType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SyncContinuation(Function &&func, const QFuture<ParentResultType> &f,
|
template<typename F = Function>
|
||||||
|
SyncContinuation(F &&func, const QFuture<ParentResultType> &f,
|
||||||
const QFutureInterface<ResultType> &p)
|
const QFutureInterface<ResultType> &p)
|
||||||
: Continuation<Function, ResultType, ParentResultType>(std::forward<Function>(func), f, p)
|
: Continuation<Function, ResultType, ParentResultType>(std::forward<F>(func), f, p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,9 +306,10 @@ class AsyncContinuation final : public QRunnable,
|
|||||||
public Continuation<Function, ResultType, ParentResultType>
|
public Continuation<Function, ResultType, ParentResultType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AsyncContinuation(Function &&func, const QFuture<ParentResultType> &f,
|
template<typename F = Function>
|
||||||
|
AsyncContinuation(F &&func, const QFuture<ParentResultType> &f,
|
||||||
const QFutureInterface<ResultType> &p, QThreadPool *pool = nullptr)
|
const QFutureInterface<ResultType> &p, QThreadPool *pool = nullptr)
|
||||||
: Continuation<Function, ResultType, ParentResultType>(std::forward<Function>(func), f, p),
|
: Continuation<Function, ResultType, ParentResultType>(std::forward<F>(func), f, p),
|
||||||
threadPool(pool)
|
threadPool(pool)
|
||||||
{
|
{
|
||||||
this->promise.setRunnable(this);
|
this->promise.setRunnable(this);
|
||||||
@ -334,12 +339,13 @@ template<class Function, class ResultType>
|
|||||||
class FailureHandler
|
class FailureHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void create(Function &&function, QFuture<ResultType> *future,
|
template<typename F = Function>
|
||||||
|
static void create(F &&function, QFuture<ResultType> *future,
|
||||||
const QFutureInterface<ResultType> &promise);
|
const QFutureInterface<ResultType> &promise);
|
||||||
|
|
||||||
FailureHandler(Function &&func, const QFuture<ResultType> &f,
|
template<typename F = Function>
|
||||||
const QFutureInterface<ResultType> &p)
|
FailureHandler(F &&func, const QFuture<ResultType> &f, const QFutureInterface<ResultType> &p)
|
||||||
: promise(p), parentFuture(f), handler(std::forward<Function>(func))
|
: promise(p), parentFuture(f), handler(std::forward<F>(func))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +444,8 @@ bool Continuation<Function, ResultType, ParentResultType>::execute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function, typename ResultType, typename ParentResultType>
|
template<typename Function, typename ResultType, typename ParentResultType>
|
||||||
void Continuation<Function, ResultType, ParentResultType>::create(Function &&func,
|
template<typename F>
|
||||||
|
void Continuation<Function, ResultType, ParentResultType>::create(F &&func,
|
||||||
QFuture<ParentResultType> *f,
|
QFuture<ParentResultType> *f,
|
||||||
QFutureInterface<ResultType> &p,
|
QFutureInterface<ResultType> &p,
|
||||||
QtFuture::Launch policy)
|
QtFuture::Launch policy)
|
||||||
@ -461,10 +468,10 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun
|
|||||||
Continuation<Function, ResultType, ParentResultType> *continuationJob = nullptr;
|
Continuation<Function, ResultType, ParentResultType> *continuationJob = nullptr;
|
||||||
if (launchAsync) {
|
if (launchAsync) {
|
||||||
continuationJob = new AsyncContinuation<Function, ResultType, ParentResultType>(
|
continuationJob = new AsyncContinuation<Function, ResultType, ParentResultType>(
|
||||||
std::forward<Function>(func), *f, p, pool);
|
std::forward<F>(func), *f, p, pool);
|
||||||
} else {
|
} else {
|
||||||
continuationJob = new SyncContinuation<Function, ResultType, ParentResultType>(
|
continuationJob = new SyncContinuation<Function, ResultType, ParentResultType>(
|
||||||
std::forward<Function>(func), *f, p);
|
std::forward<F>(func), *f, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setLaunchAsync(launchAsync);
|
p.setLaunchAsync(launchAsync);
|
||||||
@ -484,7 +491,8 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function, typename ResultType, typename ParentResultType>
|
template<typename Function, typename ResultType, typename ParentResultType>
|
||||||
void Continuation<Function, ResultType, ParentResultType>::create(Function &&func,
|
template<typename F>
|
||||||
|
void Continuation<Function, ResultType, ParentResultType>::create(F &&func,
|
||||||
QFuture<ParentResultType> *f,
|
QFuture<ParentResultType> *f,
|
||||||
QFutureInterface<ResultType> &p,
|
QFutureInterface<ResultType> &p,
|
||||||
QThreadPool *pool)
|
QThreadPool *pool)
|
||||||
@ -492,7 +500,7 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun
|
|||||||
Q_ASSERT(f);
|
Q_ASSERT(f);
|
||||||
|
|
||||||
auto continuationJob = new AsyncContinuation<Function, ResultType, ParentResultType>(
|
auto continuationJob = new AsyncContinuation<Function, ResultType, ParentResultType>(
|
||||||
std::forward<Function>(func), *f, p, pool);
|
std::forward<F>(func), *f, p, pool);
|
||||||
p.setLaunchAsync(true);
|
p.setLaunchAsync(true);
|
||||||
p.setThreadPool(pool);
|
p.setThreadPool(pool);
|
||||||
|
|
||||||
@ -571,13 +579,14 @@ void fulfillPromise(QFutureInterface<T> &promise, Function &&handler)
|
|||||||
#ifndef QT_NO_EXCEPTIONS
|
#ifndef QT_NO_EXCEPTIONS
|
||||||
|
|
||||||
template<class Function, class ResultType>
|
template<class Function, class ResultType>
|
||||||
void FailureHandler<Function, ResultType>::create(Function &&function, QFuture<ResultType> *future,
|
template<class F>
|
||||||
|
void FailureHandler<Function, ResultType>::create(F &&function, QFuture<ResultType> *future,
|
||||||
const QFutureInterface<ResultType> &promise)
|
const QFutureInterface<ResultType> &promise)
|
||||||
{
|
{
|
||||||
Q_ASSERT(future);
|
Q_ASSERT(future);
|
||||||
|
|
||||||
FailureHandler<Function, ResultType> *failureHandler = new FailureHandler<Function, ResultType>(
|
FailureHandler<Function, ResultType> *failureHandler =
|
||||||
std::forward<Function>(function), *future, promise);
|
new FailureHandler<Function, ResultType>(std::forward<F>(function), *future, promise);
|
||||||
|
|
||||||
auto failureContinuation = [failureHandler]() mutable {
|
auto failureContinuation = [failureHandler]() mutable {
|
||||||
failureHandler->run();
|
failureHandler->run();
|
||||||
@ -654,13 +663,14 @@ template<class Function, class ResultType>
|
|||||||
class CanceledHandler
|
class CanceledHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static QFuture<ResultType> create(Function &&handler, QFuture<ResultType> *future,
|
template<class F = Function>
|
||||||
|
static QFuture<ResultType> create(F &&handler, QFuture<ResultType> *future,
|
||||||
QFutureInterface<ResultType> promise)
|
QFutureInterface<ResultType> promise)
|
||||||
{
|
{
|
||||||
Q_ASSERT(future);
|
Q_ASSERT(future);
|
||||||
|
|
||||||
auto canceledContinuation = [parentFuture = *future, promise,
|
auto canceledContinuation = [parentFuture = *future, promise,
|
||||||
handler = std::move(handler)]() mutable {
|
handler = std::forward<F>(handler)]() mutable {
|
||||||
promise.reportStarted();
|
promise.reportStarted();
|
||||||
|
|
||||||
if (parentFuture.isCanceled()) {
|
if (parentFuture.isCanceled()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user