summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfuture.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qfuture.h')
-rw-r--r--src/corelib/thread/qfuture.h198
1 files changed, 139 insertions, 59 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index d3135510b3..bfca16b641 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -45,30 +45,62 @@
#include <QtCore/qfutureinterface.h>
#include <QtCore/qstring.h>
+#include <QtCore/qfuture_impl.h>
+
+#include <type_traits>
+#include <vector>
+
QT_REQUIRE_CONFIG(future);
QT_BEGIN_NAMESPACE
-
template <typename T>
class QFutureWatcher;
-template <>
-class QFutureWatcher<void>;
template <typename T>
class QFuture
{
+ static_assert (std::is_copy_constructible_v<T>
+ || std::is_move_constructible_v<T>
+ || std::is_same_v<T, void>,
+ "Type with copy or move constructors or type void is required");
public:
QFuture()
: d(QFutureInterface<T>::canceledResult())
{ }
+
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
explicit QFuture(QFutureInterface<T> *p) // internal
: d(*p)
{ }
+
+ template<typename U = T, typename = QtPrivate::EnableForVoid<U>>
+ explicit QFuture(QFutureInterfaceBase *p) // internal
+ : d(*p)
+ {
+ }
+
+#if !defined(Q_CC_XLC)
+ template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
+ QFuture(const QFuture<U> &other) : d(other.d)
+ {
+ }
+
+ template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
+ QFuture<void> &operator=(const QFuture<U> &other)
+ {
+ d = other.d;
+ return *this;
+ }
+#endif
+
#if defined(Q_CLANG_QDOC)
~QFuture() { }
QFuture(const QFuture<T> &) { }
QFuture<T> & operator=(const QFuture<T> &) { }
+
+ // 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); }
@@ -94,16 +126,54 @@ public:
QString progressText() const { return d.progressText(); }
void waitForFinished() { d.waitForFinished(); }
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
inline T result() const;
+
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
inline T resultAt(int index) const;
+
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); }
- operator T() const { return result(); }
+ // operator T()
+ template<typename U = T>
+ operator typename std::enable_if_t<!std::is_same_v<U, void>, U>() const { return result(); }
+
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
QList<T> results() const { return d.results(); }
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
+ T takeResult() { return d.takeResult(); }
+
+ template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
+ std::vector<T> takeResults() { return d.takeResults(); }
+
+ bool isValid() const { return d.isValid(); }
+
+ template<class Function>
+ using ResultType = typename QtPrivate::ResultTypeHelper<Function, T>::ResultType;
+
+ template<class Function>
+ QFuture<ResultType<Function>> then(Function &&function);
+
+ template<class Function>
+ QFuture<ResultType<Function>> then(QtFuture::Launch policy, Function &&function);
+
+ template<class Function>
+ QFuture<ResultType<Function>> then(QThreadPool *pool, Function &&function);
+
+#ifndef QT_NO_EXCEPTIONS
+ template<class Function,
+ typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
+ QFuture<T> onFailed(Function &&handler);
+#endif
+
class const_iterator
{
public:
+ static_assert(!std::is_same_v<T, void>,
+ "It isn't possible to define QFuture<void>::const_iterator");
+
typedef std::bidirectional_iterator_tag iterator_category;
typedef qptrdiff difference_type;
typedef T value_type;
@@ -190,26 +260,51 @@ public:
friend class const_iterator;
typedef const_iterator ConstIterator;
+ template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
const_iterator begin() const { return const_iterator(this, 0); }
+
+ template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
const_iterator constBegin() const { return const_iterator(this, 0); }
+
+ template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
const_iterator end() const { return const_iterator(this, -1); }
+
+ template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
const_iterator constEnd() const { return const_iterator(this, -1); }
private:
friend class QFutureWatcher<T>;
-public: // Warning: the d pointer is not documented and is considered private.
- mutable QFutureInterface<T> d;
+ template<class U>
+ friend class QFuture;
+
+ template<class Function, class ResultType, class ParentResultType>
+ friend class QtPrivate::Continuation;
+
+#ifndef QT_NO_EXCEPTIONS
+ template<class Function, class ResultType>
+ friend class QtPrivate::FailureHandler;
+#endif
+
+ using QFuturePrivate =
+ std::conditional_t<std::is_same_v<T, void>, QFutureInterfaceBase, QFutureInterface<T>>;
+
+#ifdef QFUTURE_TEST
+public:
+#endif
+ mutable QFuturePrivate d;
};
-template <typename T>
+template<typename T>
+template<typename U, typename>
inline T QFuture<T>::result() const
{
d.waitForResult(0);
return d.resultReference(0);
}
-template <typename T>
+template<typename T>
+template<typename U, typename>
inline T QFuture<T>::resultAt(int index) const
{
d.waitForResult(index);
@@ -222,64 +317,47 @@ inline QFuture<T> QFutureInterface<T>::future()
return QFuture<T>(this);
}
-Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
-
-template <>
-class QFuture<void>
+template<class T>
+template<class Function>
+QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(Function &&function)
{
-public:
- QFuture()
- : d(QFutureInterface<void>::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 <typename T>
- QFuture(const QFuture<T> &other)
- : d(other.d)
- { }
-
- template <typename T>
- QFuture<void> &operator=(const QFuture<T> &other)
- {
- d = other.d;
- return *this;
- }
-#endif
-
- void cancel() { d.cancel(); }
- bool isCanceled() const { return d.isCanceled(); }
+ return then(QtFuture::Launch::Sync, std::forward<Function>(function));
+}
- 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(); }
+template<class T>
+template<class Function>
+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(
+ std::forward<Function>(function), this, promise, policy);
+ return promise.future();
+}
- bool isStarted() const { return d.isStarted(); }
- bool isFinished() const { return d.isFinished(); }
- bool isRunning() const { return d.isRunning(); }
+template<class T>
+template<class Function>
+QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QThreadPool *pool,
+ Function &&function)
+{
+ QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
+ QtPrivate::Continuation<Function, ResultType<Function>, T>::create(
+ std::forward<Function>(function), this, promise, pool);
+ return promise.future();
+}
- 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(); }
+#ifndef QT_NO_EXCEPTIONS
-private:
- friend class QFutureWatcher<void>;
+template<class T>
+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);
+ return promise.future();
+}
-#ifdef QFUTURE_TEST
-public:
#endif
- mutable QFutureInterfaceBase d;
-};
inline QFuture<void> QFutureInterface<void>::future()
{
@@ -292,6 +370,8 @@ QFuture<void> qToVoidFuture(const QFuture<T> &future)
return QFuture<void>(future.d);
}
+Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
+
QT_END_NAMESPACE
#endif // QFUTURE_H