1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #ifndef QFUTURE_H |
43 | #define QFUTURE_H |
44 | |
45 | #include <QtCore/qglobal.h> |
46 | |
47 | #ifndef QT_NO_QFUTURE |
48 | |
49 | #include <QtCore/qfutureinterface.h> |
50 | #include <QtCore/qstring.h> |
51 | #include <QtCore/qtconcurrentcompilertest.h> |
52 | |
53 | QT_BEGIN_HEADER |
54 | QT_BEGIN_NAMESPACE |
55 | |
56 | QT_MODULE(Core) |
57 | |
58 | template <typename T> |
59 | class QFutureWatcher; |
60 | template <> |
61 | class QFutureWatcher<void>; |
62 | |
63 | template <typename T> |
64 | class QFuture |
65 | { |
66 | public: |
67 | QFuture() |
68 | : d(QFutureInterface<T>::canceledResult()) |
69 | { } |
70 | explicit QFuture(QFutureInterface<T> *p) // internal |
71 | : d(*p) |
72 | { } |
73 | QFuture(const QFuture &other) |
74 | : d(other.d) |
75 | { } |
76 | ~QFuture() |
77 | { } |
78 | |
79 | inline QFuture &operator=(const QFuture &other); |
80 | bool operator==(const QFuture &other) const { return (d == other.d); } |
81 | bool operator!=(const QFuture &other) const { return (d != other.d); } |
82 | |
83 | void cancel() { d.cancel(); } |
84 | bool isCanceled() const { return d.isCanceled(); } |
85 | |
86 | void setPaused(bool paused) { d.setPaused(paused); } |
87 | bool isPaused() const { return d.isPaused(); } |
88 | void pause() { setPaused(true); } |
89 | void resume() { setPaused(false); } |
90 | void togglePaused() { d.togglePaused(); } |
91 | |
92 | bool isStarted() const { return d.isStarted(); } |
93 | bool isFinished() const { return d.isFinished(); } |
94 | bool isRunning() const { return d.isRunning(); } |
95 | |
96 | int resultCount() const { return d.resultCount(); } |
97 | int progressValue() const { return d.progressValue(); } |
98 | int progressMinimum() const { return d.progressMinimum(); } |
99 | int progressMaximum() const { return d.progressMaximum(); } |
100 | QString progressText() const { return d.progressText(); } |
101 | void waitForFinished() { d.waitForFinished(); } |
102 | |
103 | inline T result() const; |
104 | inline T resultAt(int index) const; |
105 | bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); } |
106 | |
107 | operator T() const { return result(); } |
108 | QList<T> results() const { return d.results(); } |
109 | |
110 | class const_iterator |
111 | { |
112 | public: |
113 | typedef std::bidirectional_iterator_tag iterator_category; |
114 | typedef qptrdiff difference_type; |
115 | typedef T value_type; |
116 | typedef const T *pointer; |
117 | typedef const T &reference; |
118 | |
119 | inline const_iterator() {} |
120 | inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {} |
121 | inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {} |
122 | inline const_iterator &operator=(const const_iterator &o) |
123 | { future = o.future; index = o.index; return *this; } |
124 | inline const T &operator*() const { return future->d.resultReference(index); } |
125 | inline const T *operator->() const { return future->d.resultPointer(index); } |
126 | |
127 | inline bool operator!=(const const_iterator &other) const |
128 | { |
129 | if (index == -1 && other.index == -1) // comparing end != end? |
130 | return false; |
131 | if (other.index == -1) |
132 | return (future->isRunning() || (index < future->resultCount())); |
133 | return (index != other.index); |
134 | } |
135 | |
136 | inline bool operator==(const const_iterator &o) const { return !operator!=(o); } |
137 | inline const_iterator &operator++() { ++index; return *this; } |
138 | inline const_iterator operator++(int) { const_iterator r = *this; ++index; return r; } |
139 | inline const_iterator &operator--() { --index; return *this; } |
140 | inline const_iterator operator--(int) { const_iterator r = *this; --index; return r; } |
141 | inline const_iterator operator+(int j) const { return const_iterator(future, index + j); } |
142 | inline const_iterator operator-(int j) const { return const_iterator(future, index - j); } |
143 | inline const_iterator &operator+=(int j) { index += j; return *this; } |
144 | inline const_iterator &operator-=(int j) { index -= j; return *this; } |
145 | private: |
146 | QFuture const * future; |
147 | int index; |
148 | }; |
149 | friend class const_iterator; |
150 | typedef const_iterator ConstIterator; |
151 | |
152 | const_iterator begin() const { return const_iterator(this, 0); } |
153 | const_iterator constBegin() const { return const_iterator(this, 0); } |
154 | const_iterator end() const { return const_iterator(this, -1); } |
155 | const_iterator constEnd() const { return const_iterator(this, -1); } |
156 | |
157 | private: |
158 | friend class QFutureWatcher<T>; |
159 | |
160 | public: // Warning: the d pointer is not documented and is considered private. |
161 | mutable QFutureInterface<T> d; |
162 | }; |
163 | |
164 | template <typename T> |
165 | inline QFuture<T> &QFuture<T>::operator=(const QFuture<T> &other) |
166 | { |
167 | d = other.d; |
168 | return *this; |
169 | } |
170 | |
171 | template <typename T> |
172 | inline T QFuture<T>::result() const |
173 | { |
174 | d.waitForResult(0); |
175 | return d.resultReference(0); |
176 | } |
177 | |
178 | template <typename T> |
179 | inline T QFuture<T>::resultAt(int index) const |
180 | { |
181 | d.waitForResult(index); |
182 | return d.resultReference(index); |
183 | } |
184 | |
185 | template <typename T> |
186 | inline QFuture<T> QFutureInterface<T>::future() |
187 | { |
188 | return QFuture<T>(this); |
189 | } |
190 | |
191 | Q_DECLARE_SEQUENTIAL_ITERATOR(Future) |
192 | |
193 | template <> |
194 | class QFuture<void> |
195 | { |
196 | public: |
197 | QFuture() |
198 | : d(QFutureInterface<void>::canceledResult()) |
199 | { } |
200 | explicit QFuture(QFutureInterfaceBase *p) // internal |
201 | : d(*p) |
202 | { } |
203 | QFuture(const QFuture &other) |
204 | : d(other.d) |
205 | { } |
206 | ~QFuture() |
207 | { } |
208 | |
209 | QFuture &operator=(const QFuture &other); |
210 | bool operator==(const QFuture &other) const { return (d == other.d); } |
211 | bool operator!=(const QFuture &other) const { return (d != other.d); } |
212 | |
213 | #if !defined(Q_CC_XLC) |
214 | template <typename T> |
215 | QFuture(const QFuture<T> &other) |
216 | : d(other.d) |
217 | { } |
218 | |
219 | template <typename T> |
220 | QFuture<void> &operator=(const QFuture<T> &other) |
221 | { |
222 | d = other.d; |
223 | return *this; |
224 | } |
225 | #endif |
226 | |
227 | void cancel() { d.cancel(); } |
228 | bool isCanceled() const { return d.isCanceled(); } |
229 | |
230 | void setPaused(bool paused) { d.setPaused(paused); } |
231 | bool isPaused() const { return d.isPaused(); } |
232 | void pause() { setPaused(true); } |
233 | void resume() { setPaused(false); } |
234 | void togglePaused() { d.togglePaused(); } |
235 | |
236 | bool isStarted() const { return d.isStarted(); } |
237 | bool isFinished() const { return d.isFinished(); } |
238 | bool isRunning() const { return d.isRunning(); } |
239 | |
240 | int resultCount() const { return d.resultCount(); } |
241 | int progressValue() const { return d.progressValue(); } |
242 | int progressMinimum() const { return d.progressMinimum(); } |
243 | int progressMaximum() const { return d.progressMaximum(); } |
244 | QString progressText() const { return d.progressText(); } |
245 | void waitForFinished() { d.waitForFinished(); } |
246 | |
247 | private: |
248 | friend class QFutureWatcher<void>; |
249 | |
250 | #ifdef QFUTURE_TEST |
251 | public: |
252 | #endif |
253 | mutable QFutureInterfaceBase d; |
254 | }; |
255 | |
256 | inline QFuture<void> &QFuture<void>::operator=(const QFuture<void> &other) |
257 | { |
258 | d = other.d; |
259 | return *this; |
260 | } |
261 | |
262 | inline QFuture<void> QFutureInterface<void>::future() |
263 | { |
264 | return QFuture<void>(this); |
265 | } |
266 | |
267 | template <typename T> |
268 | QFuture<void> qToVoidFuture(const QFuture<T> &future) |
269 | { |
270 | return QFuture<void>(future.d); |
271 | } |
272 | |
273 | QT_END_NAMESPACE |
274 | QT_END_HEADER |
275 | |
276 | #endif // QT_NO_CONCURRENT |
277 | |
278 | #endif // QFUTURE_H |
279 | |