1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #ifndef QTCONCURRENT_RESULTSTORE_H
43 #define QTCONCURRENT_RESULTSTORE_H
45 #include <QtCore/qglobal.h>
49 #include <QtCore/qmap.h>
50 #include <QtCore/qdebug.h>
58 ResultStore stores indexed results. Results can be added and retrieved
59 either individually batched in a QVector. Retriveing results and checking
60 which indexes are in the store can be done either by iterating or by random
61 accees. In addition results kan be removed from the front of the store,
62 either individually or in batches.
67 namespace QtConcurrent
{
72 ResultItem(const void *_result
, int _count
) : m_count(_count
), result(_result
) { } // contruct with vector of results
73 ResultItem(const void *_result
) : m_count(0), result(_result
) { } // construct with result
74 ResultItem() : m_count(0), result(0) { }
75 bool isValid() const { return result
!= 0; }
76 bool isVector() const { return m_count
!= 0; }
77 int count() const { return (m_count
== 0) ? 1 : m_count
; }
78 int m_count
; // result is either a pointer to a result or to a vector of results,
79 const void *result
; // if count is 0 it's a result, otherwise it's a vector.
82 class Q_CORE_EXPORT ResultIteratorBase
86 ResultIteratorBase(QMap
<int, ResultItem
>::const_iterator _mapIterator
, int _vectorIndex
= 0);
87 int vectorIndex() const;
88 int resultIndex() const;
90 ResultIteratorBase
operator++();
91 int batchSize() const;
92 void batchedAdvance();
93 bool operator==(const ResultIteratorBase
&other
) const;
94 bool operator!=(const ResultIteratorBase
&other
) const;
95 bool isVector() const;
96 bool canIncrementVectorIndex() const;
98 QMap
<int, ResultItem
>::const_iterator mapIterator
;
102 template <typename T
>
103 class ResultIterator
: public ResultIteratorBase
106 ResultIterator(const ResultIteratorBase
&base
)
107 : ResultIteratorBase(base
) { }
109 const T
&value() const
114 const T
*pointer() const
116 if (mapIterator
.value().isVector())
117 return &(reinterpret_cast<const QVector
<T
> *>(mapIterator
.value().result
)->at(m_vectorIndex
));
119 return reinterpret_cast<const T
*>(mapIterator
.value().result
);
123 class Q_CORE_EXPORT ResultStoreBase
127 void setFilterMode(bool enable
);
128 bool filterMode() const;
129 int addResult(int index
, const void *result
);
130 int addResults(int index
, const void *results
, int vectorSize
, int logicalCount
);
131 ResultIteratorBase
begin() const;
132 ResultIteratorBase
end() const;
133 bool hasNextResult() const;
134 ResultIteratorBase
resultAt(int index
) const;
135 bool contains(int index
) const;
137 virtual ~ResultStoreBase() { };
140 int insertResultItem(int index
, ResultItem
&resultItem
);
141 void insertResultItemIfValid(int index
, ResultItem
&resultItem
);
142 void syncPendingResults();
143 void syncResultCount();
144 int updateInsertIndex(int index
, int _count
);
146 QMap
<int, ResultItem
> m_results
;
147 int insertIndex
; // The index where the next results(s) will be inserted.
148 int resultCount
; // The number of consecutive results stored, starting at index 0.
151 QMap
<int, ResultItem
> pendingResults
;
156 template <typename T
>
157 class ResultStore
: public ResultStoreBase
162 ResultStore(const ResultStoreBase
&base
)
163 : ResultStoreBase(base
) { }
165 int addResult(int index
, const T
*result
)
168 return ResultStoreBase::addResult(index
, result
);
170 return ResultStoreBase::addResult(index
, new T(*result
));
173 int addResults(int index
, const QVector
<T
> *results
)
175 return ResultStoreBase::addResults(index
, new QVector
<T
>(*results
), results
->count(), results
->count());
178 int addResults(int index
, const QVector
<T
> *results
, int totalCount
)
180 return ResultStoreBase::addResults(index
, new QVector
<T
>(*results
), results
->count(), totalCount
);
183 int addCanceledResult(int index
)
185 return addResult(index
, 0);
188 int addCanceledResults(int index
, int _count
)
191 return addResults(index
, &empty
, _count
);
194 ResultIterator
<T
> begin() const
196 return static_cast<ResultIterator
<T
> >(ResultStoreBase::begin());
199 ResultIterator
<T
> end() const
201 return static_cast<ResultIterator
<T
> >(ResultStoreBase::end());
204 ResultIterator
<T
> resultAt(int index
) const
206 return static_cast<ResultIterator
<T
> >(ResultStoreBase::resultAt(index
));
211 QMap
<int, ResultItem
>::const_iterator mapIterator
= m_results
.constBegin();
212 while (mapIterator
!= m_results
.constEnd()) {
213 if (mapIterator
.value().isVector())
214 delete reinterpret_cast<const QVector
<T
> *>(mapIterator
.value().result
);
216 delete reinterpret_cast<const T
*>(mapIterator
.value().result
);
230 } // namespace QtConcurrent
237 #endif // QT_NO_CONCURRENT