Optimize ContinuationWrapper used for support of move-only continuations

After QFuture continuations became non-copyable (see earlier commits),
we have to always use ContinuationWrapper to save the continuations
inside std::function, since it requires the callable to be copyable.
Optimize the wrapper, by storing the callable directly (instead of using
a ref-counted QSharedPointer) and introducing a fake copy-constructor
that makes sure that it's never called.

Pick-to: 6.3 6.2
Change-Id: I0ed5f90ad62ede3b5c6d6e56ef58eb6377122920
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Sona Kurazyan 2022-01-18 15:45:56 +01:00
parent afdae3618a
commit b292928e35
2 changed files with 12 additions and 4 deletions

View File

@ -538,11 +538,19 @@ bool Continuation<Function, ResultType, ParentResultType>::execute()
template<class Function> template<class Function>
struct ContinuationWrapper struct ContinuationWrapper
{ {
ContinuationWrapper(Function &&f) : function(QSharedPointer<Function>::create(std::move(f))) { } ContinuationWrapper(Function &&f) : function(std::move(f)) { }
void operator()(const QFutureInterfaceBase &parentData) { (*function)(parentData); } ContinuationWrapper(const ContinuationWrapper &other)
: function(std::move(const_cast<ContinuationWrapper &>(other).function))
{
Q_ASSERT_X(false, "QFuture", "Continuation shouldn't be copied");
}
ContinuationWrapper(ContinuationWrapper &&other) = default;
ContinuationWrapper &operator=(ContinuationWrapper &&) = default;
void operator()(const QFutureInterfaceBase &parentData) { function(parentData); }
private: private:
QSharedPointer<Function> function; Function function;
}; };
template<typename Function, typename ResultType, typename ParentResultType> template<typename Function, typename ResultType, typename ParentResultType>

View File

@ -837,7 +837,7 @@ void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState)
void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func) void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func)
{ {
setContinuation(func, nullptr); setContinuation(std::move(func), nullptr);
} }
void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func, void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func,