Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtconcurrentfilterkernel.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QTCONCURRENT_FILTERKERNEL_H
6#define QTCONCURRENT_FILTERKERNEL_H
7
8#include <QtConcurrent/qtconcurrent_global.h>
9
10#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
11
12#include <QtConcurrent/qtconcurrentiteratekernel.h>
13#include <QtConcurrent/qtconcurrentmapkernel.h>
14#include <QtConcurrent/qtconcurrentreducekernel.h>
15
16QT_BEGIN_NAMESPACE
17
18
19
20namespace QtConcurrent {
21
22template <typename T>
24{
25 typedef typename T::value_type value_type;
26};
27
28template <typename T>
29struct qValueType<const T*>
30{
31 typedef T value_type;
32};
33
34template <typename T>
35struct qValueType<T*>
36{
37 typedef T value_type;
38};
39
40// Implementation of filter
41template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
42class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
43{
44 typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
45 typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
46 typedef void T;
47
48 Sequence reducedResult;
49 Sequence &sequence;
50 KeepFunctor keep;
51 ReduceFunctor reduce;
52 Reducer reducer;
53
54public:
55 template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
56 FilterKernel(QThreadPool *pool, Sequence &_sequence, Keep &&_keep, Reduce &&_reduce)
57 : IterateKernelType(pool, const_cast<const Sequence &>(_sequence).begin(),
58 const_cast<const Sequence &>(_sequence).end()), reducedResult(),
59 sequence(_sequence),
63 { }
64
65 bool runIteration(typename Sequence::const_iterator it, int index, T *) override
66 {
67 IntermediateResults<typename Sequence::value_type> results;
68 results.begin = index;
69 results.end = index + 1;
70
71 if (std::invoke(keep, *it))
72 results.vector.append(*it);
73
74 reducer.runReduce(reduce, reducedResult, results);
75 return false;
76 }
77
78 bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override
79 {
80 IntermediateResults<typename Sequence::value_type> results;
81 results.begin = begin;
82 results.end = end;
83 results.vector.reserve(end - begin);
84
85
86 typename Sequence::const_iterator it = sequenceBeginIterator;
87 std::advance(it, begin);
88 for (int i = begin; i < end; ++i) {
89 if (std::invoke(keep, *it))
90 results.vector.append(*it);
91 std::advance(it, 1);
92 }
93
94 reducer.runReduce(reduce, reducedResult, results);
95 return false;
96 }
97
99 {
100 reducer.finish(reduce, reducedResult);
101 sequence = std::move(reducedResult);
102 }
103
105 {
106 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
107 }
108
110 {
111 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
112 }
113
114 typedef void ReturnType;
115 typedef void ResultType;
116};
117
118// Implementation of filter-reduce
119template <typename ReducedResultType,
120 typename Iterator,
121 typename KeepFunctor,
122 typename ReduceFunctor,
123 typename Reducer = ReduceKernel<ReduceFunctor,
125 typename qValueType<Iterator>::value_type> >
127{
128 ReducedResultType &reducedResult;
129 KeepFunctor keep;
130 ReduceFunctor reduce;
131 Reducer reducer;
132 typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
133
134public:
135 template<typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
136 FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
137 Reduce &&_reduce, ReduceOptions reduceOption)
139 reducedResult(this->defaultValue.value),
142 reducer(pool, reduceOption)
143 { }
144
145 template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
146 FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
147 Reduce &&_reduce, ReducedResultType &&initialValue,
148 ReduceOptions reduceOption)
150 reducedResult(this->defaultValue.value),
153 reducer(pool, reduceOption)
154 {
155 }
156
157 bool runIteration(Iterator it, int index, ReducedResultType *) override
158 {
159 IntermediateResults<typename qValueType<Iterator>::value_type> results;
160 results.begin = index;
161 results.end = index + 1;
162
163 if (std::invoke(keep, *it))
164 results.vector.append(*it);
165
166 reducer.runReduce(reduce, reducedResult, results);
167 return false;
168 }
169
170 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *) override
171 {
172 IntermediateResults<typename qValueType<Iterator>::value_type> results;
173 results.begin = begin;
174 results.end = end;
175 results.vector.reserve(end - begin);
176
177 Iterator it = sequenceBeginIterator;
178 std::advance(it, begin);
179 for (int i = begin; i < end; ++i) {
180 if (std::invoke(keep, *it))
181 results.vector.append(*it);
182 std::advance(it, 1);
183 }
184
185 reducer.runReduce(reduce, reducedResult, results);
186 return false;
187 }
188
190 {
191 reducer.finish(reduce, reducedResult);
192 }
193
195 {
196 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
197 }
198
200 {
201 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
202 }
203
204 typedef ReducedResultType ReturnType;
205 typedef ReducedResultType ResultType;
206 ReducedResultType *result() override
207 {
208 return &reducedResult;
209 }
210};
211
212// Implementation of filter that reports individual results via QFutureInterface
213template <typename Iterator, typename KeepFunctor>
215{
216 typedef typename qValueType<Iterator>::value_type T;
217 typedef IterateKernel<Iterator, T> IterateKernelType;
218
219 KeepFunctor keep;
220
221public:
222 typedef T ReturnType;
223 typedef T ResultType;
224
225 template <typename Keep = KeepFunctor>
226 FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep)
228 { }
229
231 {
232 if (this->futureInterface)
233 this->futureInterface->setFilterMode(true);
234 IterateKernelType::start();
235 }
236
237 bool runIteration(Iterator it, int index, T *) override
238 {
239 if (std::invoke(keep, *it))
240 this->reportResult(&(*it), index);
241 else
242 this->reportResult(nullptr, index);
243 return false;
244 }
245
246 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *) override
247 {
248 const int count = end - begin;
249 IntermediateResults<typename qValueType<Iterator>::value_type> results;
250 results.begin = begin;
251 results.end = end;
252 results.vector.reserve(count);
253
254 Iterator it = sequenceBeginIterator;
255 std::advance(it, begin);
256 for (int i = begin; i < end; ++i) {
257 if (std::invoke(keep, *it))
258 results.vector.append(*it);
259 std::advance(it, 1);
260 }
261
262 this->reportResults(results.vector, begin, count);
263 return false;
264 }
265};
266
267//! [QtConcurrent-2]
268template <typename Iterator, typename KeepFunctor>
269inline
271startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
272{
273 return startThreadEngine(new FilteredEachKernel<Iterator, std::decay_t<KeepFunctor>>
274 (pool, begin, end, std::forward<KeepFunctor>(functor)));
275}
276
277//! [QtConcurrent-3]
278template <typename Sequence, typename KeepFunctor>
279inline decltype(auto) startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
280{
281 using DecayedSequence = std::decay_t<Sequence>;
282 using DecayedFunctor = std::decay_t<KeepFunctor>;
283 using SequenceHolderType = SequenceHolder1<DecayedSequence,
284 FilteredEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
285 DecayedFunctor>;
286 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
287 std::forward<KeepFunctor>(functor)));
288}
289
290//! [QtConcurrent-4]
291template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
293 Sequence &&sequence,
294 MapFunctor &&mapFunctor,
295 ReduceFunctor &&reduceFunctor,
296 ReduceOptions options)
297{
298 using DecayedSequence = std::decay_t<Sequence>;
299 using DecayedMapFunctor = std::decay_t<MapFunctor>;
300 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
301 using Iterator = typename DecayedSequence::const_iterator;
302 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
303 typename qValueType<Iterator>::value_type>;
304 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
305 DecayedReduceFunctor, Reducer>;
306 using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
307 DecayedMapFunctor, DecayedReduceFunctor>;
308 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
309 std::forward<MapFunctor>(mapFunctor),
310 std::forward<ReduceFunctor>(reduceFunctor),
311 options));
312}
313
314
315//! [QtConcurrent-5]
316template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
318 Iterator begin,
319 Iterator end,
320 MapFunctor &&mapFunctor,
321 ReduceFunctor &&reduceFunctor,
322 ReduceOptions options)
323{
324 using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
325 typename qValueType<Iterator>::value_type>;
326 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
327 std::decay_t<ReduceFunctor>, Reducer>;
328 return startThreadEngine(
329 new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
330 std::forward<ReduceFunctor>(reduceFunctor), options));
331}
332
333// Repeat the two functions above, but now with an initial value!
334//! [QtConcurrent-6]
335template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
337 Sequence &&sequence,
338 MapFunctor &&mapFunctor,
339 ReduceFunctor &&reduceFunctor,
340 ResultType &&initialValue,
341 ReduceOptions options)
342{
343 using DecayedSequence = std::decay_t<Sequence>;
344 using DecayedMapFunctor = std::decay_t<MapFunctor>;
345 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
346 using Iterator = typename DecayedSequence::const_iterator;
347 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
348 typename qValueType<Iterator>::value_type>;
349 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
350 DecayedReduceFunctor, Reducer>;
351 using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
352 DecayedMapFunctor, DecayedReduceFunctor>;
353 return startThreadEngine(new SequenceHolderType(
354 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(mapFunctor),
355 std::forward<ReduceFunctor>(reduceFunctor), std::forward<ResultType>(initialValue),
356 options));
357}
358
359//! [QtConcurrent-7]
360template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
362 Iterator begin,
363 Iterator end,
364 MapFunctor &&mapFunctor,
365 ReduceFunctor &&reduceFunctor,
366 ResultType &&initialValue,
367 ReduceOptions options)
368{
369 using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
370 typename qValueType<Iterator>::value_type>;
371 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
372 std::decay_t<ReduceFunctor>, Reducer>;
373 return startThreadEngine(
374 new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
375 std::forward<ReduceFunctor>(reduceFunctor),
376 std::forward<ResultType>(initialValue), options));
377}
378
379
380} // namespace QtConcurrent
381
382
383QT_END_NAMESPACE
384
385#endif // QT_NO_CONCURRENT
386
387#endif
FilterKernel(QThreadPool *pool, Sequence &_sequence, Keep &&_keep, Reduce &&_reduce)
bool runIteration(typename Sequence::const_iterator it, int index, T *) override
bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override
bool runIteration(Iterator it, int index, T *) override
FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep)
bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *) override
FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep, Reduce &&_reduce, ReduceOptions reduceOption)
bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *) override
bool runIteration(Iterator it, int index, ReducedResultType *) override
FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep, Reduce &&_reduce, ReducedResultType &&initialValue, ReduceOptions reduceOption)
\inmodule QtConcurrent
ThreadEngineStarter< ResultType > startFilteredReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
[QtConcurrent-6]
ThreadEngineStarter< ResultType > startFilteredReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
[QtConcurrent-4]
decltype(auto) startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
[QtConcurrent-3]
ThreadEngineStarter< ResultType > startFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options)
[QtConcurrent-5]
ThreadEngineStarter< typename qValueType< Iterator >::value_type > startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
[QtConcurrent-2]
ThreadEngineStarter< ResultType > startFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options)
[QtConcurrent-7]