Qt 4.8
qtconcurrentfilterkernel.h
Go to the documentation of this file.
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 QTCONCURRENT_FILTERKERNEL_H
43 #define QTCONCURRENT_FILTERKERNEL_H
44 
45 #include <QtCore/qglobal.h>
46 
47 #ifndef QT_NO_CONCURRENT
48 
49 #include <QtCore/qtconcurrentiteratekernel.h>
50 #include <QtCore/qtconcurrentmapkernel.h>
51 #include <QtCore/qtconcurrentreducekernel.h>
52 
55 
56 QT_MODULE(Core)
57 
58 #ifndef qdoc
59 
60 namespace QtConcurrent {
61 
62 template <typename T>
63 struct qValueType
64 {
65  typedef typename T::value_type value_type;
66 };
67 
68 template <typename T>
69 struct qValueType<const T*>
70 {
71  typedef T value_type;
72 };
73 
74 template <typename T>
75 struct qValueType<T*>
76 {
77  typedef T value_type;
78 };
79 
80 // Implementation of filter
81 template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
82 class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
83 {
84  typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
85  typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
86  typedef typename ReduceFunctor::result_type T;
87 
88  Sequence reducedResult;
89  Sequence &sequence;
90  KeepFunctor keep;
91  ReduceFunctor reduce;
92  Reducer reducer;
93 
94 public:
95  FilterKernel(Sequence &_sequence, KeepFunctor _keep, ReduceFunctor _reduce)
96  : IterateKernelType(const_cast<const Sequence &>(_sequence).begin(), const_cast<const Sequence &>(_sequence).end()), reducedResult(),
97  sequence(_sequence),
98  keep(_keep),
99  reduce(_reduce),
100  reducer(OrderedReduce)
101  { }
102 
103  bool runIteration(typename Sequence::const_iterator it, int index, T *)
104  {
105  IntermediateResults<typename Sequence::value_type> results;
106  results.begin = index;
107  results.end = index + 1;
108 
109  if (keep(*it))
110  results.vector.append(*it);
111 
112  reducer.runReduce(reduce, reducedResult, results);
113  return false;
114  }
115 
116  bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *)
117  {
118  IntermediateResults<typename Sequence::value_type> results;
119  results.begin = begin;
120  results.end = end;
121  results.vector.reserve(end - begin);
122 
123 
124  typename Sequence::const_iterator it = sequenceBeginIterator;
125  advance(it, begin);
126  for (int i = begin; i < end; ++i) {
127  if (keep(*it))
128  results.vector.append(*it);
129  advance(it, 1);
130  }
131 
132  reducer.runReduce(reduce, reducedResult, results);
133  return false;
134  }
135 
136  void finish()
137  {
138  reducer.finish(reduce, reducedResult);
139  sequence = reducedResult;
140  }
141 
142  inline bool shouldThrottleThread()
143  {
144  return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
145  }
146 
147  inline bool shouldStartThread()
148  {
149  return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
150  }
151 
152  typedef void ReturnType;
153  typedef void ResultType;
154 };
155 
156 // Implementation of filter-reduce
157 template <typename ReducedResultType,
158  typename Iterator,
159  typename KeepFunctor,
160  typename ReduceFunctor,
161  typename Reducer = ReduceKernel<ReduceFunctor,
162  ReducedResultType,
163  typename qValueType<Iterator>::value_type> >
164 class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
165 {
166  ReducedResultType reducedResult;
167  KeepFunctor keep;
168  ReduceFunctor reduce;
169  Reducer reducer;
170  typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
171 
172 public:
173  FilteredReducedKernel(Iterator begin,
174  Iterator end,
175  KeepFunctor _keep,
176  ReduceFunctor _reduce,
177  ReduceOptions reduceOption)
178  : IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption)
179  { }
180 
181 #if 0
182  FilteredReducedKernel(ReducedResultType initialValue,
183  KeepFunctor keep,
184  ReduceFunctor reduce,
185  ReduceOption reduceOption)
186  : reducedResult(initialValue), keep(keep), reduce(reduce), reducer(reduceOption)
187  { }
188 #endif
189 
190  bool runIteration(Iterator it, int index, ReducedResultType *)
191  {
192  IntermediateResults<typename qValueType<Iterator>::value_type> results;
193  results.begin = index;
194  results.end = index + 1;
195 
196  if (keep(*it))
197  results.vector.append(*it);
198 
199  reducer.runReduce(reduce, reducedResult, results);
200  return false;
201  }
202 
203  bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *)
204  {
205  IntermediateResults<typename qValueType<Iterator>::value_type> results;
206  results.begin = begin;
207  results.end = end;
208  results.vector.reserve(end - begin);
209 
210  Iterator it = sequenceBeginIterator;
211  advance(it, begin);
212  for (int i = begin; i < end; ++i) {
213  if (keep(*it))
214  results.vector.append(*it);
215  advance(it, 1);
216  }
217 
218  reducer.runReduce(reduce, reducedResult, results);
219  return false;
220  }
221 
222  void finish()
223  {
224  reducer.finish(reduce, reducedResult);
225  }
226 
227  inline bool shouldThrottleThread()
228  {
229  return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
230  }
231 
232  inline bool shouldStartThread()
233  {
234  return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
235  }
236 
237  typedef ReducedResultType ReturnType;
238  typedef ReducedResultType ResultType;
239  ReducedResultType *result()
240  {
241  return &reducedResult;
242  }
243 };
244 
245 // Implementation of filter that reports individual results via QFutureInterface
246 template <typename Iterator, typename KeepFunctor>
247 class FilteredEachKernel : public IterateKernel<Iterator, typename qValueType<Iterator>::value_type>
248 {
249  typedef typename qValueType<Iterator>::value_type T;
250  typedef IterateKernel<Iterator, T> IterateKernelType;
251 
252  KeepFunctor keep;
253 
254 public:
255  typedef T ReturnType;
256  typedef T ResultType;
257 
258  FilteredEachKernel(Iterator begin, Iterator end, KeepFunctor _keep)
259  : IterateKernelType(begin, end), keep(_keep)
260  { }
261 
262  void start()
263  {
264  if (this->futureInterface)
265  this->futureInterface->setFilterMode(true);
266  IterateKernelType::start();
267  }
268 
269  bool runIteration(Iterator it, int index, T *)
270  {
271  if (keep(*it))
272  this->reportResult(&(*it), index);
273  else
274  this->reportResult(0, index);
275  return false;
276  }
277 
278  bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *)
279  {
280  const int count = end - begin;
281  IntermediateResults<typename qValueType<Iterator>::value_type> results;
282  results.begin = begin;
283  results.end = end;
284  results.vector.reserve(count);
285 
286  Iterator it = sequenceBeginIterator;
287  advance(it, begin);
288  for (int i = begin; i < end; ++i) {
289  if (keep(*it))
290  results.vector.append(*it);
291  advance(it, 1);
292  }
293 
294  this->reportResults(results.vector, begin, count);
295  return false;
296  }
297 };
298 
299 template <typename Iterator, typename KeepFunctor>
300 inline
301 ThreadEngineStarter<typename qValueType<Iterator>::value_type>
302 startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
303 {
304  return startThreadEngine(new FilteredEachKernel<Iterator, KeepFunctor>(begin, end, functor));
305 }
306 
307 template <typename Sequence, typename KeepFunctor>
308 inline ThreadEngineStarter<typename Sequence::value_type>
309 startFiltered(const Sequence &sequence, KeepFunctor functor)
310 {
311  typedef SequenceHolder1<Sequence,
312  FilteredEachKernel<typename Sequence::const_iterator, KeepFunctor>,
313  KeepFunctor>
314  SequenceHolderType;
315  return startThreadEngine(new SequenceHolderType(sequence, functor));
316 }
317 
318 template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
319 inline ThreadEngineStarter<ResultType> startFilteredReduced(const Sequence & sequence,
320  MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
321  ReduceOptions options)
322 {
323  typedef typename Sequence::const_iterator Iterator;
324  typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type > Reducer;
325  typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
326  typedef SequenceHolder2<Sequence, FilteredReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
327  return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
328 }
329 
330 
331 template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
332 inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iterator end,
333  MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
334  ReduceOptions options)
335 {
336  typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type> Reducer;
337  typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
338  return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options));
339 }
340 
341 
342 } // namespace QtConcurrent
343 
344 #endif // qdoc
345 
348 
349 #endif // QT_NO_CONCURRENT
350 
351 #endif
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define QT_MODULE(x)
Definition: qglobal.h:2783
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
#define it(className, varName)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
ReduceOption
This enum specifies the order of which results from the map or filter function are passed to the redu...
The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded pro...
quint16 index
static Bool functor(Display *display, XEvent *event, XPointer arg)
static const KeyPair *const end
#define QT_END_HEADER
Definition: qglobal.h:137