diff -r 000000000000 -r 1918ee327afb src/corelib/concurrent/qfuture.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/corelib/concurrent/qfuture.h Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFUTURE_H +#define QFUTURE_H + +#include + +#ifndef QT_NO_QFUTURE + +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +template +class QFutureWatcher; +template <> +class QFutureWatcher; + +template +class QFuture +{ +public: + QFuture() + : d(QFutureInterface::canceledResult()) + { } + explicit QFuture(QFutureInterface *p) // internal + : d(*p) + { } + QFuture(const QFuture &other) + : d(other.d) + { } + ~QFuture() + { } + + inline QFuture &operator=(const QFuture &other); + bool operator==(const QFuture &other) const { return (d == other.d); } + bool operator!=(const QFuture &other) const { return (d != other.d); } + + void cancel() { d.cancel(); } + bool isCanceled() const { return d.isCanceled(); } + + void setPaused(bool paused) { d.setPaused(paused); } + bool isPaused() const { return d.isPaused(); } + void pause() { setPaused(true); } + void resume() { setPaused(false); } + void togglePaused() { d.togglePaused(); } + + bool isStarted() const { return d.isStarted(); } + bool isFinished() const { return d.isFinished(); } + bool isRunning() const { return d.isRunning(); } + + int resultCount() const { return d.resultCount(); } + int progressValue() const { return d.progressValue(); } + int progressMinimum() const { return d.progressMinimum(); } + int progressMaximum() const { return d.progressMaximum(); } + QString progressText() const { return d.progressText(); } + void waitForFinished() { d.waitForFinished(); } + + inline T result() const; + inline T resultAt(int index) const; + bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); } + + operator T() const { return result(); } + QList results() const { return d.results(); } + + class const_iterator + { + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef const T *pointer; + typedef const T &reference; + + inline const_iterator() {} + inline const_iterator(QFuture const * const _future, int _index) : future(_future), index(_index) {} + 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 + { + 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); + } + + 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; } + private: + QFuture const * future; + int index; + }; + friend class const_iterator; + typedef const_iterator ConstIterator; + + const_iterator begin() const { return const_iterator(this, 0); } + const_iterator constBegin() const { return const_iterator(this, 0); } + const_iterator end() const { return const_iterator(this, -1); } + const_iterator constEnd() const { return const_iterator(this, -1); } + +private: + friend class QFutureWatcher; + +public: // Warning: the d pointer is not documented and is considered private. + mutable QFutureInterface d; +}; + +template +inline QFuture &QFuture::operator=(const QFuture &other) +{ + d = other.d; + return *this; +} + +template +inline T QFuture::result() const +{ + d.waitForResult(0); + return d.resultReference(0); +} + +template +inline T QFuture::resultAt(int index) const +{ + d.waitForResult(index); + return d.resultReference(index); +} + +template +inline QFuture QFutureInterface::future() +{ + return QFuture(this); +} + +Q_DECLARE_SEQUENTIAL_ITERATOR(Future) + +template <> +class QFuture +{ +public: + QFuture() + : d(QFutureInterface::canceledResult()) + { } + explicit QFuture(QFutureInterfaceBase *p) // internal + : d(*p) + { } + QFuture(const QFuture &other) + : d(other.d) + { } + ~QFuture() + { } + + QFuture &operator=(const QFuture &other); + bool operator==(const QFuture &other) const { return (d == other.d); } + bool operator!=(const QFuture &other) const { return (d != other.d); } + +#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(Q_CC_XLC) + template + QFuture(const QFuture &other) + : d(other.d) + { } + + template + QFuture &operator=(const QFuture &other) + { + d = other.d; + return *this; + } +#endif + + void cancel() { d.cancel(); } + bool isCanceled() const { return d.isCanceled(); } + + void setPaused(bool paused) { d.setPaused(paused); } + bool isPaused() const { return d.isPaused(); } + void pause() { setPaused(true); } + void resume() { setPaused(false); } + void togglePaused() { d.togglePaused(); } + + bool isStarted() const { return d.isStarted(); } + bool isFinished() const { return d.isFinished(); } + bool isRunning() const { return d.isRunning(); } + + int resultCount() const { return d.resultCount(); } + int progressValue() const { return d.progressValue(); } + int progressMinimum() const { return d.progressMinimum(); } + int progressMaximum() const { return d.progressMaximum(); } + QString progressText() const { return d.progressText(); } + void waitForFinished() { d.waitForFinished(); } + +private: + friend class QFutureWatcher; + +#ifdef QFUTURE_TEST +public: +#endif + mutable QFutureInterfaceBase d; +}; + +inline QFuture &QFuture::operator=(const QFuture &other) +{ + d = other.d; + return *this; +} + +inline QFuture QFutureInterface::future() +{ + return QFuture(this); +} + +template +QFuture qToVoidFuture(const QFuture &future) +{ + return QFuture(future.d); +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QT_NO_CONCURRENT + +#endif // QFUTURE_H