Qt 6.x
The Qt SDK
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>>
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>
132
133 template<class Function>
135
136 template<class Function>
138
139 template<class Function>
141
142#ifndef QT_NO_EXCEPTIONS
143 template<class Function,
144 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
146
147 template<class Function,
148 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
150#endif
151
152 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
154
155 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
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>
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); }
186 inline bool operator!=(const const_iterator &other) const { return index != other.index; }
187 inline bool operator==(const const_iterator &o) const { return !operator!=(o); }
189 { index = advanceIndex(index, 1); return *this; }
191 { index = advanceIndex(index, -1); return *this; }
193 {
194 const_iterator r = *this;
195 index = advanceIndex(index, 1);
196 return r;
197 }
199 {
200 const_iterator r = *this;
201 index = advanceIndex(index, -1);
202 return r;
203 }
204 inline const_iterator operator+(int j) const
205 { return const_iterator(future, advanceIndex(index, j)); }
206 inline const_iterator operator-(int j) const
207 { return const_iterator(future, advanceIndex(index, -j)); }
209 { index = advanceIndex(index, j); return *this; }
211 { index = advanceIndex(index, -j); return *this; }
213 { return const_iterator(k.future, k.advanceIndex(k.index, j)); }
214
215 private:
233 int advanceIndex(int idx, int n) const
234 {
235 // The end iterator can be decremented, leave as-is for other cases
236 if (idx == -1 && n >= 0)
237 return idx;
238
239 // Special case for decrementing the end iterator: wait for
240 // finished to get the total result count.
241 if (idx == -1 && future->isRunning())
242 future->d.waitForFinished();
243
244 // Wait for result at target index
245 const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
246 future->d.waitForResult(targetIndex);
247
248 // After waiting there is either a result or the end was reached
249 return (targetIndex < future->resultCount()) ? targetIndex : -1;
250 }
251
252 QFuture const * future;
253 int index;
254 };
255 friend class const_iterator;
257
258 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
259 const_iterator begin() const { return const_iterator(this, 0); }
260
261 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
262 const_iterator constBegin() const { return const_iterator(this, 0); }
263
264 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
265 const_iterator end() const { return const_iterator(this, -1); }
266
267 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
268 const_iterator constEnd() const { return const_iterator(this, -1); }
269
270private:
271 friend class QFutureWatcher<T>;
272
273 template<class U>
274 friend class QFuture;
275
277
278 template<class Function, class ResultType, class ParentResultType>
280
281 template<class Function, class ResultType>
283
284#ifndef QT_NO_EXCEPTIONS
285 template<class Function, class ResultType>
287#endif
288
289 template<typename ResultType>
291
293
294 using QFuturePrivate =
295 std::conditional_t<std::is_same_v<T, void>, QFutureInterfaceBase, QFutureInterface<T>>;
296
297#ifdef QFUTURE_TEST
298public:
299#endif
300 mutable QFuturePrivate d;
301};
302
303template<typename T>
304template<typename U, typename>
305inline T QFuture<T>::result() const
306{
307 d.waitForResult(0);
308 return d.resultReference(0);
309}
310
311template<typename T>
312template<typename U, typename>
313inline T QFuture<T>::resultAt(int index) const
314{
315 d.waitForResult(index);
316 return d.resultReference(index);
317}
318
319template <typename T>
321{
322 return QFuture<T>(this);
323}
324
325template<class T>
326template<class Function>
328{
329 return then(QtFuture::Launch::Sync, std::forward<Function>(function));
330}
331
332template<class T>
333template<class Function>
334QFuture<typename QFuture<T>::template ResultType<Function>>
336{
339 std::forward<Function>(function), this, promise, policy);
340 return promise.future();
341}
342
343template<class T>
344template<class Function>
346 Function &&function)
347{
350 std::forward<Function>(function), this, promise, pool);
351 return promise.future();
352}
353
354template<class T>
355template<class Function>
357 Function &&function)
358{
361 std::forward<Function>(function), this, promise, context);
362 return promise.future();
363}
364
365#ifndef QT_NO_EXCEPTIONS
366template<class T>
367template<class Function, typename>
369{
371 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
372 this, promise);
373 return promise.future();
374}
375
376template<class T>
377template<class Function, typename>
379{
381 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
382 this, promise, context);
383 return promise.future();
384}
385
386#endif
387
388template<class T>
389template<class Function, typename>
391{
393 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
394 this, promise);
395 return promise.future();
396}
397
398template<class T>
399template<class Function, typename>
401{
403 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
404 this, promise, context);
405 return promise.future();
406}
407
408template<class T>
409template<class U, typename>
411{
412 if constexpr (QtPrivate::isQFutureV<typename QtPrivate::Future<T>::type>)
413 return QtPrivate::UnwrapHandler::unwrapImpl(this).unwrap();
414 else
416}
417
419{
420 return QFuture<void>(this);
421}
422
423template<typename T>
425{
426 return future.d;
427}
428
429namespace QtPrivate
430{
431
432template<typename T>
433struct MetaTypeQFutureHelper<QFuture<T>>
434{
435 static bool registerConverter() {
436 if constexpr (std::is_same_v<T, void>)
437 return false;
438
439 return QMetaType::registerConverter<QFuture<T>, QFuture<void>>(
440 [](const QFuture<T> &future) { return QFuture<void>(future); });
441 }
442};
443
444} // namespace QtPrivate
445
446namespace QtFuture {
447
448#ifndef Q_QDOC
449
450template<typename OutputSequence, typename InputIt,
451 typename ValueType = typename std::iterator_traits<InputIt>::value_type,
452 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
455 int> = 0>
457{
458 return QtPrivate::whenAllImpl<OutputSequence, InputIt, ValueType>(first, last);
459}
460
461template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
462 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
464 int> = 0>
466{
467 return QtPrivate::whenAllImpl<QList<ValueType>, InputIt, ValueType>(first, last);
468}
469
470template<typename OutputSequence, typename... Futures,
471 std::enable_if_t<std::conjunction_v<QtPrivate::IsRandomAccessible<OutputSequence>,
472 QtPrivate::NotEmpty<Futures...>,
474 int> = 0>
475QFuture<OutputSequence> whenAll(Futures &&... futures)
476{
477 return QtPrivate::whenAllImpl<OutputSequence, Futures...>(std::forward<Futures>(futures)...);
478}
479
480template<typename... Futures,
481 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
483 int> = 0>
485{
486 return QtPrivate::whenAllImpl<QList<std::variant<std::decay_t<Futures>...>>, Futures...>(
487 std::forward<Futures>(futures)...);
488}
489
490template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
491 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
493 int> = 0>
495 InputIt last)
496{
497 return QtPrivate::whenAnyImpl<InputIt, ValueType>(first, last);
498}
499
500template<typename... Futures,
501 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
503 int> = 0>
505{
506 return QtPrivate::whenAnyImpl(std::forward<Futures>(futures)...);
507}
508
509#else
510
511template<typename OutputSequence, typename InputIt>
512QFuture<OutputSequence> whenAll(InputIt first, InputIt last);
513
514template<typename OutputSequence, typename... Futures>
515QFuture<OutputSequence> whenAll(Futures &&... futures);
516
517template<typename T, typename InputIt>
518QFuture<QtFuture::WhenAnyResult<T>> whenAny(InputIt first, InputIt last);
519
520template<typename... Futures>
521QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures);
522
523#endif // Q_QDOC
524
525#if QT_DEPRECATED_SINCE(6, 10)
526#if defined(Q_QDOC)
527static QFuture<void> makeReadyFuture()
528#else
529template<typename T = void>
530QT_DEPRECATED_VERSION_X(6, 10, "Use makeReadyVoidFuture() instead")
531static QFuture<T> makeReadyFuture()
532#endif
533{
534 return makeReadyVoidFuture();
535}
536#endif // QT_DEPRECATED_SINCE(6, 10)
537
538} // namespace QtFuture
539
541
543
545
546#endif // QFUTURE_H
static QFutureInterfaceBase get(const QFuture< T > &future)
Definition qfuture.h:424
QFuture< T > future()
Definition qfuture.h:320
const_iterator & operator-=(int j)
Definition qfuture.h:210
const_iterator operator-(int j) const
Definition qfuture.h:206
std::bidirectional_iterator_tag iterator_category
Definition qfuture.h:172
const_iterator operator++(int)
Definition qfuture.h:192
const_iterator operator--(int)
Definition qfuture.h:198
const_iterator & operator++()
Definition qfuture.h:188
const_iterator(const const_iterator &o)
Definition qfuture.h:181
friend const_iterator operator+(int j, const_iterator k)
Definition qfuture.h:212
bool operator!=(const const_iterator &other) const
Definition qfuture.h:186
const_iterator & operator--()
Definition qfuture.h:190
const_iterator & operator+=(int j)
Definition qfuture.h:208
bool operator==(const const_iterator &o) const
Definition qfuture.h:187
const_iterator operator+(int j) const
Definition qfuture.h:204
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:368
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:305
QFuture< ResultType< Function > > then(QThreadPool *pool, Function &&function)
T resultAt(int index) const
Definition qfuture.h:313
const_iterator end() const
Definition qfuture.h:265
const_iterator begin() const
Definition qfuture.h:259
const_iterator ConstIterator
Definition qfuture.h:256
int progressValue() const
Definition qfuture.h:98
auto unwrap()
Definition qfuture.h:410
QString progressText() const
Definition qfuture.h:101
QFuture()
Definition qfuture.h:31
QFuture< T > onFailed(QObject *context, Function &&handler)
Definition qfuture.h:378
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:390
void suspend()
Definition qfuture.h:89
QFuture< T > onCanceled(QObject *context, Function &&handler)
Definition qfuture.h:400
const_iterator constEnd() const
Definition qfuture.h:268
QFuture(QFutureInterfaceBase *p)
Definition qfuture.h:41
QFuture(QFutureInterface< T > *p)
Definition qfuture.h:36
friend class QFutureInterfaceBase
Definition qfuture.h:276
bool isResultReadyAt(int resultIndex) const
Definition qfuture.h:111
QFuture< ResultType< Function > > then(QObject *context, Function &&function)
friend class QFuture
Definition qfuture.h:274
T takeResult()
Definition qfuture.h:117
const_iterator constBegin() const
Definition qfuture.h:262
QFuture< ResultType< Function > > then(QtFuture::Launch policy, Function &&function)
void resume()
Definition qfuture.h:90
bool isFinished() const
Definition qfuture.h:94
Definition qlist.h:74
\inmodule QtCore
Definition qobject.h:90
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qthreadpool.h:20
Combined button and popup list for selecting options.
QFuture< OutputSequence > whenAll(InputIt first, InputIt last)
Definition qfuture.h:456
Q_CORE_EXPORT QFuture< void > makeReadyVoidFuture()
QFuture< WhenAnyResult< typename QtPrivate::Future< ValueType >::type > > whenAny(InputIt first, InputIt last)
Definition qfuture.h:494
\macro QT_NAMESPACE
QFuture< OutputSequence > whenAllImpl(InputIt first, InputIt last)
std::bool_constant<(sizeof...(Args) > 0)> NotEmpty
QFuture< QtFuture::WhenAnyResult< typename Future< ValueType >::type > > whenAnyImpl(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
static void * context
#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
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
#define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
Definition qiterator.h:20
#define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE)
Definition qmetatype.h:1552
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:69
QFuture< void > future
[5]
QSharedPointer< T > other(t)
[5]
QSizePolicy policy
view create()
static auto unwrapImpl(T *outer)