diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2017-12-11 21:12:10 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-13 10:41:25 +0200 |
commit | 6faa4d4a87662a6254542da37b3a6fff528e0a6c (patch) | |
tree | 04578d13b1c923a3a34e4f9ace27d2884759d76a /src | |
parent | 486c55d7437c247472e287f0f2ccc883399d9f79 (diff) |
QFuture: Wait for result on iterator advance
Wait for the result at the target index if the future
is running and the iterator index is past the current
result count.
Determine if there is a result at the target index
after waitForResult() returns, and return -1/end if
not.
Also support decrementing the end iterator. In this
case wait for the future to finish in order to get
the final result count.
Task-number: QTBUG-59811
Change-Id: I8fcc711bab2e72c3c5196a55b794d25e18bb324d
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/thread/qfuture.h | 82 |
1 files changed, 64 insertions, 18 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h index a456dd9139..d3135510b3 100644 --- a/src/corelib/thread/qfuture.h +++ b/src/corelib/thread/qfuture.h @@ -111,33 +111,79 @@ public: typedef const T &reference; inline const_iterator() {} - inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {} + inline const_iterator(QFuture const * const _future, int _index) + : future(_future), index(advanceIndex(_index, 0)) { } inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {} inline const_iterator &operator=(const const_iterator &o) { future = o.future; index = o.index; return *this; } inline const T &operator*() const { return future->d.resultReference(index); } inline const T *operator->() const { return future->d.resultPointer(index); } - - inline bool operator!=(const const_iterator &other) const + inline bool operator!=(const const_iterator &other) const { return index != other.index; } + inline bool operator==(const const_iterator &o) const { return !operator!=(o); } + inline const_iterator &operator++() + { index = advanceIndex(index, 1); return *this; } + inline const_iterator &operator--() + { index = advanceIndex(index, -1); return *this; } + inline const_iterator operator++(int) + { + const_iterator r = *this; + index = advanceIndex(index, 1); + return r; + } + inline const_iterator operator--(int) { - if (index == -1 && other.index == -1) // comparing end != end? - return false; - if (other.index == -1) - return (future->isRunning() || (index < future->resultCount())); - return (index != other.index); + const_iterator r = *this; + index = advanceIndex(index, -1); + return r; } + inline const_iterator operator+(int j) const + { return const_iterator(future, advanceIndex(index, j)); } + inline const_iterator operator-(int j) const + { return const_iterator(future, advanceIndex(index, -j)); } + inline const_iterator &operator+=(int j) + { index = advanceIndex(index, j); return *this; } + inline const_iterator &operator-=(int j) + { index = advanceIndex(index, -j); return *this; } + friend inline const_iterator operator+(int j, const_iterator k) + { return const_iterator(k.future, k.advanceIndex(k.index, j)); } - inline bool operator==(const const_iterator &o) const { return !operator!=(o); } - inline const_iterator &operator++() { ++index; return *this; } - inline const_iterator operator++(int) { const_iterator r = *this; ++index; return r; } - inline const_iterator &operator--() { --index; return *this; } - inline const_iterator operator--(int) { const_iterator r = *this; --index; return r; } - inline const_iterator operator+(int j) const { return const_iterator(future, index + j); } - inline const_iterator operator-(int j) const { return const_iterator(future, index - j); } - inline const_iterator &operator+=(int j) { index += j; return *this; } - inline const_iterator &operator-=(int j) { index -= j; return *this; } - friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } private: + /*! \internal + + Advances the iterator index \a idx \a n steps, waits for the + result at the target index, and returns the target index. + + The index may be -1, indicating the end iterator, either + as the argument or as the return value. The end iterator + may be decremented. + + The caller is responsible for not advancing the iterator + before begin() or past end(), with the exception that + attempting to advance a non-end iterator past end() for + a running future is allowed and will return the end iterator. + + Note that n == 0 is valid and will wait for the result + at the given index. + */ + int advanceIndex(int idx, int n) const + { + // The end iterator can be decremented, leave as-is for other cases + if (idx == -1 && n >= 0) + return idx; + + // Special case for decrementing the end iterator: wait for + // finished to get the total result count. + if (idx == -1 && future->isRunning()) + future->d.waitForFinished(); + + // Wait for result at target index + const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n; + future->d.waitForResult(targetIndex); + + // After waiting there is either a result or the end was reached + return (targetIndex < future->resultCount()) ? targetIndex : -1; + } + QFuture const * future; int index; }; |