00001 /**************************************************************************** 00002 ** 00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 00004 ** All rights reserved. 00005 ** Contact: Nokia Corporation (qt-info@nokia.com) 00006 ** 00007 ** This file is part of the QtCore module of the Qt Toolkit. 00008 ** 00009 ** $QT_BEGIN_LICENSE:LGPL$ 00010 ** Commercial Usage 00011 ** Licensees holding valid Qt Commercial licenses may use this file in 00012 ** accordance with the Qt Commercial License Agreement provided with the 00013 ** Software or, alternatively, in accordance with the terms contained in 00014 ** a written agreement between you and Nokia. 00015 ** 00016 ** GNU Lesser General Public License Usage 00017 ** Alternatively, this file may be used under the terms of the GNU Lesser 00018 ** General Public License version 2.1 as published by the Free Software 00019 ** Foundation and appearing in the file LICENSE.LGPL included in the 00020 ** packaging of this file. Please review the following information to 00021 ** ensure the GNU Lesser General Public License version 2.1 requirements 00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 00023 ** 00024 ** In addition, as a special exception, Nokia gives you certain additional 00025 ** rights. These rights are described in the Nokia Qt LGPL Exception 00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module. 00027 ** 00028 ** GNU General Public License Usage 00029 ** Alternatively, this file may be used under the terms of the GNU 00030 ** General Public License version 3.0 as published by the Free Software 00031 ** Foundation and appearing in the file LICENSE.GPL included in the 00032 ** packaging of this file. Please review the following information to 00033 ** ensure the GNU General Public License version 3.0 requirements will be 00034 ** met: http://www.gnu.org/copyleft/gpl.html. 00035 ** 00036 ** If you have questions regarding the use of this file, please contact 00037 ** Nokia at qt-info@nokia.com. 00038 ** $QT_END_LICENSE$ 00039 ** 00040 ****************************************************************************/ 00041 00042 #ifndef QFUTURE_H 00043 #define QFUTURE_H 00044 00045 #include <QtCore/qglobal.h> 00046 00047 #ifndef QT_NO_QFUTURE 00048 00049 #include <QtCore/qfutureinterface.h> 00050 #include <QtCore/qstring.h> 00051 #include <QtCore/qtconcurrentcompilertest.h> 00052 00053 QT_BEGIN_HEADER 00054 QT_BEGIN_NAMESPACE 00055 00056 QT_MODULE(Core) 00057 00058 template <typename T> 00059 class QFutureWatcher; 00060 template <> 00061 class QFutureWatcher<void>; 00062 00063 template <typename T> 00064 class QFuture 00065 { 00066 public: 00067 QFuture() 00068 : d(QFutureInterface<T>::canceledResult()) 00069 { } 00070 explicit QFuture(QFutureInterface<T> *p) // internal 00071 : d(*p) 00072 { } 00073 QFuture(const QFuture &other) 00074 : d(other.d) 00075 { } 00076 ~QFuture() 00077 { } 00078 00079 inline QFuture &operator=(const QFuture &other); 00080 bool operator==(const QFuture &other) const { return (d == other.d); } 00081 bool operator!=(const QFuture &other) const { return (d != other.d); } 00082 00083 void cancel() { d.cancel(); } 00084 bool isCanceled() const { return d.isCanceled(); } 00085 00086 void setPaused(bool paused) { d.setPaused(paused); } 00087 bool isPaused() const { return d.isPaused(); } 00088 void pause() { setPaused(true); } 00089 void resume() { setPaused(false); } 00090 void togglePaused() { d.togglePaused(); } 00091 00092 bool isStarted() const { return d.isStarted(); } 00093 bool isFinished() const { return d.isFinished(); } 00094 bool isRunning() const { return d.isRunning(); } 00095 00096 int resultCount() const { return d.resultCount(); } 00097 int progressValue() const { return d.progressValue(); } 00098 int progressMinimum() const { return d.progressMinimum(); } 00099 int progressMaximum() const { return d.progressMaximum(); } 00100 QString progressText() const { return d.progressText(); } 00101 void waitForFinished() { d.waitForFinished(); } 00102 00103 inline T result() const; 00104 inline T resultAt(int index) const; 00105 bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); } 00106 00107 operator T() const { return result(); } 00108 QList<T> results() const { return d.results(); } 00109 00110 class const_iterator 00111 { 00112 public: 00113 typedef std::bidirectional_iterator_tag iterator_category; 00114 typedef qptrdiff difference_type; 00115 typedef T value_type; 00116 typedef const T *pointer; 00117 typedef const T &reference; 00118 00119 inline const_iterator() {} 00120 inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {} 00121 inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {} 00122 inline const_iterator &operator=(const const_iterator &o) 00123 { future = o.future; index = o.index; return *this; } 00124 inline const T &operator*() const { return future->d.resultReference(index); } 00125 inline const T *operator->() const { return future->d.resultPointer(index); } 00126 00127 inline bool operator!=(const const_iterator &other) const 00128 { 00129 if (index == -1 && other.index == -1) // comparing end != end? 00130 return false; 00131 if (other.index == -1) 00132 return (future->isRunning() || (index < future->resultCount())); 00133 return (index != other.index); 00134 } 00135 00136 inline bool operator==(const const_iterator &o) const { return !operator!=(o); } 00137 inline const_iterator &operator++() { ++index; return *this; } 00138 inline const_iterator operator++(int) { const_iterator r = *this; ++index; return r; } 00139 inline const_iterator &operator--() { --index; return *this; } 00140 inline const_iterator operator--(int) { const_iterator r = *this; --index; return r; } 00141 inline const_iterator operator+(int j) const { return const_iterator(future, index + j); } 00142 inline const_iterator operator-(int j) const { return const_iterator(future, index - j); } 00143 inline const_iterator &operator+=(int j) { index += j; return *this; } 00144 inline const_iterator &operator-=(int j) { index -= j; return *this; } 00145 private: 00146 QFuture const * future; 00147 int index; 00148 }; 00149 friend class const_iterator; 00150 typedef const_iterator ConstIterator; 00151 00152 const_iterator begin() const { return const_iterator(this, 0); } 00153 const_iterator constBegin() const { return const_iterator(this, 0); } 00154 const_iterator end() const { return const_iterator(this, -1); } 00155 const_iterator constEnd() const { return const_iterator(this, -1); } 00156 00157 private: 00158 friend class QFutureWatcher<T>; 00159 00160 public: // Warning: the d pointer is not documented and is considered private. 00161 mutable QFutureInterface<T> d; 00162 }; 00163 00164 template <typename T> 00165 inline QFuture<T> &QFuture<T>::operator=(const QFuture<T> &other) 00166 { 00167 d = other.d; 00168 return *this; 00169 } 00170 00171 template <typename T> 00172 inline T QFuture<T>::result() const 00173 { 00174 d.waitForResult(0); 00175 return d.resultReference(0); 00176 } 00177 00178 template <typename T> 00179 inline T QFuture<T>::resultAt(int index) const 00180 { 00181 d.waitForResult(index); 00182 return d.resultReference(index); 00183 } 00184 00185 template <typename T> 00186 inline QFuture<T> QFutureInterface<T>::future() 00187 { 00188 return QFuture<T>(this); 00189 } 00190 00191 Q_DECLARE_SEQUENTIAL_ITERATOR(Future) 00192 00193 template <> 00194 class QFuture<void> 00195 { 00196 public: 00197 QFuture() 00198 : d(QFutureInterface<void>::canceledResult()) 00199 { } 00200 explicit QFuture(QFutureInterfaceBase *p) // internal 00201 : d(*p) 00202 { } 00203 QFuture(const QFuture &other) 00204 : d(other.d) 00205 { } 00206 ~QFuture() 00207 { } 00208 00209 QFuture &operator=(const QFuture &other); 00210 bool operator==(const QFuture &other) const { return (d == other.d); } 00211 bool operator!=(const QFuture &other) const { return (d != other.d); } 00212 00213 #if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(Q_CC_XLC) 00214 template <typename T> 00215 QFuture(const QFuture<T> &other) 00216 : d(other.d) 00217 { } 00218 00219 template <typename T> 00220 QFuture<void> &operator=(const QFuture<T> &other) 00221 { 00222 d = other.d; 00223 return *this; 00224 } 00225 #endif 00226 00227 void cancel() { d.cancel(); } 00228 bool isCanceled() const { return d.isCanceled(); } 00229 00230 void setPaused(bool paused) { d.setPaused(paused); } 00231 bool isPaused() const { return d.isPaused(); } 00232 void pause() { setPaused(true); } 00233 void resume() { setPaused(false); } 00234 void togglePaused() { d.togglePaused(); } 00235 00236 bool isStarted() const { return d.isStarted(); } 00237 bool isFinished() const { return d.isFinished(); } 00238 bool isRunning() const { return d.isRunning(); } 00239 00240 int resultCount() const { return d.resultCount(); } 00241 int progressValue() const { return d.progressValue(); } 00242 int progressMinimum() const { return d.progressMinimum(); } 00243 int progressMaximum() const { return d.progressMaximum(); } 00244 QString progressText() const { return d.progressText(); } 00245 void waitForFinished() { d.waitForFinished(); } 00246 00247 private: 00248 friend class QFutureWatcher<void>; 00249 00250 #ifdef QFUTURE_TEST 00251 public: 00252 #endif 00253 mutable QFutureInterfaceBase d; 00254 }; 00255 00256 inline QFuture<void> &QFuture<void>::operator=(const QFuture<void> &other) 00257 { 00258 d = other.d; 00259 return *this; 00260 } 00261 00262 inline QFuture<void> QFutureInterface<void>::future() 00263 { 00264 return QFuture<void>(this); 00265 } 00266 00267 template <typename T> 00268 QFuture<void> qToVoidFuture(const QFuture<T> &future) 00269 { 00270 return QFuture<void>(future.d); 00271 } 00272 00273 QT_END_NAMESPACE 00274 QT_END_HEADER 00275 00276 #endif // QT_NO_CONCURRENT 00277 00278 #endif // QFUTURE_H