diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2020-11-29 20:46:02 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2020-12-01 08:12:09 +0000 |
commit | bc46c7b8ea40c64ad909769ce9f37381013598dd (patch) | |
tree | f359616e0ef43909d2fc0cd0b7ed0371ffd2160f /src | |
parent | a9ba5fe7aad1fd47828eec3202f8f91d1d8e55e2 (diff) | |
download | qtbase-bc46c7b8ea40c64ad909769ce9f37381013598dd.tar.gz |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/thread/qfuture.h | 10 | ||||
-rw-r--r-- | src/corelib/thread/qfuture_impl.h | 58 |
2 files changed, 40 insertions, 28 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h index 44c5331261..101bdc7808 100644 --- a/src/corelib/thread/qfuture.h +++ b/src/corelib/thread/qfuture.h @@ -347,7 +347,7 @@ QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QtFuture::Launch policy, Function &&function) { 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); return promise.future(); } @@ -358,7 +358,7 @@ QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QTh Function &&function) { 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); return promise.future(); } @@ -370,7 +370,8 @@ template<class Function, typename> QFuture<T> QFuture<T>::onFailed(Function &&handler) { 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(); } @@ -381,7 +382,8 @@ template<class Function, typename> QFuture<T> QFuture<T>::onCanceled(Function &&handler) { 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(); } diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index 1a02cc9cf1..a837c3cefb 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -247,20 +247,23 @@ template<typename Function, typename ResultType, typename ParentResultType> class Continuation { public: - Continuation(Function &&func, const QFuture<ParentResultType> &f, + template<typename F = Function> + Continuation(F &&func, const QFuture<ParentResultType> &f, 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; bool execute(); - static void create(Function &&func, QFuture<ParentResultType> *f, - QFutureInterface<ResultType> &p, QtFuture::Launch policy); + template<typename F = Function> + static void create(F &&func, QFuture<ParentResultType> *f, QFutureInterface<ResultType> &p, + QtFuture::Launch policy); - static void create(Function &&func, QFuture<ParentResultType> *f, - QFutureInterface<ResultType> &p, QThreadPool *pool); + template<typename F = Function> + static void create(F &&func, QFuture<ParentResultType> *f, QFutureInterface<ResultType> &p, + QThreadPool *pool); private: void fulfillPromiseWithResult(); @@ -285,9 +288,10 @@ template<typename Function, typename ResultType, typename ParentResultType> class SyncContinuation final : public Continuation<Function, ResultType, ParentResultType> { public: - SyncContinuation(Function &&func, const QFuture<ParentResultType> &f, + template<typename F = Function> + SyncContinuation(F &&func, const QFuture<ParentResultType> &f, 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: - 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) - : Continuation<Function, ResultType, ParentResultType>(std::forward<Function>(func), f, p), + : Continuation<Function, ResultType, ParentResultType>(std::forward<F>(func), f, p), threadPool(pool) { this->promise.setRunnable(this); @@ -334,12 +339,13 @@ template<class Function, class ResultType> class FailureHandler { 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); - FailureHandler(Function &&func, const QFuture<ResultType> &f, - const QFutureInterface<ResultType> &p) - : promise(p), parentFuture(f), handler(std::forward<Function>(func)) + template<typename F = Function> + FailureHandler(F &&func, const QFuture<ResultType> &f, const QFutureInterface<ResultType> &p) + : 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> -void Continuation<Function, ResultType, ParentResultType>::create(Function &&func, +template<typename F> +void Continuation<Function, ResultType, ParentResultType>::create(F &&func, QFuture<ParentResultType> *f, QFutureInterface<ResultType> &p, QtFuture::Launch policy) @@ -461,10 +468,10 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun Continuation<Function, ResultType, ParentResultType> *continuationJob = nullptr; if (launchAsync) { continuationJob = new AsyncContinuation<Function, ResultType, ParentResultType>( - std::forward<Function>(func), *f, p, pool); + std::forward<F>(func), *f, p, pool); } else { continuationJob = new SyncContinuation<Function, ResultType, ParentResultType>( - std::forward<Function>(func), *f, p); + std::forward<F>(func), *f, p); } p.setLaunchAsync(launchAsync); @@ -484,7 +491,8 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun } 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, QFutureInterface<ResultType> &p, QThreadPool *pool) @@ -492,7 +500,7 @@ void Continuation<Function, ResultType, ParentResultType>::create(Function &&fun Q_ASSERT(f); 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.setThreadPool(pool); @@ -571,13 +579,14 @@ void fulfillPromise(QFutureInterface<T> &promise, Function &&handler) #ifndef QT_NO_EXCEPTIONS 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) { Q_ASSERT(future); - FailureHandler<Function, ResultType> *failureHandler = new FailureHandler<Function, ResultType>( - std::forward<Function>(function), *future, promise); + FailureHandler<Function, ResultType> *failureHandler = + new FailureHandler<Function, ResultType>(std::forward<F>(function), *future, promise); auto failureContinuation = [failureHandler]() mutable { failureHandler->run(); @@ -654,13 +663,14 @@ template<class Function, class ResultType> class CanceledHandler { 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) { Q_ASSERT(future); auto canceledContinuation = [parentFuture = *future, promise, - handler = std::move(handler)]() mutable { + handler = std::forward<F>(handler)]() mutable { promise.reportStarted(); if (parentFuture.isCanceled()) { |