diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-08-17 16:00:26 +0200 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-08-18 09:41:55 +0200 |
commit | 642b9fce81b46e23b35b17e8284bd81bdba57fdd (patch) | |
tree | 22c5f33e691bbbe6289acde7bbbc6b9f3191c09c /src/concurrent | |
parent | c4ac9e74c79ebba3493ce29b25623b8c39b021a4 (diff) |
QtConcurrent::run: support non default-constructible return types
The QtConcurrent::RunFunctionTask class keeps a variable to store the
result of QtConcurrent::run when it becomes available, so that it can be
reported afterwards. This requires the result type to be
default-constructible. However there's no need in storing the result, it
can be reported immediately after it becomes available.
Pick-to: 6.1 6.2
Fixes: QTBUG-95214
Change-Id: I95f3dbff0ab41eaa81b104a8834b37d10a0d193a
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/concurrent')
-rw-r--r-- | src/concurrent/qtconcurrentrunbase.h | 22 | ||||
-rw-r--r-- | src/concurrent/qtconcurrentstoredfunctioncall.h | 15 |
2 files changed, 11 insertions, 26 deletions
diff --git a/src/concurrent/qtconcurrentrunbase.h b/src/concurrent/qtconcurrentrunbase.h index 20267a2d5b..6038d0e60c 100644 --- a/src/concurrent/qtconcurrentrunbase.h +++ b/src/concurrent/qtconcurrentrunbase.h @@ -117,37 +117,15 @@ public: promise.reportException(QUnhandledException(std::current_exception())); } #endif - - reportResult(); - promise.reportFinished(); } protected: virtual void runFunctor() = 0; - virtual void reportResult() {} QFutureInterface<T> promise; }; -template <typename T> -class RunFunctionTask : public RunFunctionTaskBase<T> -{ -protected: - void reportResult() override - { - if constexpr (std::is_move_constructible_v<T>) - this->promise.reportAndMoveResult(std::move(result)); - else if constexpr (std::is_copy_constructible_v<T>) - this->promise.reportResult(result); - } - - T result; -}; - -template <> -class RunFunctionTask<void> : public RunFunctionTaskBase<void> {}; - } //namespace QtConcurrent #endif //Q_QDOC diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h index 98ce28f6dc..5b2fffdec1 100644 --- a/src/concurrent/qtconcurrentstoredfunctioncall.h +++ b/src/concurrent/qtconcurrentstoredfunctioncall.h @@ -138,7 +138,7 @@ template <class ...Types> using DecayedTuple = std::tuple<std::decay_t<Types>...>; template <class Function, class ...Args> -struct StoredFunctionCall : public RunFunctionTask<InvokeResultType<Function, Args...>> +struct StoredFunctionCall : public RunFunctionTaskBase<InvokeResultType<Function, Args...>> { StoredFunctionCall(DecayedTuple<Function, Args...> &&_data) : data(std::move(_data)) @@ -152,10 +152,17 @@ protected: return std::invoke(function, args...); }; - if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) + if constexpr (std::is_void_v<InvokeResultType<Function, Args...>>) { std::apply(invoke, std::move(data)); - else - this->result = std::apply(invoke, std::move(data)); + } else { + auto result = std::apply(invoke, std::move(data)); + + using T = InvokeResultType<Function, Args...>; + if constexpr (std::is_move_constructible_v<T>) + this->promise.reportAndMoveResult(std::move(result)); + else if constexpr (std::is_copy_constructible_v<T>) + this->promise.reportResult(result); + } } private: |