Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfuture.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QFUTURE_H
5#define QFUTURE_H
6
7#include <QtCore/qglobal.h>
8
9#include <QtCore/qfutureinterface.h>
10#include <QtCore/qmetatype.h>
11#include <QtCore/qstring.h>
12
13#include <QtCore/qfuture_impl.h>
14
15#include <type_traits>
16
18
20
21template <typename T>
22class QFutureWatcher;
23
24template <typename T>
26{
27 static_assert (std::is_move_constructible_v<T>
28 || std::is_same_v<T, void>,
29 "A move-constructible type or type void is required");
30public:
32 : d(QFutureInterface<T>::canceledResult())
33 { }
34
35 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
36 explicit QFuture(QFutureInterface<T> *p) // internal
37 : d(*p)
38 { }
39
40 template<typename U = T, typename = QtPrivate::EnableForVoid<U>>
41 explicit QFuture(QFutureInterfaceBase *p) // internal
42 : d(*p)
43 {
44 }
45
46 template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
47 explicit QFuture(const QFuture<U> &other) : d(other.d)
48 {
49 }
50
51 template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
52 QFuture<void> &operator=(const QFuture<U> &other)
53 {
54 d = other.d;
55 return *this;
56 }
57
58#if defined(Q_QDOC)
59 ~QFuture() { }
60 QFuture(const QFuture<T> &) { }
61 QFuture<T> & operator=(const QFuture<T> &) { }
62#endif
63
64 void cancel() { d.cancel(); }
65 bool isCanceled() const { return d.isCanceled(); }
66
67#if QT_DEPRECATED_SINCE(6, 0)
68 QT_DEPRECATED_VERSION_X_6_0("Use setSuspended() instead.")
69 void setPaused(bool paused) { d.setSuspended(paused); }
70
71 QT_DEPRECATED_VERSION_X_6_0("Use isSuspending() or isSuspended() instead.")
72 bool isPaused() const
73 {
76 return d.isPaused();
78 }
79
80 QT_DEPRECATED_VERSION_X_6_0("Use toggleSuspended() instead.")
81 void togglePaused() { d.toggleSuspended(); }
82
83 QT_DEPRECATED_VERSION_X_6_0("Use suspend() instead.")
84 void pause() { suspend(); }
85#endif
86 bool isSuspending() const { return d.isSuspending(); }
87 bool isSuspended() const { return d.isSuspended(); }
88 void setSuspended(bool suspend) { d.setSuspended(suspend); }
89 void suspend() { setSuspended(true); }
90 void resume() { setSuspended(false); }
91 void toggleSuspended() { d.toggleSuspended(); }
92
93 bool isStarted() const { return d.isStarted(); }
94 bool isFinished() const { return d.isFinished(); }
95 bool isRunning() const { return d.isRunning(); }
96
97 int resultCount() const { return d.resultCount(); }
98 int progressValue() const { return d.progressValue(); }
99 int progressMinimum() const { return d.progressMinimum(); }
100 int progressMaximum() const { return d.progressMaximum(); }
101 QString progressText() const { return d.progressText(); }
102 void waitForFinished() { d.waitForFinished(); }
103
104 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
105 inline T result() const;
106
107 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
108 inline T resultAt(int index) const;
109
110 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
111 bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); }
112
113 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
114 QList<T> results() const { return d.results(); }
115
116 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
117 T takeResult() { return d.takeResult(); }
118
119#if 0
120 // TODO: Enable and make it return a QList, when QList is fixed to support move-only types
121 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
122 std::vector<T> takeResults() { return d.takeResults(); }
123#endif
124
125 bool isValid() const { return d.isValid(); }
126
127 template<class Function>
129
130 template<class Function>
131 QFuture<ResultType<Function>> then(Function &&function);
132
133 template<class Function>
134 QFuture<ResultType<Function>> then(QtFuture::Launch policy, Function &&function);
135
136 template<class Function>
137 QFuture<ResultType<Function>> then(QThreadPool *pool, Function &&function);
138
139 template<class Function>
140 QFuture<ResultType<Function>> then(QObject *context, Function &&function);
141
142#ifndef QT_NO_EXCEPTIONS
143 template<class Function,
144 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
145 QFuture<T> onFailed(Function &&handler);
146
147 template<class Function,
148 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
149 QFuture<T> onFailed(QObject *context, Function &&handler);
150#endif
151
152 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
153 QFuture<T> onCanceled(Function &&handler);
154
155 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
156 QFuture<T> onCanceled(QObject *context, Function &&handler);
157
158#if !defined(Q_QDOC)
159 template<class U = T, typename = std::enable_if_t<QtPrivate::isQFutureV<U>>>
160 auto unwrap();
161#else
162 template<class U>
163 QFuture<U> unwrap();
164#endif
165
167 {
168 public:
169 static_assert(!std::is_same_v<T, void>,
170 "It isn't possible to define QFuture<void>::const_iterator");
171
172 typedef std::bidirectional_iterator_tag iterator_category;
174 typedef T value_type;
175 typedef const T *pointer;
176 typedef const T &reference;
177
178 inline const_iterator() {}
179 inline const_iterator(QFuture const * const _future, int _index)
180 : future(_future), index(advanceIndex(_index, 0)) { }
181 inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {}
183 { future = o.future; index = o.index; return *this; }
184 inline const T &operator*() const { return future->d.resultReference(index); }
185 inline const T *operator->() const { return future->d.resultPointer(index); }
187 { index = advanceIndex(index, 1); return *this; }
189 { index = advanceIndex(index, -1); return *this; }
191 {
192 const_iterator r = *this;
193 index = advanceIndex(index, 1);
194 return r;
195 }
197 {
198 const_iterator r = *this;
199 index = advanceIndex(index, -1);
200 return r;
201 }
202 inline const_iterator operator+(int j) const
203 { return const_iterator(future, advanceIndex(index, j)); }
204 inline const_iterator operator-(int j) const
205 { return const_iterator(future, advanceIndex(index, -j)); }
207 { index = advanceIndex(index, j); return *this; }
209 { index = advanceIndex(index, -j); return *this; }
211 { return const_iterator(k.future, k.advanceIndex(k.index, j)); }
212
213 private:
214 friend bool comparesEqual(const const_iterator &lhs, const const_iterator &rhs) noexcept
215 {
216 return lhs.index == rhs.index;
217 }
219
220
237 int advanceIndex(int idx, int n) const
238 {
239 // The end iterator can be decremented, leave as-is for other cases
240 if (idx == -1 && n >= 0)
241 return idx;
242
243 // Special case for decrementing the end iterator: wait for
244 // finished to get the total result count.
245 if (idx == -1 && future->isRunning())
246 future->d.waitForFinished();
247
248 // Wait for result at target index
249 const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
250 future->d.waitForResult(targetIndex);
251
252 // After waiting there is either a result or the end was reached
253 return (targetIndex < future->resultCount()) ? targetIndex : -1;
254 }
255
256 QFuture const * future;
257 int index;
258 };
259 friend class const_iterator;
261
262 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
263 const_iterator begin() const { return const_iterator(this, 0); }
264
265 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
266 const_iterator constBegin() const { return const_iterator(this, 0); }
267
268 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
269 const_iterator end() const { return const_iterator(this, -1); }
270
271 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
272 const_iterator constEnd() const { return const_iterator(this, -1); }
273
274private:
275 friend class QFutureWatcher<T>;
276
277 template<class U>
278 friend class QFuture;
279
281
282 template<class Function, class ResultType, class ParentResultType>
284
285 template<class Function, class ResultType>
287
288#ifndef QT_NO_EXCEPTIONS
289 template<class Function, class ResultType>
291#endif
292
293 template<typename ResultType>
295
297
298 using QFuturePrivate =
299 std::conditional_t<std::is_same_v<T, void>, QFutureInterfaceBase, QFutureInterface<T>>;
300
301#ifdef QFUTURE_TEST
302public:
303#endif
304 mutable QFuturePrivate d;
305};
306
307template<typename T>
308template<typename U, typename>
309inline T QFuture<T>::result() const
310{
311 d.waitForResult(0);
312 return d.resultReference(0);
313}
314
315template<typename T>
316template<typename U, typename>
317inline T QFuture<T>::resultAt(int index) const
318{
319 d.waitForResult(index);
320 return d.resultReference(index);
321}
322
323template <typename T>
325{
326 return QFuture<T>(this);
327}
328
329template<class T>
330template<class Function>
331QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(Function &&function)
332{
333 return then(QtFuture::Launch::Sync, std::forward<Function>(function));
334}
335
336template<class T>
337template<class Function>
338QFuture<typename QFuture<T>::template ResultType<Function>>
340{
341 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
343 std::forward<Function>(function), this, promise, policy);
344 return promise.future();
345}
346
347template<class T>
348template<class Function>
349QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QThreadPool *pool,
350 Function &&function)
351{
352 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
354 std::forward<Function>(function), this, promise, pool);
355 return promise.future();
356}
357
358template<class T>
359template<class Function>
360QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QObject *context,
361 Function &&function)
362{
363 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
365 std::forward<Function>(function), this, promise, context);
366 return promise.future();
367}
368
369#ifndef QT_NO_EXCEPTIONS
370template<class T>
371template<class Function, typename>
372QFuture<T> QFuture<T>::onFailed(Function &&handler)
373{
374 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
375 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
376 this, promise);
377 return promise.future();
378}
379
380template<class T>
381template<class Function, typename>
383{
384 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
385 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
386 this, promise, context);
387 return promise.future();
388}
389
390#endif
391
392template<class T>
393template<class Function, typename>
394QFuture<T> QFuture<T>::onCanceled(Function &&handler)
395{
396 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
397 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
398 this, promise);
399 return promise.future();
400}
401
402template<class T>
403template<class Function, typename>
405{
406 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
407 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
408 this, promise, context);
409 return promise.future();
410}
411
412template<class T>
413template<class U, typename>
415{
416 if constexpr (QtPrivate::isQFutureV<typename QtPrivate::Future<T>::type>)
417 return QtPrivate::UnwrapHandler::unwrapImpl(this).unwrap();
418 else
420}
421
422inline QFuture<void> QFutureInterface<void>::future()
423{
424 return QFuture<void>(this);
425}
426
427template<typename T>
429{
430 return future.d;
431}
432
433namespace QtPrivate
434{
435
436template<typename T>
437struct MetaTypeQFutureHelper<QFuture<T>>
438{
439 static bool registerConverter() {
440 if constexpr (std::is_same_v<T, void>)
441 return false;
442
443 return QMetaType::registerConverter<QFuture<T>, QFuture<void>>(
444 [](const QFuture<T> &future) { return QFuture<void>(future); });
445 }
446};
447
448} // namespace QtPrivate
449
450namespace QtFuture {
451
452#ifndef Q_QDOC
453
454template<typename OutputSequence, typename InputIt,
455 typename ValueType = typename std::iterator_traits<InputIt>::value_type,
456 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
459 int> = 0>
460QFuture<OutputSequence> whenAll(InputIt first, InputIt last)
461{
462 return QtPrivate::whenAllImpl<OutputSequence, InputIt, ValueType>(first, last);
463}
464
465template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
466 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
468 int> = 0>
469QFuture<QList<ValueType>> whenAll(InputIt first, InputIt last)
470{
471 return QtPrivate::whenAllImpl<QList<ValueType>, InputIt, ValueType>(first, last);
472}
473
474template<typename OutputSequence, typename... Futures,
475 std::enable_if_t<std::conjunction_v<QtPrivate::IsRandomAccessible<OutputSequence>,
476 QtPrivate::NotEmpty<Futures...>,
478 int> = 0>
479QFuture<OutputSequence> whenAll(Futures &&... futures)
480{
481 return QtPrivate::whenAllImpl<OutputSequence, Futures...>(std::forward<Futures>(futures)...);
482}
483
484template<typename... Futures,
485 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
487 int> = 0>
488QFuture<QList<std::variant<std::decay_t<Futures>...>>> whenAll(Futures &&... futures)
489{
490 return QtPrivate::whenAllImpl<QList<std::variant<std::decay_t<Futures>...>>, Futures...>(
491 std::forward<Futures>(futures)...);
492}
493
494template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
495 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
497 int> = 0>
498QFuture<WhenAnyResult<typename QtPrivate::Future<ValueType>::type>> whenAny(InputIt first,
499 InputIt last)
500{
501 return QtPrivate::whenAnyImpl<InputIt, ValueType>(first, last);
502}
503
504template<typename... Futures,
505 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
507 int> = 0>
508QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures)
509{
510 return QtPrivate::whenAnyImpl(std::forward<Futures>(futures)...);
511}
512
513#else
514
515template<typename OutputSequence, typename InputIt>
516QFuture<OutputSequence> whenAll(InputIt first, InputIt last);
517
518template<typename OutputSequence, typename... Futures>
519QFuture<OutputSequence> whenAll(Futures &&... futures);
520
521template<typename T, typename InputIt>
522QFuture<QtFuture::WhenAnyResult<T>> whenAny(InputIt first, InputIt last);
523
524template<typename... Futures>
525QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures);
526
527#endif // Q_QDOC
528
529#if QT_DEPRECATED_SINCE(6, 10)
530#if defined(Q_QDOC)
531static QFuture<void> makeReadyFuture()
532#else
533template<typename T = void>
534QT_DEPRECATED_VERSION_X(6, 10, "Use makeReadyVoidFuture() instead.")
535static QFuture<T> makeReadyFuture()
536#endif
537{
538 return makeReadyVoidFuture();
539}
540#endif // QT_DEPRECATED_SINCE(6, 10)
541
542} // namespace QtFuture
543
545
547
549
550#endif // QFUTURE_H
static QFutureInterfaceBase get(const QFuture< T > &future)
Definition qfuture.h:428
QFuture< T > future()
Definition qfuture.h:324
const_iterator & operator-=(int j)
Definition qfuture.h:208
const_iterator operator-(int j) const
Definition qfuture.h:204
std::bidirectional_iterator_tag iterator_category
Definition qfuture.h:172
const_iterator operator++(int)
Definition qfuture.h:190
const_iterator operator--(int)
Definition qfuture.h:196
const_iterator & operator++()
Definition qfuture.h:186
const_iterator(const const_iterator &o)
Definition qfuture.h:181
friend const_iterator operator+(int j, const_iterator k)
Definition qfuture.h:210
const_iterator & operator--()
Definition qfuture.h:188
const_iterator & operator+=(int j)
Definition qfuture.h:206
const_iterator operator+(int j) const
Definition qfuture.h:202
friend bool comparesEqual(const const_iterator &lhs, const const_iterator &rhs) noexcept
Definition qfuture.h:214
const T * operator->() const
Definition qfuture.h:185
const_iterator(QFuture const *const _future, int _index)
Definition qfuture.h:179
const T & operator*() const
Definition qfuture.h:184
const_iterator & operator=(const const_iterator &o)
Definition qfuture.h:182
QFuture< ResultType< Function > > then(Function &&function)
void toggleSuspended()
Definition qfuture.h:91
QFuture< T > onFailed(Function &&handler)
Definition qfuture.h:372
bool isCanceled() const
Definition qfuture.h:65
typename QtPrivate::ResultTypeHelper< Function, T >::ResultType ResultType
Definition qfuture.h:128
void setSuspended(bool suspend)
Definition qfuture.h:88
int progressMaximum() const
Definition qfuture.h:100
void cancel()
Definition qfuture.h:64
QFuture(const QFuture< U > &other)
Definition qfuture.h:47
int resultCount() const
Definition qfuture.h:97
bool isRunning() const
Definition qfuture.h:95
bool isValid() const
Definition qfuture.h:125
QList< T > results() const
Definition qfuture.h:114
bool isStarted() const
Definition qfuture.h:93
T result() const
Definition qfuture.h:309
QFuture< ResultType< Function > > then(QThreadPool *pool, Function &&function)
T resultAt(int index) const
Definition qfuture.h:317
const_iterator end() const
Definition qfuture.h:269
const_iterator begin() const
Definition qfuture.h:263
const_iterator ConstIterator
Definition qfuture.h:260
int progressValue() const
Definition qfuture.h:98
auto unwrap()
Definition qfuture.h:414
QString progressText() const
Definition qfuture.h:101
QFuture()
Definition qfuture.h:31
QFuture< T > onFailed(QObject *context, Function &&handler)
Definition qfuture.h:382
QFuture< void > & operator=(const QFuture< U > &other)
Definition qfuture.h:52
void waitForFinished()
Definition qfuture.h:102
bool isSuspended() const
Definition qfuture.h:87
bool isSuspending() const
Definition qfuture.h:86
int progressMinimum() const
Definition qfuture.h:99
QFuture< T > onCanceled(Function &&handler)
Definition qfuture.h:394
void suspend()
Definition qfuture.h:89
QFuture< T > onCanceled(QObject *context, Function &&handler)
Definition qfuture.h:404
const_iterator constEnd() const
Definition qfuture.h:272
QFuture(QFutureInterfaceBase *p)
Definition qfuture.h:41
friend class const_iterator
Definition qfuture.h:259
QFuture(QFutureInterface< T > *p)
Definition qfuture.h:36
friend class QFutureInterfaceBase
Definition qfuture.h:280
bool isResultReadyAt(int resultIndex) const
Definition qfuture.h:111
QFuture< ResultType< Function > > then(QObject *context, Function &&function)
friend class QFuture
Definition qfuture.h:278
T takeResult()
Definition qfuture.h:117
const_iterator constBegin() const
Definition qfuture.h:266
QFuture< ResultType< Function > > then(QtFuture::Launch policy, Function &&function)
void resume()
Definition qfuture.h:90
bool isFinished() const
Definition qfuture.h:94
\inmodule QtCore
Definition qobject.h:103
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qthreadpool.h:22
Combined button and popup list for selecting options.
QFuture< OutputSequence > whenAll(InputIt first, InputIt last)
Definition qfuture.h:460
QFuture< WhenAnyResult< typename QtPrivate::Future< ValueType >::type > > whenAny(InputIt first, InputIt last)
Definition qfuture.h:498
\macro QT_NO_KEYWORDS >
QFuture< OutputSequence > whenAllImpl(InputIt first, InputIt last)
std::is_convertible< typename std::iterator_traits< std::decay_t< decltype( std::begin(std::declval< Sequence >()))> >::iterator_category, std::random_access_iterator_tag > IsRandomAccessible
std::bool_constant< isQFutureV< T > > isQFuture
QFuture< QtFuture::WhenAnyResult< typename Future< ValueType >::type > > whenAnyImpl(InputIt first, InputIt last)
std::bool_constant<(sizeof...(Args) > 0)> NotEmpty
static void * context
#define Q_DECLARE_EQUALITY_COMPARABLE(...)
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_DEPRECATED
#define QT_WARNING_PUSH
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
Definition qiterator.h:21
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
Definition qmetatype.h:1573
GLuint index
[2]
GLboolean r
[2]
GLint first
GLfloat n
GLfloat GLfloat p
[1]
#define QT_REQUIRE_CONFIG(feature)
#define QT_DEPRECATED_VERSION_X(major, minor, text)
#define QT_DEPRECATED_VERSION_X_6_0(text)
ptrdiff_t qptrdiff
Definition qtypes.h:164
QFuture< void > future
[5]
QSharedPointer< T > other(t)
[5]
QSizePolicy policy
view create()
static auto unwrapImpl(T *outer)