Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qfuture.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*! \class QFuture
5
\inmodule QtCore
6
\threadsafe
7
\brief The QFuture class represents the result of an asynchronous computation.
8
\since 4.4
9
10
\ingroup thread
11
12
QFuture allows threads to be synchronized against one or more results
13
which will be ready at a later point in time. The result can be of any type
14
that has default, copy and possibly move constructors. If
15
a result is not available at the time of calling the result(), resultAt(),
16
results() and takeResult() functions, QFuture will wait until the result
17
becomes available. You can use the isResultReadyAt() function to determine
18
if a result is ready or not. For QFuture objects that report more than one
19
result, the resultCount() function returns the number of continuous results.
20
This means that it is always safe to iterate through the results from 0 to
21
resultCount(). takeResult() invalidates a future, and any subsequent attempt
22
to access result or results from the future leads to undefined behavior.
23
isValid() tells you if results can be accessed.
24
25
QFuture provides a \l{Java-style iterators}{Java-style iterator}
26
(QFutureIterator) and an \l{STL-style iterators}{STL-style iterator}
27
(QFuture::const_iterator). Using these iterators is another way to access
28
results in the future.
29
30
If the result of one asynchronous computation needs to be passed
31
to another, QFuture provides a convenient way of chaining multiple sequential
32
computations using then(). onCanceled() can be used for adding a handler to
33
be called if the QFuture is canceled. Additionally, onFailed() can be used
34
to handle any failures that occurred in the chain. Note that QFuture relies
35
on exceptions for the error handling. If using exceptions is not an option,
36
you can still indicate the error state of QFuture, by making the error type
37
part of the QFuture type. For example, you can use std::variant, std::any or
38
similar for keeping the result or failure or make your custom type.
39
40
The example below demonstrates how the error handling can be done without
41
using exceptions. Let's say we want to send a network request to obtain a large
42
file from a network location. Then we want to write it to the file system and
43
return its location in case of a success. Both of these operations may fail
44
with different errors. So, we use \c std::variant to keep the result
45
or error:
46
47
\snippet code/src_corelib_thread_qfuture.cpp 3
48
49
And we combine the two operations using then():
50
51
\snippet code/src_corelib_thread_qfuture.cpp 4
52
53
It's possible to chain multiple continuations and handlers in any order.
54
For example:
55
56
\snippet code/src_corelib_thread_qfuture.cpp 15
57
58
Depending on the state of \c testFuture (canceled, has exception or has a
59
result), the next onCanceled(), onFailed() or then() will be called. So
60
if \c testFuture is successfully fulfilled, \c {Block 1} will be called. If
61
it succeeds as well, the next then() (\c {Block 4}) is called. If \c testFuture
62
gets canceled or fails with an exception, either \c {Block 2} or \c {Block 3}
63
will be called respectively. The next then() will be called afterwards, and the
64
story repeats.
65
66
\note If \c {Block 2} is invoked and throws an exception, the following
67
onFailed() (\c {Block 3}) will handle it. If the order of onFailed() and
68
onCanceled() were reversed, the exception state would propagate to the
69
next continuations and eventually would be caught in \c {Block 5}.
70
71
In the next example the first onCanceled() (\c {Block 2}) is removed:
72
73
\snippet code/src_corelib_thread_qfuture.cpp 16
74
75
If \c testFuture gets canceled, its state is propagated to the next then(),
76
which will be also canceled. So in this case \c {Block 6} will be called.
77
78
The future can have only one continuation. Consider the following example:
79
80
\snippet code/src_corelib_thread_qfuture.cpp 31
81
82
In this case \c f1 and \c f2 are effectively the same QFuture object, as
83
they share the same internal state. As a result, calling
84
\l {QFuture::}{then} on \c f2 will overwrite the continuation specified for
85
\c {f1}. So, only \c {"second"} will be printed when this code is executed.
86
87
QFuture also offers ways to interact with a running computation. For
88
instance, the computation can be canceled with the cancel() function. To
89
suspend or resume the computation, use the setSuspended() function or one of
90
the suspend(), resume(), or toggleSuspended() convenience functions. Be aware
91
that not all running asynchronous computations can be canceled or suspended.
92
For example, the future returned by QtConcurrent::run() cannot be canceled;
93
but the future returned by QtConcurrent::mappedReduced() can.
94
95
Progress information is provided by the progressValue(),
96
progressMinimum(), progressMaximum(), and progressText() functions. The
97
waitForFinished() function causes the calling thread to block and wait for
98
the computation to finish, ensuring that all results are available.
99
100
The state of the computation represented by a QFuture can be queried using
101
the isCanceled(), isStarted(), isFinished(), isRunning(), isSuspending()
102
or isSuspended() functions.
103
104
QFuture<void> is specialized to not contain any of the result fetching
105
functions. Any QFuture<T> can be assigned or copied into a QFuture<void>
106
as well. This is useful if only status or progress information is needed
107
- not the actual result data.
108
109
To interact with running tasks using signals and slots, use QFutureWatcher.
110
111
You can also use QtFuture::connect() to connect signals to a QFuture object
112
which will be resolved when a signal is emitted. This allows working with
113
signals like with QFuture objects. For example, if you combine it with then(),
114
you can attach multiple continuations to a signal, which are invoked in the
115
same thread or a new thread.
116
117
The QtFuture::whenAll() and QtFuture::whenAny() functions can be used to
118
combine several futures and track when the last or first of them completes.
119
120
A ready QFuture object with a value or a QFuture object holding exception can
121
be created using convenience functions QtFuture::makeReadyVoidFuture(),
122
QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), and
123
QtFuture::makeExceptionalFuture().
124
125
\note Some APIs (see \l {QFuture::then()} or various QtConcurrent method
126
overloads) allow scheduling the computation to a specific thread pool.
127
However, QFuture implements a work-stealing algorithm to prevent deadlocks
128
and optimize thread usage. As a result, computations can be executed
129
directly in the thread which requests the QFuture's result.
130
131
\note To start a computation and store results in a QFuture, use QPromise or
132
one of the APIs in the \l {Qt Concurrent} framework.
133
134
\sa QPromise, QtFuture::connect(), QtFuture::makeReadyVoidFuture(),
135
QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(),
136
QtFuture::makeExceptionalFuture(), QFutureWatcher, {Qt Concurrent}
137
*/
138
139
/*! \fn template <typename T> QFuture<T>::QFuture()
140
141
Constructs an empty, canceled future.
142
*/
143
144
/*! \fn template <typename T> QFuture<T>::QFuture(const QFuture<T> &other)
145
146
Constructs a copy of \a other.
147
148
\sa operator=()
149
*/
150
151
/*! \fn template <typename T> QFuture<T>::QFuture(QFutureInterface<T> *resultHolder)
152
\internal
153
*/
154
155
/*! \fn template <typename T> QFuture<T>::~QFuture()
156
157
Destroys the future.
158
159
Note that this neither waits nor cancels the asynchronous computation. Use
160
waitForFinished() or QFutureSynchronizer when you need to ensure that the
161
computation is completed before the future is destroyed.
162
*/
163
164
/*! \fn template <typename T> QFuture<T> &QFuture<T>::operator=(const QFuture<T> &other)
165
166
Assigns \a other to this future and returns a reference to this future.
167
*/
168
169
/*! \fn template <typename T> void QFuture<T>::cancel()
170
171
Cancels the asynchronous computation represented by this future. Note that
172
the cancellation is asynchronous. Use waitForFinished() after calling
173
cancel() when you need synchronous cancellation.
174
175
Results currently available may still be accessed on a canceled future,
176
but new results will \e not become available after calling this function.
177
Any QFutureWatcher object that is watching this future will not deliver
178
progress and result ready signals on a canceled future.
179
180
Be aware that not all running asynchronous computations can be canceled.
181
For example, the future returned by QtConcurrent::run() cannot be canceled;
182
but the future returned by QtConcurrent::mappedReduced() can.
183
184
\sa cancelChain()
185
*/
186
187
/*! \fn template <typename T> bool QFuture<T>::isCanceled() const
188
189
Returns \c true if the asynchronous computation has been canceled with the
190
cancel() function; otherwise returns \c false.
191
192
Be aware that the computation may still be running even though this
193
function returns \c true. See cancel() for more details.
194
*/
195
196
/*!
197
\fn template <typename T> void QFuture<T>::cancelChain()
198
\since 6.10
199
200
Cancels the entire continuation chain. All already-finished futures are
201
unchanged and their results are still available. Every pending continuation
202
is canceled, and its \l {onCanceled()} handler is called, if it exists in
203
the continuation chain.
204
205
\snippet code/src_corelib_thread_qfuture.cpp 38
206
207
In the example, if the chain is canceled before the \c {Then 2} continuation
208
is executed, both \c {OnCanceled 1} and \c {OnCanceled 2} cancellation
209
handlers will be invoked.
210
211
If the chain is canceled after \c {Then 2}, but before \c {Then 4}, then
212
only \c {OnCanceled 2} will be invoked.
213
214
\note When called on an already finished future, this method has no effect.
215
It's recommended to use it on the QFuture object that represents the entire
216
continuation chain, like it's shown in the example above.
217
218
\sa cancel()
219
*/
220
221
#
if
QT_DEPRECATED_SINCE
(
6
,
0
)
222
/*! \fn template <typename T> void QFuture<T>::setPaused(bool paused)
223
224
\deprecated [6.0] Use setSuspended() instead.
225
226
If \a paused is true, this function pauses the asynchronous computation
227
represented by the future. If the computation is already paused, this
228
function does nothing. Any QFutureWatcher object that is watching this
229
future will stop delivering progress and result ready signals while the
230
future is paused. Signal delivery will continue once the future is
231
resumed.
232
233
If \a paused is false, this function resumes the asynchronous computation.
234
If the computation was not previously paused, this function does nothing.
235
236
Be aware that not all computations can be paused. For example, the future
237
returned by QtConcurrent::run() cannot be paused; but the future returned
238
by QtConcurrent::mappedReduced() can.
239
240
\sa suspend(), resume(), toggleSuspended()
241
*/
242
243
/*! \fn template <typename T> bool QFuture<T>::isPaused() const
244
245
\deprecated [6.0] Use isSuspending() or isSuspended() instead.
246
247
Returns \c true if the asynchronous computation has been paused with the
248
pause() function; otherwise returns \c false.
249
250
Be aware that the computation may still be running even though this
251
function returns \c true. See setPaused() for more details. To check
252
if pause actually took effect, use isSuspended() instead.
253
254
\sa toggleSuspended(), isSuspended()
255
*/
256
257
/*! \fn template <typename T> void QFuture<T>::pause()
258
259
\deprecated [6.0] Use suspend() instead.
260
261
Pauses the asynchronous computation represented by this future. This is a
262
convenience method that simply calls setPaused(true).
263
264
\sa resume()
265
*/
266
267
/*! \fn template <typename T> void QFuture<T>::togglePaused()
268
269
\deprecated [6.0] Use toggleSuspended() instead.
270
271
Toggles the paused state of the asynchronous computation. In other words,
272
if the computation is currently paused, calling this function resumes it;
273
if the computation is running, it is paused. This is a convenience method
274
for calling setPaused(!isPaused()).
275
276
\sa setSuspended(), suspend(), resume()
277
*/
278
#
endif
// QT_DEPRECATED_SINCE(6, 0)
279
280
/*! \fn template <typename T> void QFuture<T>::setSuspended(bool suspend)
281
282
\since 6.0
283
284
If \a suspend is true, this function suspends the asynchronous computation
285
represented by the future(). If the computation is already suspended, this
286
function does nothing. QFutureWatcher will not immediately stop delivering
287
progress and result ready signals when the future is suspended. At the moment
288
of suspending there may still be computations that are in progress and cannot
289
be stopped. Signals for such computations will still be delivered.
290
291
If \a suspend is false, this function resumes the asynchronous computation.
292
If the computation was not previously suspended, this function does nothing.
293
294
Be aware that not all computations can be suspended. For example, the
295
QFuture returned by QtConcurrent::run() cannot be suspended; but the QFuture
296
returned by QtConcurrent::mappedReduced() can.
297
298
\sa suspend(), resume(), toggleSuspended()
299
*/
300
301
/*! \fn template <typename T> bool QFuture<T>::isSuspending() const
302
303
\since 6.0
304
305
Returns \c true if the asynchronous computation has been suspended with the
306
suspend() function, but the work is not yet suspended, and computation is still
307
running. Returns \c false otherwise.
308
309
To check if suspension is actually in effect, use isSuspended() instead.
310
311
\sa setSuspended(), toggleSuspended(), isSuspended()
312
*/
313
314
/*! \fn template <typename T> bool QFuture<T>::isSuspended() const
315
316
\since 6.0
317
318
Returns \c true if a suspension of the asynchronous computation has been
319
requested, and it is in effect, meaning that no more results or progress
320
changes are expected.
321
322
\sa setSuspended(), toggleSuspended(), isSuspending()
323
*/
324
325
/*! \fn template <typename T> void QFuture<T>::suspend()
326
327
\since 6.0
328
329
Suspends the asynchronous computation represented by this future. This is a
330
convenience method that simply calls setSuspended(true).
331
332
\sa resume()
333
*/
334
335
/*! \fn template <typename T> void QFuture<T>::resume()
336
337
Resumes the asynchronous computation represented by the future(). This is
338
a convenience method that simply calls setSuspended(false).
339
340
\sa suspend()
341
*/
342
343
/*! \fn template <typename T> void QFuture<T>::toggleSuspended()
344
345
\since 6.0
346
347
Toggles the suspended state of the asynchronous computation. In other words,
348
if the computation is currently suspending or suspended, calling this
349
function resumes it; if the computation is running, it is suspended. This is a
350
convenience method for calling setSuspended(!(isSuspending() || isSuspended())).
351
352
\sa setSuspended(), suspend(), resume()
353
*/
354
355
/*! \fn template <typename T> bool QFuture<T>::isStarted() const
356
357
Returns \c true if the asynchronous computation represented by this future
358
has been started; otherwise returns \c false.
359
*/
360
361
/*! \fn template <typename T> bool QFuture<T>::isFinished() const
362
363
Returns \c true if the asynchronous computation represented by this future
364
has finished; otherwise returns \c false.
365
*/
366
367
/*! \fn template <typename T> bool QFuture<T>::isRunning() const
368
369
Returns \c true if the asynchronous computation represented by this future is
370
currently running; otherwise returns \c false.
371
*/
372
373
/*! \fn template <typename T> int QFuture<T>::resultCount() const
374
375
Returns the number of continuous results available in this future. The real
376
number of results stored might be different from this value, due to gaps
377
in the result set. It is always safe to iterate through the results from 0
378
to resultCount().
379
\sa result(), resultAt(), results(), takeResult()
380
*/
381
382
/*! \fn template <typename T> int QFuture<T>::progressValue() const
383
384
Returns the current progress value, which is between the progressMinimum()
385
and progressMaximum().
386
387
\sa progressMinimum(), progressMaximum()
388
*/
389
390
/*! \fn template <typename T> int QFuture<T>::progressMinimum() const
391
392
Returns the minimum progressValue().
393
394
\sa progressValue(), progressMaximum()
395
*/
396
397
/*! \fn template <typename T> int QFuture<T>::progressMaximum() const
398
399
Returns the maximum progressValue().
400
401
\sa progressValue(), progressMinimum()
402
*/
403
404
/*! \fn template <typename T> QString QFuture<T>::progressText() const
405
406
Returns the (optional) textual representation of the progress as reported
407
by the asynchronous computation.
408
409
Be aware that not all computations provide a textual representation of the
410
progress, and as such, this function may return an empty string.
411
*/
412
413
/*! \fn template <typename T> void QFuture<T>::waitForFinished()
414
415
Waits for the asynchronous computation to finish (including cancel()ed
416
computations), i.e. until isFinished() returns \c true.
417
*/
418
419
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture<T>::result() const
420
421
Returns the first result in the future. If the result is not immediately
422
available, this function will block and wait for the result to become
423
available. This is a convenience method for calling resultAt(0). Note
424
that \c result() returns a copy of the internally stored result. If \c T is
425
a move-only type, or you don't want to copy the result, use takeResult()
426
instead.
427
428
\note Calling \c result() leads to undefined behavior if isValid()
429
returns \c false for this QFuture.
430
431
\sa resultAt(), results(), takeResult()
432
*/
433
434
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture<T>::resultAt(int index) const
435
436
Returns the result at \a index in the future. If the result is not
437
immediately available, this function will block and wait for the result to
438
become available.
439
440
\note Calling resultAt() leads to undefined behavior if isValid()
441
returns \c false for this QFuture.
442
443
\sa result(), results(), takeResult(), resultCount()
444
*/
445
446
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> bool QFuture<T>::isResultReadyAt(int index) const
447
448
Returns \c true if the result at \a index is immediately available; otherwise
449
returns \c false.
450
451
\note Calling isResultReadyAt() leads to undefined behavior if isValid()
452
returns \c false for this QFuture.
453
454
\sa resultAt(), resultCount(), takeResult()
455
*/
456
457
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QList<T> QFuture<T>::results() const
458
459
Returns all results from the future. If the results are not immediately available,
460
this function will block and wait for them to become available. Note that
461
\c results() returns a copy of the internally stored results. Getting all
462
results of a move-only type \c T is not supported at the moment. However you can
463
still iterate through the list of move-only results by using \l{STL-style iterators}
464
or read-only \l{Java-style iterators}.
465
466
\note Calling \c results() leads to undefined behavior if isValid()
467
returns \c false for this QFuture.
468
469
\sa result(), resultAt(), takeResult(), resultCount(), isValid()
470
*/
471
472
#
if
0
473
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> std::vector<T> QFuture<T>::takeResults()
474
475
If isValid() returns \c false, calling this function leads to undefined behavior.
476
takeResults() takes all results from the QFuture object and invalidates it
477
(isValid() will return \c false for this future). If the results are
478
not immediately available, this function will block and wait for them to
479
become available. This function tries to use move semantics for the results
480
if available and falls back to copy construction if the type is not movable.
481
482
\note QFuture in general allows sharing the results between different QFuture
483
objects (and potentially between different threads). takeResults() was introduced
484
to make QFuture also work with move-only types (like std::unique_ptr), so it
485
assumes that only one thread can move the results out of the future, and only
486
once.
487
488
\sa takeResult(), result(), resultAt(), results(), resultCount(), isValid()
489
*/
490
#
endif
491
492
/*! \fn template <typename T> template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>> std::vector<T> QFuture<T>::takeResult()
493
494
\since 6.0
495
496
Call this function only if isValid() returns \c true, otherwise
497
the behavior is undefined. This function takes (moves) the first result from
498
the QFuture object, when only one result is expected. If there are any other
499
results, they are discarded after taking the first one.
500
If the result is not immediately available, this function will block and
501
wait for the result to become available. The QFuture will try to use move
502
semantics if possible, and will fall back to copy construction if the type
503
is not movable. After the result was taken, isValid() will evaluate
504
as \c false.
505
506
\note QFuture in general allows sharing the results between different QFuture
507
objects (and potentially between different threads). takeResult() was introduced
508
to make QFuture also work with move-only types (like std::unique_ptr), so it
509
assumes that only one thread can move the results out of the future, and
510
do it only once. Also note that taking the list of all results is not supported
511
at the moment. However you can still iterate through the list of move-only
512
results by using \l{STL-style iterators} or read-only \l{Java-style iterators}.
513
514
\sa result(), results(), resultAt(), isValid()
515
*/
516
517
/*! \fn template <typename T> bool QFuture<T>::isValid() const
518
519
\since 6.0
520
521
Returns \c true if a result or results can be accessed or taken from this
522
QFuture object. Returns \c false after the result was taken from the future.
523
524
\note The return value of this function only implies whether the future
525
result can be consumed, not if it is ready. This function will return
526
\c true when the related QPromise is started, but the result is not yet
527
ready. To test readiness, call \l isResultReadyAt() or \l isFinished().
528
529
\sa takeResult(), result(), results(), resultAt(), isFinished(),
530
isResultReadyAt()
531
*/
532
533
/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::begin() const
534
535
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first result in the
536
future.
537
538
\sa constBegin(), end()
539
*/
540
541
/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::end() const
542
543
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary result
544
after the last result in the future.
545
546
\sa begin(), constEnd()
547
*/
548
549
/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::constBegin() const
550
551
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first result in the
552
future.
553
554
\sa begin(), constEnd()
555
*/
556
557
/*! \fn template<typename T> template<class U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture<T>::constEnd() const
558
559
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary result
560
after the last result in the future.
561
562
\sa constBegin(), end()
563
*/
564
565
/*! \class QFuture::const_iterator
566
\reentrant
567
\since 4.4
568
\inmodule QtCore
569
570
\brief The QFuture::const_iterator class provides an STL-style const
571
iterator for QFuture.
572
573
QFuture provides both \l{STL-style iterators} and \l{Java-style iterators}.
574
The STL-style iterators are more low-level and more cumbersome to use; on
575
the other hand, they are slightly faster and, for developers who already
576
know STL, have the advantage of familiarity.
577
578
The default QFuture::const_iterator constructor creates an uninitialized
579
iterator. You must initialize it using a QFuture function like
580
QFuture::constBegin() or QFuture::constEnd() before you start iterating.
581
Here's a typical loop that prints all the results available in a future:
582
583
\snippet code/src_corelib_thread_qfuture.cpp 0
584
585
\sa QFutureIterator, QFuture
586
*/
587
588
/*! \typedef QFuture::const_iterator::iterator_category
589
590
Typedef for std::bidirectional_iterator_tag. Provided for STL compatibility.
591
*/
592
593
/*! \typedef QFuture::const_iterator::difference_type
594
595
Typedef for ptrdiff_t. Provided for STL compatibility.
596
*/
597
598
/*! \typedef QFuture::const_iterator::value_type
599
600
Typedef for T. Provided for STL compatibility.
601
*/
602
603
/*! \typedef QFuture::const_iterator::pointer
604
605
Typedef for const T *. Provided for STL compatibility.
606
*/
607
608
/*! \typedef QFuture::const_iterator::reference
609
610
Typedef for const T &. Provided for STL compatibility.
611
*/
612
613
/*! \fn template <typename T> QFuture<T>::const_iterator::const_iterator()
614
615
Constructs an uninitialized iterator.
616
617
Functions like operator*() and operator++() should not be called on an
618
uninitialized iterartor. Use operator=() to assign a value to it before
619
using it.
620
621
\sa QFuture::constBegin(), QFuture::constEnd()
622
*/
623
624
/*! \fn template <typename T> QFuture<T>::const_iterator::const_iterator(QFuture const * const future, int index)
625
\internal
626
*/
627
628
/*! \fn template <typename T> QFuture<T>::const_iterator::const_iterator(const const_iterator &other)
629
630
Constructs a copy of \a other.
631
*/
632
633
/*! \fn template <typename T> QFuture<T>::const_iterator &QFuture<T>::const_iterator::operator=(const const_iterator &other)
634
635
Assigns \a other to this iterator.
636
*/
637
638
/*! \fn template <typename T> const T &QFuture<T>::const_iterator::operator*() const
639
640
Returns the current result.
641
*/
642
643
/*! \fn template <typename T> const T *QFuture<T>::const_iterator::operator->() const
644
645
Returns a pointer to the current result.
646
*/
647
648
/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator!=(const const_iterator &lhs, const const_iterator &rhs)
649
650
Returns \c true if \a lhs points to a different result than \a rhs iterator;
651
otherwise returns \c false.
652
653
\sa operator==()
654
*/
655
656
/*! \fn template <typename T> bool QFuture<T>::const_iterator::operator==(const const_iterator &lhs, const const_iterator &rhs)
657
658
Returns \c true if \a lhs points to the same result as \a rhs iterator;
659
otherwise returns \c false.
660
661
\sa operator!=()
662
*/
663
664
/*! \fn template <typename T> QFuture<T>::const_iterator &QFuture<T>::const_iterator::operator++()
665
666
The prefix \c{++} operator (\c{++it}) advances the iterator to the next result
667
in the future and returns an iterator to the new current result.
668
669
Calling this function on QFuture<T>::constEnd() leads to undefined results.
670
671
\sa operator--()
672
*/
673
674
/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::const_iterator::operator++(int)
675
676
\overload
677
678
The postfix \c{++} operator (\c{it++}) advances the iterator to the next
679
result in the future and returns an iterator to the previously current
680
result.
681
*/
682
683
/*! \fn template <typename T> QFuture<T>::const_iterator &QFuture<T>::const_iterator::operator--()
684
685
The prefix \c{--} operator (\c{--it}) makes the preceding result current and
686
returns an iterator to the new current result.
687
688
Calling this function on QFuture<T>::constBegin() leads to undefined results.
689
690
\sa operator++()
691
*/
692
693
/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::const_iterator::operator--(int)
694
695
\overload
696
697
The postfix \c{--} operator (\c{it--}) makes the preceding result current and
698
returns an iterator to the previously current result.
699
*/
700
701
/*! \fn template <typename T> QFuture<T>::const_iterator &QFuture<T>::const_iterator::operator+=(int j)
702
703
Advances the iterator by \a j results. (If \a j is negative, the iterator
704
goes backward.)
705
706
\sa operator-=(), operator+()
707
*/
708
709
/*! \fn template <typename T> QFuture<T>::const_iterator &QFuture<T>::const_iterator::operator-=(int j)
710
711
Makes the iterator go back by \a j results. (If \a j is negative, the
712
iterator goes forward.)
713
714
\sa operator+=(), operator-()
715
*/
716
717
/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::const_iterator::operator+(int j) const
718
719
Returns an iterator to the results at \a j positions forward from this
720
iterator. (If \a j is negative, the iterator goes backward.)
721
722
\sa operator-(), operator+=()
723
*/
724
725
/*! \fn template <typename T> QFuture<T>::const_iterator QFuture<T>::const_iterator::operator-(int j) const
726
727
Returns an iterator to the result at \a j positions backward from this
728
iterator. (If \a j is negative, the iterator goes forward.)
729
730
\sa operator+(), operator-=()
731
*/
732
733
/*! \typedef QFuture::ConstIterator
734
735
Qt-style synonym for QFuture::const_iterator.
736
*/
737
738
/*!
739
\class QFutureIterator
740
\reentrant
741
\since 4.4
742
\inmodule QtCore
743
744
\brief The QFutureIterator class provides a Java-style const iterator for
745
QFuture.
746
747
QFuture has both \l{Java-style iterators} and \l{STL-style iterators}. The
748
Java-style iterators are more high-level and easier to use than the
749
STL-style iterators; on the other hand, they are slightly less efficient.
750
751
An alternative to using iterators is to use index positions. Some QFuture
752
member functions take an index as their first parameter, making it
753
possible to access results without using iterators.
754
755
QFutureIterator<T> allows you to iterate over a QFuture<T>. Note that
756
there is no mutable iterator for QFuture (unlike the other Java-style
757
iterators).
758
759
The QFutureIterator constructor takes a QFuture as its argument. After
760
construction, the iterator is located at the very beginning of the result
761
list (i.e. before the first result). Here's how to iterate over all the
762
results sequentially:
763
764
\snippet code/src_corelib_thread_qfuture.cpp 1
765
766
The next() function returns the next result (waiting for it to become
767
available, if necessary) from the future and advances the iterator. Unlike
768
STL-style iterators, Java-style iterators point \e between results rather
769
than directly \e at results. The first call to next() advances the iterator
770
to the position between the first and second result, and returns the first
771
result; the second call to next() advances the iterator to the position
772
between the second and third result, and returns the second result; and
773
so on.
774
775
\image javaiterators1.png
776
777
Here's how to iterate over the elements in reverse order:
778
779
\snippet code/src_corelib_thread_qfuture.cpp 2
780
781
If you want to find all occurrences of a particular value, use findNext()
782
or findPrevious() in a loop.
783
784
Multiple iterators can be used on the same future. If the future is
785
modified while a QFutureIterator is active, the QFutureIterator will
786
continue iterating over the original future, ignoring the modified copy.
787
788
\sa QFuture::const_iterator, QFuture
789
*/
790
791
/*!
792
\fn template <typename T> QFutureIterator<T>::QFutureIterator(const QFuture<T> &future)
793
794
Constructs an iterator for traversing \a future. The iterator is set to be
795
at the front of the result list (before the first result).
796
797
\sa operator=()
798
*/
799
800
/*! \fn template <typename T> QFutureIterator<T> &QFutureIterator<T>::operator=(const QFuture<T> &future)
801
802
Makes the iterator operate on \a future. The iterator is set to be at the
803
front of the result list (before the first result).
804
805
\sa toFront(), toBack()
806
*/
807
808
/*! \fn template <typename T> void QFutureIterator<T>::toFront()
809
810
Moves the iterator to the front of the result list (before the first
811
result).
812
813
\sa toBack(), next()
814
*/
815
816
/*! \fn template <typename T> void QFutureIterator<T>::toBack()
817
818
Moves the iterator to the back of the result list (after the last result).
819
820
\sa toFront(), previous()
821
*/
822
823
/*! \fn template <typename T> bool QFutureIterator<T>::hasNext() const
824
825
Returns \c true if there is at least one result ahead of the iterator, e.g.,
826
the iterator is \e not at the back of the result list; otherwise returns
827
false.
828
829
\sa hasPrevious(), next()
830
*/
831
832
/*! \fn template <typename T> const T &QFutureIterator<T>::next()
833
834
Returns the next result and advances the iterator by one position.
835
836
Calling this function on an iterator located at the back of the result
837
list leads to undefined results.
838
839
\sa hasNext(), peekNext(), previous()
840
*/
841
842
/*! \fn template <typename T> const T &QFutureIterator<T>::peekNext() const
843
844
Returns the next result without moving the iterator.
845
846
Calling this function on an iterator located at the back of the result
847
list leads to undefined results.
848
849
\sa hasNext(), next(), peekPrevious()
850
*/
851
852
/*! \fn template <typename T> bool QFutureIterator<T>::hasPrevious() const
853
854
Returns \c true if there is at least one result ahead of the iterator, e.g.,
855
the iterator is \e not at the front of the result list; otherwise returns
856
false.
857
858
\sa hasNext(), previous()
859
*/
860
861
/*! \fn template <typename T> const T &QFutureIterator<T>::previous()
862
863
Returns the previous result and moves the iterator back by one position.
864
865
Calling this function on an iterator located at the front of the result
866
list leads to undefined results.
867
868
\sa hasPrevious(), peekPrevious(), next()
869
*/
870
871
/*! \fn template <typename T> const T &QFutureIterator<T>::peekPrevious() const
872
873
Returns the previous result without moving the iterator.
874
875
Calling this function on an iterator located at the front of the result
876
list leads to undefined results.
877
878
\sa hasPrevious(), previous(), peekNext()
879
*/
880
881
/*! \fn template <typename T> bool QFutureIterator<T>::findNext(const T &value)
882
883
Searches for \a value starting from the current iterator position forward.
884
Returns \c true if \a value is found; otherwise returns \c false.
885
886
After the call, if \a value was found, the iterator is positioned just
887
after the matching result; otherwise, the iterator is positioned at the
888
back of the result list.
889
890
\sa findPrevious()
891
*/
892
893
/*! \fn template <typename T> bool QFutureIterator<T>::findPrevious(const T &value)
894
895
Searches for \a value starting from the current iterator position
896
backward. Returns \c true if \a value is found; otherwise returns \c false.
897
898
After the call, if \a value was found, the iterator is positioned just
899
before the matching result; otherwise, the iterator is positioned at the
900
front of the result list.
901
902
\sa findNext()
903
*/
904
905
/*!
906
\namespace QtFuture
907
\inheaderfile QFuture
908
909
\inmodule QtCore
910
\brief Contains miscellaneous identifiers used by the QFuture class.
911
*/
912
913
914
/*!
915
\enum QtFuture::Launch
916
917
\since 6.0
918
919
Represents execution policies for running a QFuture continuation.
920
921
\value Sync The continuation will be launched in the same thread that
922
fulfills the promise associated with the future to which the
923
continuation was attached, or if it has already finished, the
924
continuation will be invoked immediately, in the thread that
925
executes \c then().
926
927
\value Async The continuation will be launched in a separate thread taken from
928
the global QThreadPool.
929
930
\value Inherit The continuation will inherit the launch policy or thread pool of
931
the future to which it is attached.
932
933
\c Sync is used as a default launch policy.
934
935
\sa QFuture::then(), QThreadPool::globalInstance()
936
937
*/
938
939
/*!
940
\class QtFuture::WhenAnyResult
941
\inmodule QtCore
942
\ingroup thread
943
\brief QtFuture::WhenAnyResult is used to represent the result of QtFuture::whenAny().
944
\since 6.3
945
946
The \c {QtFuture::WhenAnyResult<T>} struct is used for packaging the copy and
947
the index of the first completed \c QFuture<T> in the sequence of futures
948
packaging type \c T that are passed to QtFuture::whenAny().
949
950
\sa QFuture, QtFuture::whenAny()
951
*/
952
953
/*!
954
\variable QtFuture::WhenAnyResult::index
955
956
The field contains the index of the first completed QFuture in the sequence
957
of futures passed to whenAny(). It has type \c qsizetype.
958
959
\sa QtFuture::whenAny()
960
*/
961
962
/*!
963
\variable QtFuture::WhenAnyResult::future
964
965
The field contains the copy of the first completed QFuture that packages type
966
\c T, where \c T is the type packaged by the futures passed to whenAny().
967
968
\sa QtFuture::whenAny()
969
*/
970
971
/*! \fn template<class Sender, class Signal, typename = QtPrivate::EnableIfInvocable<Sender, Signal>> static QFuture<ArgsType<Signal>> QtFuture::connect(Sender *sender, Signal signal)
972
973
Creates and returns a QFuture which will become available when the \a sender emits
974
the \a signal. If the \a signal takes no arguments, a QFuture<void> is returned. If
975
the \a signal takes a single argument, the resulted QFuture will be filled with the
976
signal's argument value. If the \a signal takes multiple arguments, the resulted QFuture
977
is filled with std::tuple storing the values of signal's arguments. If the \a sender
978
is destroyed before the \a signal is emitted, the resulted QFuture will be canceled.
979
980
For example, let's say we have the following object:
981
982
\snippet code/src_corelib_thread_qfuture.cpp 10
983
984
We can connect its signals to QFuture objects in the following way:
985
986
\snippet code/src_corelib_thread_qfuture.cpp 11
987
988
We can also chain continuations to be run when a signal is emitted:
989
990
\snippet code/src_corelib_thread_qfuture.cpp 12
991
992
You can also start the continuation in a new thread or a custom thread pool
993
using QtFuture::Launch policies. For example:
994
995
\snippet code/src_corelib_thread_qfuture.cpp 13
996
997
Throwing an exception from a slot invoked by Qt's signal-slot connection
998
is considered to be an undefined behavior, if it is not handled within the
999
slot. But with QFuture::connect(), you can throw and handle exceptions from
1000
the continuations:
1001
1002
\snippet code/src_corelib_thread_qfuture.cpp 14
1003
1004
\note The connected future will be fulfilled only once, when the signal is
1005
emitted for the first time.
1006
1007
\sa QFuture, QFuture::then()
1008
*/
1009
1010
/*! \fn template<typename T, typename = QtPrivate::EnableForNonVoid<T>> static QFuture<std::decay_t<T>> QtFuture::makeReadyFuture(T &&value)
1011
1012
\since 6.1
1013
\overload
1014
\deprecated [6.6] Use makeReadyValueFuture() instead.
1015
1016
Creates and returns a QFuture which already has a result \a value.
1017
The returned QFuture has a type of std::decay_t<T>, where T is not void.
1018
1019
\code
1020
auto f = QtFuture::makeReadyFuture(std::make_unique<int>(42));
1021
...
1022
const int result = *f.takeResult(); // result == 42
1023
\endcode
1024
1025
The method should be avoided because
1026
it has an inconsistent set of overloads. From Qt 6.10 onwards, using it
1027
in code will result in compiler warnings.
1028
1029
\sa QFuture, QtFuture::makeReadyVoidFuture(),
1030
QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(),
1031
QtFuture::makeExceptionalFuture()
1032
*/
1033
1034
/*! \fn QFuture<void> QtFuture::makeReadyFuture()
1035
1036
\since 6.1
1037
\overload
1038
\deprecated [6.6] Use makeReadyVoidFuture() instead.
1039
1040
Creates and returns a void QFuture. Such QFuture can't store any result.
1041
One can use it to query the state of the computation.
1042
The returned QFuture will always be in the finished state.
1043
1044
\code
1045
auto f = QtFuture::makeReadyFuture();
1046
...
1047
const bool started = f.isStarted(); // started == true
1048
const bool running = f.isRunning(); // running == false
1049
const bool finished = f.isFinished(); // finished == true
1050
\endcode
1051
1052
The method should be avoided because
1053
it has an inconsistent set of overloads. From Qt 6.10 onwards, using it
1054
in code will result in compiler warnings.
1055
1056
\sa QFuture, QFuture::isStarted(), QFuture::isRunning(),
1057
QFuture::isFinished(), QtFuture::makeReadyVoidFuture(),
1058
QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(),
1059
QtFuture::makeExceptionalFuture()
1060
*/
1061
1062
/*! \fn template<typename T> static QFuture<T> QtFuture::makeReadyFuture(const QList<T> &values)
1063
1064
\since 6.1
1065
\overload
1066
\deprecated [6.6] Use makeReadyRangeFuture() instead.
1067
1068
Creates and returns a QFuture which already has multiple results set from \a values.
1069
1070
\code
1071
const QList<int> values { 1, 2, 3 };
1072
auto f = QtFuture::makeReadyFuture(values);
1073
...
1074
const int count = f.resultCount(); // count == 3
1075
const auto results = f.results(); // results == { 1, 2, 3 }
1076
\endcode
1077
1078
The method should be avoided because
1079
it has an inconsistent set of overloads. From Qt 6.10 onwards, using it
1080
in code will result in compiler warnings.
1081
1082
\sa QFuture, QtFuture::makeReadyVoidFuture(),
1083
QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(),
1084
QtFuture::makeExceptionalFuture()
1085
*/
1086
1087
/*! \fn template<typename T> static QFuture<std::decay_t<T>> QtFuture::makeReadyValueFuture(T &&value)
1088
1089
\since 6.6
1090
1091
Creates and returns a QFuture which already has a result \a value.
1092
The returned QFuture has a type of std::decay_t<T>, where T is not void.
1093
The returned QFuture will already be in the finished state.
1094
1095
\snippet code/src_corelib_thread_qfuture.cpp 35
1096
1097
\sa QFuture, QtFuture::makeReadyRangeFuture(),
1098
QtFuture::makeReadyVoidFuture(), QtFuture::makeExceptionalFuture()
1099
*/
1100
1101
/*! \fn QFuture<void> QtFuture::makeReadyVoidFuture()
1102
1103
\since 6.6
1104
1105
Creates and returns a void QFuture. Such QFuture can't store any result.
1106
One can use it to query the state of the computation.
1107
The returned QFuture will already be in the finished state.
1108
1109
\snippet code/src_corelib_thread_qfuture.cpp 36
1110
1111
\sa QFuture, QFuture::isStarted(), QFuture::isRunning(),
1112
QFuture::isFinished(), QtFuture::makeReadyValueFuture(),
1113
QtFuture::makeReadyRangeFuture(), QtFuture::makeExceptionalFuture()
1114
*/
1115
1116
/*! \fn template<typename T> static QFuture<T> QtFuture::makeExceptionalFuture(const QException &exception)
1117
1118
\since 6.1
1119
1120
Creates and returns a QFuture which already has an exception \a exception.
1121
1122
\code
1123
QException e;
1124
auto f = QtFuture::makeExceptionalFuture<int>(e);
1125
...
1126
try {
1127
f.result(); // throws QException
1128
} catch (QException &) {
1129
// handle exception here
1130
}
1131
\endcode
1132
1133
\sa QFuture, QException, QtFuture::makeReadyVoidFuture(),
1134
QtFuture::makeReadyValueFuture()
1135
*/
1136
1137
/*! \fn template<typename T> static QFuture<T> QtFuture::makeExceptionalFuture(std::exception_ptr exception)
1138
1139
\since 6.1
1140
\overload
1141
1142
Creates and returns a QFuture which already has an exception \a exception.
1143
1144
\code
1145
struct TestException
1146
{
1147
};
1148
...
1149
auto exception = std::make_exception_ptr(TestException());
1150
auto f = QtFuture::makeExceptionalFuture<int>(exception);
1151
...
1152
try {
1153
f.result(); // throws TestException
1154
} catch (TestException &) {
1155
// handle exception here
1156
}
1157
\endcode
1158
1159
\sa QFuture, QException, QtFuture::makeReadyVoidFuture(),
1160
QtFuture::makeReadyValueFuture()
1161
*/
1162
1163
/*! \fn template<typename Container, QtFuture::if_container_with_input_iterators<Container>> static QFuture<QtFuture::ContainedType<Container>> QtFuture::makeReadyRangeFuture(Container &&container)
1164
1165
\since 6.6
1166
\overload
1167
1168
Takes an input container \a container and returns a QFuture with multiple
1169
results of type \c ContainedType initialized from the values of the
1170
\a container.
1171
1172
\snippet code/src_corelib_thread_qfuture.cpp 32
1173
\dots
1174
\snippet code/src_corelib_thread_qfuture.cpp 34
1175
1176
\constraints the \c Container has input iterators.
1177
1178
\sa QFuture, QtFuture::makeReadyVoidFuture(),
1179
QtFuture::makeReadyValueFuture(), QtFuture::makeExceptionalFuture()
1180
*/
1181
1182
/*! \fn template<typename ValueType> static QFuture<ValueType> QtFuture::makeReadyRangeFuture(std::initializer_list<ValueType> values)
1183
1184
\since 6.6
1185
\overload
1186
1187
Returns a QFuture with multiple results of type \c ValueType initialized
1188
from the input initializer list \a values.
1189
1190
\snippet code/src_corelib_thread_qfuture.cpp 33
1191
\dots
1192
\snippet code/src_corelib_thread_qfuture.cpp 34
1193
1194
\sa QFuture, QtFuture::makeReadyVoidFuture(),
1195
QtFuture::makeReadyValueFuture(), QtFuture::makeExceptionalFuture()
1196
*/
1197
1198
/*! \fn template<class T> template<class Function> QFuture<typename QFuture<T>::ResultType<Function>> QFuture<T>::then(Function &&function)
1199
1200
\since 6.0
1201
\overload
1202
1203
Attaches a continuation to this future, allowing to chain multiple asynchronous
1204
computations if desired, using the \l {QtFuture::Launch}{Sync} policy.
1205
\a function is a callable that takes an argument of the type packaged by this
1206
future if this has a result (is not a QFuture<void>). Otherwise it takes no
1207
arguments. This method returns a new QFuture that packages a value of the type
1208
returned by \a function. The returned future will be in an uninitialized state
1209
until the attached continuation is invoked, or until this future fails or is
1210
canceled.
1211
1212
\note Use other overloads of this method if you need to launch the continuation in
1213
a separate thread.
1214
1215
You can chain multiple operations like this:
1216
1217
\code
1218
QFuture<int> future = ...;
1219
future.then([](int res1){ ... }).then([](int res2){ ... })...
1220
\endcode
1221
1222
Or:
1223
\code
1224
QFuture<void> future = ...;
1225
future.then([](){ ... }).then([](){ ... })...
1226
\endcode
1227
1228
The continuation can also take a QFuture argument (instead of its value), representing
1229
the previous future. This can be useful if, for example, QFuture has multiple results,
1230
and the user wants to access them inside the continuation. Or the user needs to handle
1231
the exception of the previous future inside the continuation, to not interrupt the chain
1232
of multiple continuations. For example:
1233
1234
\snippet code/src_corelib_thread_qfuture.cpp 5
1235
1236
\warning If the previous future contains multiple results of type \c {T},
1237
and the continuation takes an argument of type \c {T} as a parameter, only
1238
the first result from the previous QFuture will be handled in the
1239
continuation!
1240
1241
If the previous future throws an exception and it is not handled inside the
1242
continuation, the exception will be propagated to the continuation future, to
1243
allow the caller to handle it:
1244
1245
\snippet code/src_corelib_thread_qfuture.cpp 6
1246
1247
In this case the whole chain of continuations will be interrupted.
1248
1249
\note If this future gets canceled, the continuations attached to it will
1250
also be canceled.
1251
1252
\sa onFailed(), onCanceled()
1253
*/
1254
1255
/*! \fn template<class T> template<class Function> QFuture<typename QFuture<T>::ResultType<Function>> QFuture<T>::then(QtFuture::Launch policy, Function &&function)
1256
1257
\since 6.0
1258
\overload
1259
1260
Attaches a continuation to this future, allowing to chain multiple asynchronous
1261
computations. When the asynchronous computation represented by this future
1262
finishes, \a function will be invoked according to the given launch \a policy.
1263
A new QFuture representing the result of the continuation is returned.
1264
1265
Depending on the \a policy, continuation will be invoked in the same thread as
1266
this future, in a new thread, or will inherit the launch policy and thread pool of
1267
this future. If no launch policy is specified (see the overload taking only a callable),
1268
the \c Sync policy will be used.
1269
1270
In the following example both continuations will be invoked in a new thread (but in
1271
the same one).
1272
1273
\code
1274
QFuture<int> future = ...;
1275
future.then(QtFuture::Launch::Async, [](int res){ ... }).then([](int res2){ ... });
1276
\endcode
1277
1278
In the following example both continuations will be invoked in new threads using the
1279
same thread pool.
1280
1281
\code
1282
QFuture<int> future = ...;
1283
future.then(QtFuture::Launch::Async, [](int res){ ... })
1284
.then(QtFuture::Launch::Inherit, [](int res2){ ... });
1285
\endcode
1286
1287
See the documentation of the other overload for more details about \a function.
1288
1289
\sa onFailed(), onCanceled()
1290
*/
1291
1292
/*! \fn template<class T> template<class Function> QFuture<typename QFuture<T>::ResultType<Function>> QFuture<T>::then(QThreadPool *pool, Function &&function)
1293
1294
\since 6.0
1295
\overload
1296
1297
Attaches a continuation to this future, allowing to chain multiple asynchronous
1298
computations if desired. When the asynchronous computation represented by this
1299
future finishes, \a function will be scheduled on \a pool.
1300
1301
\sa onFailed(), onCanceled()
1302
*/
1303
1304
/*! \fn template<class T> template<class Function> QFuture<typename QFuture<T>::ResultType<Function>> QFuture<T>::then(QObject *context, Function &&function)
1305
1306
\since 6.1
1307
\overload
1308
1309
Attaches a continuation to this future, allowing to chain multiple asynchronous
1310
computations if desired. When the asynchronous computation represented by this
1311
future finishes, \a function will be invoked in the thread of the \a context object.
1312
This can be useful if the continuation needs to be invoked in a specific thread.
1313
For example:
1314
1315
\snippet code/src_corelib_thread_qfuture.cpp 17
1316
1317
The continuation attached into QtConcurrent::run updates the UI elements and cannot
1318
be invoked from a non-gui thread. So \c this is provided as a context to \c .then(),
1319
to make sure that it will be invoked in the main thread.
1320
1321
The following continuations will be also invoked from the same context,
1322
unless a different context or launch policy is specified:
1323
1324
\snippet code/src_corelib_thread_qfuture.cpp 18
1325
1326
This is because by default \c .then() is invoked from the same thread as the
1327
previous one.
1328
1329
But note that if the continuation is attached after this future has already finished,
1330
it will be invoked immediately, in the thread that executes \c then():
1331
1332
\snippet code/src_corelib_thread_qfuture.cpp 20
1333
1334
In the above example if \c cachedResultsReady is \c true, and a ready future is
1335
returned, it is possible that the first \c .then() finishes before the second one
1336
is attached. In this case it will be resolved in the current thread. Therefore, when
1337
in doubt, pass the context explicitly.
1338
1339
\target context_lifetime
1340
If the \a context is destroyed before the chain has finished, the future is canceled.
1341
This implies that a cancellation handler might be invoked when the \a context is not valid
1342
anymore. To guard against this, capture the \a context as a QPointer:
1343
1344
\snippet code/src_corelib_thread_qfuture.cpp 37
1345
1346
When the context object is destroyed, cancellation happens immediately. Previous futures in the
1347
chain are \e {not} cancelled and keep running until they are finished.
1348
1349
\note When calling this method, it should be guaranteed that the \a context stays alive
1350
during setup of the chain.
1351
1352
\sa onFailed(), onCanceled()
1353
*/
1354
1355
/*! \fn template<class T> template<class Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture<T>::onFailed(Function &&handler)
1356
1357
\since 6.0
1358
1359
Attaches a failure handler to this future, to handle any exceptions. The
1360
returned future behaves exactly as this future (has the same state and result)
1361
unless this future fails with an exception.
1362
1363
The \a handler is a callable which takes either no argument or one argument, to
1364
filter by specific error types, similar to the
1365
\l {https://en.cppreference.com/w/cpp/language/try_catch} {catch} statement.
1366
It returns a value of the type packaged by this future. After the failure, the
1367
returned future packages the value returned by \a handler.
1368
1369
The handler will only be invoked if an exception is raised. If the exception
1370
is raised after this handler is attached, the handler is executed in the thread
1371
that reports the future as finished as a result of the exception. If the handler
1372
is attached after this future has already failed, it will be invoked immediately,
1373
in the thread that executes \c onFailed(). Therefore, the handler cannot always
1374
make assumptions about which thread it will be run on. Use the overload that
1375
takes a context object if you want to control which thread the handler is
1376
invoked on.
1377
1378
The example below demonstrates how to attach a failure handler:
1379
1380
\snippet code/src_corelib_thread_qfuture.cpp 7
1381
1382
If there are multiple handlers attached, the first handler that matches with the
1383
thrown exception type will be invoked. For example:
1384
1385
\snippet code/src_corelib_thread_qfuture.cpp 8
1386
1387
If none of the handlers matches with the thrown exception type, the exception
1388
will be propagated to the resulted future:
1389
1390
\snippet code/src_corelib_thread_qfuture.cpp 9
1391
1392
\note You can always attach a handler taking no argument, to handle all exception
1393
types and avoid writing the try-catch block.
1394
1395
\sa then(), onCanceled()
1396
*/
1397
1398
/*! \fn template<class T> template<class Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture<T>::onFailed(QObject *context, Function &&handler)
1399
1400
\since 6.1
1401
\overload
1402
1403
Attaches a failure handler to this future, to handle any exceptions that the future
1404
raises, or that it has already raised. Returns a QFuture of the same type as this
1405
future. The handler will be invoked only in case of an exception, in the thread of
1406
the \a context object. This can be useful if the failure needs to be handled in a
1407
specific thread. For example:
1408
1409
\snippet code/src_corelib_thread_qfuture.cpp 19
1410
1411
The failure handler attached into QtConcurrent::run updates the UI elements and cannot
1412
be invoked from a non-gui thread. So \c this is provided as a context to \c .onFailed(),
1413
to make sure that it will be invoked in the main thread.
1414
1415
If the \a context is destroyed before the chain has finished, the future is canceled.
1416
See \l {context_lifetime}{then()} for details.
1417
1418
\note When calling this method, it should be guaranteed that the \a context stays alive
1419
during setup of the chain.
1420
1421
See the documentation of the other overload for more details about \a handler.
1422
1423
\sa then(), onCanceled()
1424
*/
1425
1426
/*! \fn template<class T> template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture<T>::onCanceled(Function &&handler)
1427
1428
\since 6.0
1429
1430
Attaches a cancellation \a handler to this future. The returned future
1431
behaves exactly as this future (has the same state and result) unless
1432
this future is cancelled. The \a handler is a callable which takes no
1433
arguments and returns a value of the type packaged by this future. After
1434
cancellation, the returned future packages the value returned by \a handler.
1435
1436
If attached before the cancellation, \a handler will be invoked in the same
1437
thread that reports the future as finished after the cancellation. If the
1438
handler is attached after this future has already been canceled, it will be
1439
invoked immediately in the thread that executes \c onCanceled(). Therefore,
1440
the handler cannot always make assumptions about which thread it will be run
1441
on. Use the overload that takes a context object if you want to control
1442
which thread the handler is invoked on.
1443
1444
The example below demonstrates how to attach a cancellation handler:
1445
1446
\snippet code/src_corelib_thread_qfuture.cpp 21
1447
1448
If \c testFuture is canceled, \c {Block 3} will be called and the
1449
\c resultFuture will have \c -1 as its result. Unlike \c testFuture, it won't
1450
be in a \c Canceled state. This means that you can get its result, attach
1451
countinuations to it, and so on.
1452
1453
Also note that you can cancel the chain of continuations while they are
1454
executing via the future that started the chain. Let's say \c testFuture.cancel()
1455
was called while \c {Block 1} is already executing. The next continuation will
1456
detect that cancellation was requested, so \c {Block 2} will be skipped, and
1457
the cancellation handler (\c {Block 3}) will be called.
1458
1459
\note This method returns a new \c QFuture representing the result of the
1460
continuation chain. Canceling the resulting \c QFuture itself won't invoke the
1461
cancellation handler in the chain that lead to it. This means that if you call
1462
\c resultFuture.cancel(), \c {Block 3} won't be called: because \c resultFuture is
1463
the future that results from attaching the cancellation handler to \c testFuture,
1464
no cancellation handlers have been attached to \c resultFuture itself. Only
1465
cancellation of \c testFuture or the futures returned by continuations attached
1466
before the \c onCancelled() call can trigger \c{Block 3}.
1467
1468
\sa then(), onFailed()
1469
*/
1470
1471
/*! \fn template<class T> template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture<T>::onCanceled(QObject *context, Function &&handler)
1472
1473
\since 6.1
1474
\overload
1475
1476
Attaches a cancellation \a handler to this future, to be called when the future is
1477
canceled. The \a handler is a callable which doesn't take any arguments. It will be
1478
invoked in the thread of the \a context object. This can be useful if the cancellation
1479
needs to be handled in a specific thread.
1480
1481
If the \a context is destroyed before the chain has finished, the future is canceled.
1482
See \l {context_lifetime}{then()} for details.
1483
1484
\note When calling this method, it should be guaranteed that the \a context stays alive
1485
during setup of the chain.
1486
1487
See the documentation of the other overload for more details about \a handler.
1488
1489
\sa then(), onFailed()
1490
*/
1491
1492
/*! \fn template<class T> template<class U> QFuture<U> QFuture<T>::unwrap()
1493
1494
\since 6.4
1495
1496
Unwraps the inner future from this \c QFuture<T>, where \c T is a future
1497
of type \c QFuture<U>, i.e. this future has type of \c QFuture<QFuture<U>>.
1498
For example:
1499
1500
\snippet code/src_corelib_thread_qfuture.cpp 28
1501
1502
\c unwrappedFuture will be fulfilled as soon as the inner future nested
1503
inside the \c outerFuture is fulfilled, with the same result or exception
1504
and in the same thread that reports the inner future as finished. If the
1505
inner future is canceled, \c unwrappedFuture will also be canceled.
1506
1507
This is especially useful when chaining multiple computations, and one of
1508
them returns a \c QFuture as its result type. For example, let's say we
1509
want to download multiple images from an URL, scale the images, and reduce
1510
them to a single image using QtConcurrent::mappedReduced(). We could write
1511
something like:
1512
1513
\snippet code/src_corelib_thread_qfuture.cpp 29
1514
1515
Here \c QtConcurrent::mappedReduced() returns a \c QFuture<QImage>, so
1516
\c .then(processImages) returns a \c QFuture<QFuture<QImage>>. Since
1517
\c show() takes a \c QImage as argument, the result of \c .then(processImages)
1518
can't be passed to it directly. We need to call \c .unwrap(), that will
1519
get the result of the inner future when it's ready and pass it to the next
1520
continuation.
1521
1522
In case of multiple nesting, \c .unwrap() goes down to the innermost level:
1523
1524
\snippet code/src_corelib_thread_qfuture.cpp 30
1525
*/
1526
1527
/*! \fn template<typename OutputSequence, typename InputIt> QFuture<OutputSequence> QtFuture::whenAll(InputIt first, InputIt last)
1528
1529
\since 6.3
1530
1531
Returns a new QFuture that succeeds when all futures from \a first to \a last
1532
complete. \a first and \a last are iterators to a sequence of futures packaging
1533
type \c T. \c OutputSequence is a sequence containing all completed futures
1534
from \a first to \a last, appearing in the same order as in the input. If the
1535
type of \c OutputSequence is not specified, the resulting futures will be
1536
returned in a \c QList of \c QFuture<T>. For example:
1537
1538
\snippet code/src_corelib_thread_qfuture.cpp 22
1539
1540
\note The output sequence must support random access and the \c resize()
1541
operation.
1542
1543
If \c first equals \c last, this function returns a ready QFuture that
1544
contains an empty \c OutputSequence.
1545
1546
//! [whenAll]
1547
The returned future always completes successfully after all the specified
1548
futures complete. It doesn't matter if any of these futures completes with
1549
error or is canceled. You can use \c .then() to process the completed futures
1550
after the future returned by \c whenAll() succeeds:
1551
//! [whenAll]
1552
1553
\snippet code/src_corelib_thread_qfuture.cpp 23
1554
1555
//! [whenAll-note]
1556
\note If the input futures complete on different threads, the future returned
1557
by this method will complete in the thread that the last future completes in.
1558
Therefore, the continuations attached to the future returned by \c whenAll()
1559
cannot always make assumptions about which thread they will be run on. Use the
1560
overload of \c .then() that takes a context object if you want to control which
1561
thread the continuations are invoked on.
1562
//! [whenAll-note]
1563
*/
1564
1565
/*! \fn template<typename OutputSequence, typename... Futures> QFuture<OutputSequence> QtFuture::whenAll(Futures &&... futures)
1566
1567
\since 6.3
1568
1569
Returns a new QFuture that succeeds when all \a futures packaging arbitrary
1570
types complete. \c OutputSequence is a sequence of completed futures. The type
1571
of its entries is \c std::variant<Futures...>. For each \c QFuture<T> passed to
1572
\c whenAll(), the entry at the corresponding position in \c OutputSequence
1573
will be a \c std::variant holding that \c QFuture<T>, in its completed state.
1574
If the type of \c OutputSequence is not specified, the resulting futures will
1575
be returned in a QList of \c std::variant<Futures...>. For example:
1576
1577
\snippet code/src_corelib_thread_qfuture.cpp 24
1578
1579
\note The output sequence should support random access and the \c resize()
1580
operation.
1581
1582
\include qfuture.qdoc whenAll
1583
1584
\snippet code/src_corelib_thread_qfuture.cpp 25
1585
1586
\include qfuture.qdoc whenAll-note
1587
*/
1588
1589
/*! \fn template<typename T, typename InputIt> QFuture<QtFuture::WhenAnyResult<T>> QtFuture::whenAny(InputIt first, InputIt last)
1590
1591
\since 6.3
1592
1593
Returns a new QFuture that succeeds when any of the futures from \a first to
1594
\a last completes. \a first and \a last are iterators to a sequence of futures
1595
packaging type \c T. The returned future packages a value of type
1596
\c {QtFuture::WhenAnyResult<T>} which in turn packages the index of the
1597
first completed \c QFuture and the \c QFuture itself. If \a first equals \a last,
1598
this function returns a ready \c QFuture that has \c -1 for the \c index field in
1599
the QtFuture::WhenAnyResult struct and a default-constructed \c QFuture<T> for
1600
the \c future field. Note that a default-constructed QFuture is a completed
1601
future in a cancelled state.
1602
1603
//! [whenAny]
1604
The returned future always completes successfully after the first future
1605
from the specified futures completes. It doesn't matter if the first future
1606
completes with error or is canceled. You can use \c .then() to process the
1607
result after the future returned by \c whenAny() succeeds:
1608
//! [whenAny]
1609
1610
\snippet code/src_corelib_thread_qfuture.cpp 26
1611
1612
//! [whenAny-note]
1613
\note If the input futures complete on different threads, the future returned
1614
by this method will complete in the thread that the first future completes in.
1615
Therefore, the continuations attached to the future returned by \c whenAny()
1616
cannot always make assumptions about which thread they will be run on. Use the
1617
overload of \c .then() that takes a context object if you want to control which
1618
thread the continuations are invoked on.
1619
//! [whenAny-note]
1620
1621
\sa QtFuture::WhenAnyResult
1622
*/
1623
1624
/*! \fn template<typename... Futures> QFuture<std::variant<std::decay_t<Futures>...>> QtFuture::whenAny(Futures &&... futures)
1625
1626
\since 6.3
1627
1628
Returns a new QFuture that succeeds when any of the \a futures completes.
1629
\a futures can package arbitrary types. The returned future packages the
1630
value of type \c std::variant<Futures...> which in turn packages the first
1631
completed QFuture from \a futures. You can use
1632
\l {https://en.cppreference.com/w/cpp/utility/variant/index} {std::variant::index()}
1633
to find out the index of the future in the sequence of \a futures that
1634
finished first.
1635
1636
\include qfuture.qdoc whenAny
1637
1638
\snippet code/src_corelib_thread_qfuture.cpp 27
1639
1640
\include qfuture.qdoc whenAny-note
1641
*/
qtbase
src
corelib
thread
qfuture.qdoc
Generated on
for Qt by
1.14.0