diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h index e103cfb5526..dd2f5111e04 100644 --- a/src/corelib/thread/qfuture.h +++ b/src/corelib/thread/qfuture.h @@ -53,8 +53,6 @@ QT_BEGIN_NAMESPACE template class QFutureWatcher; -template <> -class QFutureWatcher; template class QFuture @@ -63,13 +61,39 @@ public: QFuture() : d(QFutureInterface::canceledResult()) { } + + template> explicit QFuture(QFutureInterface *p) // internal : d(*p) { } + + template> + explicit QFuture(QFutureInterfaceBase *p) // internal + : d(*p) + { + } + +#if !defined(Q_CC_XLC) + template> + QFuture(const QFuture &other) : d(other.d) + { + } + + template> + QFuture &operator=(const QFuture &other) + { + d = other.d; + return *this; + } +#endif + #if defined(Q_CLANG_QDOC) ~QFuture() { } QFuture(const QFuture &) { } QFuture & operator=(const QFuture &) { } + + // This is required to allow QDoc to find the declaration of operator T(). + operator T() const; #endif bool operator==(const QFuture &other) const { return (d == other.d); } @@ -95,11 +119,20 @@ public: QString progressText() const { return d.progressText(); } void waitForFinished() { d.waitForFinished(); } + template> inline T result() const; + + template> inline T resultAt(int index) const; + + template> bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); } - operator T() const { return result(); } + // operator T() + template + operator typename std::enable_if_t, U>() const { return result(); } + + template> QList results() const { return d.results(); } template @@ -117,6 +150,9 @@ public: class const_iterator { public: + static_assert(!std::is_same_v, + "It isn't possible to define QFuture::const_iterator"); + typedef std::bidirectional_iterator_tag iterator_category; typedef qptrdiff difference_type; typedef T value_type; @@ -203,9 +239,16 @@ public: friend class const_iterator; typedef const_iterator ConstIterator; + template> const_iterator begin() const { return const_iterator(this, 0); } + + template> const_iterator constBegin() const { return const_iterator(this, 0); } + + template> const_iterator end() const { return const_iterator(this, -1); } + + template> const_iterator constEnd() const { return const_iterator(this, -1); } private: @@ -213,17 +256,21 @@ private: public: // Warning: the d pointer is not documented and is considered private. // TODO: make this private - mutable QFutureInterface d; + using QFuturePrivate = + std::conditional_t, QFutureInterfaceBase, QFutureInterface>; + mutable QFuturePrivate d; }; -template +template +template inline T QFuture::result() const { d.waitForResult(0); return d.resultReference(0); } -template +template +template inline T QFuture::resultAt(int index) const { d.waitForResult(index); @@ -265,80 +312,6 @@ QFuture::template ResultType> QFuture::then(QTh return promise.future(); } -Q_DECLARE_SEQUENTIAL_ITERATOR(Future) - -template <> -class QFuture -{ -public: - QFuture() - : d(QFutureInterface::canceledResult()) - { } - explicit QFuture(QFutureInterfaceBase *p) // internal - : d(*p) - { } - - bool operator==(const QFuture &other) const { return (d == other.d); } - bool operator!=(const QFuture &other) const { return (d != other.d); } - -#if !defined(Q_CC_XLC) - template - QFuture(const QFuture &other) - : d(other.d) - { } - - template - QFuture &operator=(const QFuture &other) - { - d = other.d; - return *this; - } -#endif - - void cancel() { d.cancel(); } - bool isCanceled() const { return d.isCanceled(); } - - void setPaused(bool paused) { d.setPaused(paused); } - bool isPaused() const { return d.isPaused(); } - void pause() { setPaused(true); } - void resume() { setPaused(false); } - void togglePaused() { d.togglePaused(); } - - bool isStarted() const { return d.isStarted(); } - bool isFinished() const { return d.isFinished(); } - bool isRunning() const { return d.isRunning(); } - - int resultCount() const { return d.resultCount(); } - int progressValue() const { return d.progressValue(); } - int progressMinimum() const { return d.progressMinimum(); } - int progressMaximum() const { return d.progressMaximum(); } - QString progressText() const { return d.progressText(); } - void waitForFinished() { d.waitForFinished(); } - - template - using ResultType = typename QtPrivate::ResultTypeHelper::ResultType; - - template - QFuture> then(Function &&function); - - template - QFuture> then(QtFuture::Launch policy, Function &&function); - - template - QFuture> then(QThreadPool *pool, Function &&function); - -private: - friend class QFutureWatcher; - -#ifdef QFUTURE_TEST -public: -#endif - mutable QFutureInterfaceBase d; - - template - friend class QtPrivate::Continuation; -}; - inline QFuture QFutureInterface::future() { return QFuture(this); @@ -350,31 +323,7 @@ QFuture qToVoidFuture(const QFuture &future) return QFuture(future.d); } -template -QFuture::ResultType> QFuture::then(Function &&function) -{ - return then(QtFuture::Launch::Sync, std::forward(function)); -} - -template -QFuture::ResultType> QFuture::then(QtFuture::Launch policy, - Function &&function) -{ - QFutureInterface> promise(QFutureInterfaceBase::State::Pending); - QtPrivate::Continuation, void>::create( - std::forward(function), this, promise, policy); - return promise.future(); -} - -template -QFuture::ResultType> QFuture::then(QThreadPool *pool, - Function &&function) -{ - QFutureInterface> promise(QFutureInterfaceBase::State::Pending); - QtPrivate::Continuation, void>::create( - std::forward(function), this, promise, pool); - return promise.future(); -} +Q_DECLARE_SEQUENTIAL_ITERATOR(Future) QT_END_NAMESPACE diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index eed7828c358..20ee7e4f338 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -66,6 +66,12 @@ enum class Launch { Sync, Async, Inherit }; namespace QtPrivate { +template +using EnableForVoid = std::enable_if_t>; + +template +using EnableForNonVoid = std::enable_if_t>; + template struct ResultTypeHelper { diff --git a/src/corelib/thread/qfuturewatcher.h b/src/corelib/thread/qfuturewatcher.h index fb7dd304997..214dc37f01f 100644 --- a/src/corelib/thread/qfuturewatcher.h +++ b/src/corelib/thread/qfuturewatcher.h @@ -110,6 +110,12 @@ private: virtual QFutureInterfaceBase &futureInterface() = 0; }; +namespace QtPrivate { + +template +using EnableForNonVoid = std::enable_if_t>; +} + template class QFutureWatcher : public QFutureWatcherBase { @@ -124,7 +130,10 @@ public: QFuture future() const { return m_future; } + template> T result() const { return m_future.result(); } + + template> T resultAt(int index) const { return m_future.resultAt(index); } #ifdef Q_QDOC @@ -180,36 +189,6 @@ Q_INLINE_TEMPLATE void QFutureWatcher::setFuture(const QFuture &_future) connectOutputInterface(); } -template <> -class QFutureWatcher : public QFutureWatcherBase -{ -public: - explicit QFutureWatcher(QObject *_parent = nullptr) - : QFutureWatcherBase(_parent) - { } - ~QFutureWatcher() - { disconnectOutputInterface(); } - - void setFuture(const QFuture &future); - QFuture future() const - { return m_future; } - -private: - QFuture m_future; - const QFutureInterfaceBase &futureInterface() const override { return m_future.d; } - QFutureInterfaceBase &futureInterface() override { return m_future.d; } -}; - -Q_INLINE_TEMPLATE void QFutureWatcher::setFuture(const QFuture &_future) -{ - if (_future == m_future) - return; - - disconnectOutputInterface(true); - m_future = _future; - connectOutputInterface(); -} - QT_END_NAMESPACE #endif // QFUTUREWATCHER_H