1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtConcurrent 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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QTCONCURRENT_FILTER_H
41#define QTCONCURRENT_FILTER_H
42
43#include <QtConcurrent/qtconcurrent_global.h>
44
45#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
46
47#include <QtConcurrent/qtconcurrentfilterkernel.h>
48#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
49
50QT_BEGIN_NAMESPACE
51
52namespace QtConcurrent {
53
54//! [QtConcurrent-1]
55template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
56ThreadEngineStarter<void> filterInternal(QThreadPool *pool, Sequence &sequence,
57 KeepFunctor &&keep, ReduceFunctor &&reduce)
58{
59 typedef FilterKernel<Sequence, std::decay_t<KeepFunctor>, std::decay_t<ReduceFunctor>>
60 KernelType;
61 return startThreadEngine(new KernelType(pool, sequence, std::forward<KeepFunctor>(keep),
62 std::forward<ReduceFunctor>(reduce)));
63}
64
65// filter() on sequences
66template <typename Sequence, typename KeepFunctor>
67QFuture<void> filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
68{
69 return filterInternal(pool, sequence, std::forward<KeepFunctor>(keep),
70 QtPrivate::PushBackWrapper());
71}
72
73template <typename Sequence, typename KeepFunctor>
74QFuture<void> filter(Sequence &sequence, KeepFunctor &&keep)
75{
76 return filterInternal(QThreadPool::globalInstance(),
77 sequence, std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper());
78}
79
80// filteredReduced() on sequences
81template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
82QFuture<ResultType> filteredReduced(QThreadPool *pool,
83 Sequence &&sequence,
84 KeepFunctor &&keep,
85 ReduceFunctor &&reduce,
86 ReduceOptions options = ReduceOptions(UnorderedReduce
87 | SequentialReduce))
88{
89 return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
90 std::forward<KeepFunctor>(keep),
91 std::forward<ReduceFunctor>(reduce), options);
92}
93
94template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
95QFuture<ResultType> filteredReduced(Sequence &&sequence,
96 KeepFunctor &&keep,
97 ReduceFunctor &&reduce,
98 ReduceOptions options = ReduceOptions(UnorderedReduce
99 | SequentialReduce))
100{
101 return startFilteredReduced<ResultType>(
102 QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
103 std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
104}
105
106#ifdef Q_CLANG_QDOC
107template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
108 typename InitialValueType>
109#else
110template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
111 typename InitialValueType,
112 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
113#endif
114QFuture<ResultType> filteredReduced(QThreadPool *pool,
115 Sequence &&sequence,
116 KeepFunctor &&keep,
117 ReduceFunctor &&reduce,
118 InitialValueType &&initialValue,
119 ReduceOptions options = ReduceOptions(UnorderedReduce
120 | SequentialReduce))
121{
122 return startFilteredReduced<ResultType>(
123 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
124 std::forward<ReduceFunctor>(reduce),
125 ResultType(std::forward<InitialValueType>(initialValue)), options);
126}
127
128#ifdef Q_CLANG_QDOC
129template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
130 typename InitialValueType>
131#else
132template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
133 typename InitialValueType,
134 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
135#endif
136QFuture<ResultType> filteredReduced(Sequence &&sequence,
137 KeepFunctor &&keep,
138 ReduceFunctor &&reduce,
139 InitialValueType &&initialValue,
140 ReduceOptions options = ReduceOptions(UnorderedReduce
141 | SequentialReduce))
142{
143 return startFilteredReduced<ResultType>(
144 QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
145 std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
146 ResultType(std::forward<InitialValueType>(initialValue)), options);
147}
148
149#ifndef Q_CLANG_QDOC
150template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
151 typename ResultType =
152 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
153QFuture<ResultType> filteredReduced(QThreadPool *pool,
154 Sequence &&sequence,
155 KeepFunctor &&keep,
156 ReduceFunctor &&reduce,
157 ReduceOptions options = ReduceOptions(UnorderedReduce
158 | SequentialReduce))
159{
160 return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
161 std::forward<KeepFunctor>(keep),
162 std::forward<ReduceFunctor>(reduce), options);
163}
164
165template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
166 typename ResultType =
167 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
168QFuture<ResultType> filteredReduced(Sequence &&sequence,
169 KeepFunctor &&keep,
170 ReduceFunctor &&reduce,
171 ReduceOptions options = ReduceOptions(UnorderedReduce
172 | SequentialReduce))
173{
174 return startFilteredReduced<ResultType>(
175 QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
176 std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce), options);
177}
178
179template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
180 typename ResultType =
181 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
182 typename InitialValueType,
183 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
184QFuture<ResultType> filteredReduced(QThreadPool *pool,
185 Sequence &&sequence,
186 KeepFunctor &&keep,
187 ReduceFunctor &&reduce,
188 InitialValueType &&initialValue,
189 ReduceOptions options = ReduceOptions(UnorderedReduce
190 | SequentialReduce))
191{
192 return startFilteredReduced<ResultType>(
193 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
194 std::forward<ReduceFunctor>(reduce),
195 ResultType(std::forward<InitialValueType>(initialValue)), options);
196}
197
198template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
199 typename ResultType =
200 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
201 typename InitialValueType,
202 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
203QFuture<ResultType> filteredReduced(Sequence &&sequence,
204 KeepFunctor &&keep,
205 ReduceFunctor &&reduce,
206 InitialValueType &&initialValue,
207 ReduceOptions options = ReduceOptions(UnorderedReduce
208 | SequentialReduce))
209{
210 return startFilteredReduced<ResultType>(
211 QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
212 std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
213 ResultType(std::forward<InitialValueType>(initialValue)), options);
214}
215#endif
216
217// filteredReduced() on iterators
218template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
219QFuture<ResultType> filteredReduced(QThreadPool *pool,
220 Iterator begin,
221 Iterator end,
222 KeepFunctor &&keep,
223 ReduceFunctor &&reduce,
224 ReduceOptions options = ReduceOptions(UnorderedReduce
225 | SequentialReduce))
226{
227 return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
228 std::forward<ReduceFunctor>(reduce), options);
229}
230
231template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
232QFuture<ResultType> filteredReduced(Iterator begin,
233 Iterator end,
234 KeepFunctor &&keep,
235 ReduceFunctor &&reduce,
236 ReduceOptions options = ReduceOptions(UnorderedReduce
237 | SequentialReduce))
238{
239 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
240 std::forward<KeepFunctor>(keep),
241 std::forward<ReduceFunctor>(reduce), options);
242}
243
244#ifdef Q_CLANG_QDOC
245template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
246 typename InitialValueType>
247#else
248template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
249 typename InitialValueType,
250 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
251#endif
252QFuture<ResultType> filteredReduced(QThreadPool *pool,
253 Iterator begin,
254 Iterator end,
255 KeepFunctor &&keep,
256 ReduceFunctor &&reduce,
257 InitialValueType &&initialValue,
258 ReduceOptions options = ReduceOptions(UnorderedReduce
259 | SequentialReduce))
260{
261 return startFilteredReduced<ResultType>(
262 pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
263 ResultType(std::forward<InitialValueType>(initialValue)), options);
264}
265
266#ifdef Q_CLANG_QDOC
267template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
268 typename InitialValueType>
269#else
270template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
271 typename InitialValueType,
272 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
273#endif
274QFuture<ResultType> filteredReduced(Iterator begin,
275 Iterator end,
276 KeepFunctor &&keep,
277 ReduceFunctor &&reduce,
278 InitialValueType &&initialValue,
279 ReduceOptions options = ReduceOptions(UnorderedReduce
280 | SequentialReduce))
281{
282 return startFilteredReduced<ResultType>(
283 QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
284 std::forward<ReduceFunctor>(reduce),
285 ResultType(std::forward<InitialValueType>(initialValue)), options);
286}
287
288#ifndef Q_CLANG_QDOC
289template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
290 typename ResultType =
291 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
292QFuture<ResultType> filteredReduced(QThreadPool *pool,
293 Iterator begin,
294 Iterator end,
295 KeepFunctor &&keep,
296 ReduceFunctor &&reduce,
297 ReduceOptions options = ReduceOptions(UnorderedReduce
298 | SequentialReduce))
299{
300 return startFilteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
301 std::forward<ReduceFunctor>(reduce), options);
302}
303
304template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
305 typename ResultType =
306 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
307QFuture<ResultType> filteredReduced(Iterator begin,
308 Iterator end,
309 KeepFunctor &&keep,
310 ReduceFunctor &&reduce,
311 ReduceOptions options = ReduceOptions(UnorderedReduce
312 | SequentialReduce))
313{
314 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end,
315 std::forward<KeepFunctor>(keep),
316 std::forward<ReduceFunctor>(reduce), options);
317}
318
319template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
320 typename ResultType =
321 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
322 typename InitialValueType,
323 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
324QFuture<ResultType> filteredReduced(QThreadPool *pool,
325 Iterator begin,
326 Iterator end,
327 KeepFunctor &&keep,
328 ReduceFunctor &&reduce,
329 InitialValueType &&initialValue,
330 ReduceOptions options = ReduceOptions(UnorderedReduce
331 | SequentialReduce))
332{
333 return startFilteredReduced<ResultType>(
334 pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
335 ResultType(std::forward<InitialValueType>(initialValue)), options);
336}
337
338template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
339 typename ResultType =
340 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
341 typename InitialValueType,
342 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
343QFuture<ResultType> filteredReduced(Iterator begin,
344 Iterator end,
345 KeepFunctor &&keep,
346 ReduceFunctor &&reduce,
347 InitialValueType &&initialValue,
348 ReduceOptions options = ReduceOptions(UnorderedReduce
349 | SequentialReduce))
350{
351 return startFilteredReduced<ResultType>(
352 QThreadPool::globalInstance(), begin, end, std::forward<KeepFunctor>(keep),
353 std::forward<ReduceFunctor>(reduce),
354 ResultType(std::forward<InitialValueType>(initialValue)), options);
355}
356#endif
357
358// filtered() on sequences
359template <typename Sequence, typename KeepFunctor>
360QFuture<typename std::decay_t<Sequence>::value_type> filtered(QThreadPool *pool,Sequence &&sequence,
361 KeepFunctor &&keep)
362{
363 return startFiltered(pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep));
364}
365
366template <typename Sequence, typename KeepFunctor>
367QFuture<typename std::decay_t<Sequence>::value_type> filtered(Sequence &&sequence,
368 KeepFunctor &&keep)
369{
370 return startFiltered(QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
371 std::forward<KeepFunctor>(keep));
372}
373
374// filtered() on iterators
375template <typename Iterator, typename KeepFunctor>
376QFuture<typename qValueType<Iterator>::value_type> filtered(QThreadPool *pool,
377 Iterator begin,
378 Iterator end,
379 KeepFunctor &&keep)
380{
381 return startFiltered(pool, begin, end, std::forward<KeepFunctor>(keep));
382}
383
384template <typename Iterator, typename KeepFunctor>
385QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin,
386 Iterator end,
387 KeepFunctor &&keep)
388{
389 return startFiltered(QThreadPool::globalInstance(), begin, end,
390 std::forward<KeepFunctor>(keep));
391}
392
393// blocking filter() on sequences
394template <typename Sequence, typename KeepFunctor>
395void blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&keep)
396{
397 QFuture<void> future = filter(pool, sequence, std::forward<KeepFunctor>(keep));
398 future.waitForFinished();
399}
400
401template <typename Sequence, typename KeepFunctor>
402void blockingFilter(Sequence &sequence, KeepFunctor &&keep)
403{
404 QFuture<void> future = filter(sequence, std::forward<KeepFunctor>(keep));
405 future.waitForFinished();
406}
407
408// blocking filteredReduced() on sequences
409template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
410ResultType blockingFilteredReduced(QThreadPool *pool,
411 Sequence &&sequence,
412 KeepFunctor &&keep,
413 ReduceFunctor &&reduce,
414 ReduceOptions options = ReduceOptions(UnorderedReduce
415 | SequentialReduce))
416{
417 QFuture<ResultType> future = filteredReduced<ResultType>(
418 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
419 std::forward<ReduceFunctor>(reduce), options);
420 return future.takeResult();
421}
422
423template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
424ResultType blockingFilteredReduced(Sequence &&sequence,
425 KeepFunctor &&keep,
426 ReduceFunctor &&reduce,
427 ReduceOptions options = ReduceOptions(UnorderedReduce
428 | SequentialReduce))
429{
430 QFuture<ResultType> future = filteredReduced<ResultType>(
431 std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
432 std::forward<ReduceFunctor>(reduce), options);
433 return future.takeResult();
434}
435
436#ifdef Q_CLANG_QDOC
437template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
438 typename InitialValueType>
439#else
440template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
441 typename InitialValueType,
442 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
443#endif
444ResultType blockingFilteredReduced(QThreadPool *pool,
445 Sequence &&sequence,
446 KeepFunctor &&keep,
447 ReduceFunctor &&reduce,
448 InitialValueType &&initialValue,
449 ReduceOptions options = ReduceOptions(UnorderedReduce
450 | SequentialReduce))
451{
452 QFuture<ResultType> future = filteredReduced<ResultType>(
453 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
454 std::forward<ReduceFunctor>(reduce),
455 ResultType(std::forward<InitialValueType>(initialValue)), options);
456 return future.takeResult();
457}
458
459#ifdef Q_CLANG_QDOC
460template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
461 typename InitialValueType>
462#else
463template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
464 typename InitialValueType,
465 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
466#endif
467ResultType blockingFilteredReduced(Sequence &&sequence,
468 KeepFunctor &&keep,
469 ReduceFunctor &&reduce,
470 InitialValueType &&initialValue,
471 ReduceOptions options = ReduceOptions(UnorderedReduce
472 | SequentialReduce))
473{
474 QFuture<ResultType> future = filteredReduced<ResultType>(
475 std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
476 std::forward<ReduceFunctor>(reduce),
477 ResultType(std::forward<InitialValueType>(initialValue)), options);
478 return future.takeResult();
479}
480
481#ifndef Q_CLANG_QDOC
482template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
483 typename ResultType =
484 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
485ResultType blockingFilteredReduced(QThreadPool *pool,
486 Sequence &&sequence,
487 KeepFunctor &&keep,
488 ReduceFunctor &&reduce,
489 ReduceOptions options = ReduceOptions(UnorderedReduce
490 | SequentialReduce))
491{
492 QFuture<ResultType> future = filteredReduced<ResultType>(
493 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
494 std::forward<ReduceFunctor>(reduce), options);
495 return future.takeResult();
496}
497
498template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
499 typename ResultType =
500 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
501ResultType blockingFilteredReduced(Sequence &&sequence,
502 KeepFunctor &&keep,
503 ReduceFunctor &&reduce,
504 ReduceOptions options = ReduceOptions(UnorderedReduce
505 | SequentialReduce))
506{
507 QFuture<ResultType> future = filteredReduced<ResultType>(
508 std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
509 std::forward<ReduceFunctor>(reduce), options);
510 return future.takeResult();
511}
512
513template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
514 typename ResultType =
515 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
516 typename InitialValueType,
517 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
518ResultType blockingFilteredReduced(QThreadPool *pool,
519 Sequence &&sequence,
520 KeepFunctor &&keep,
521 ReduceFunctor &&reduce,
522 InitialValueType &&initialValue,
523 ReduceOptions options = ReduceOptions(UnorderedReduce
524 | SequentialReduce))
525{
526 QFuture<ResultType> future = filteredReduced<ResultType>(
527 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
528 std::forward<ReduceFunctor>(reduce),
529 ResultType(std::forward<InitialValueType>(initialValue)), options);
530 return future.takeResult();
531}
532
533template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
534 typename ResultType =
535 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
536 typename InitialValueType,
537 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
538ResultType blockingFilteredReduced(Sequence &&sequence,
539 KeepFunctor &&keep,
540 ReduceFunctor &&reduce,
541 InitialValueType &&initialValue,
542 ReduceOptions options = ReduceOptions(UnorderedReduce
543 | SequentialReduce))
544{
545 QFuture<ResultType> future = filteredReduced<ResultType>(
546 std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
547 std::forward<ReduceFunctor>(reduce),
548 ResultType(std::forward<InitialValueType>(initialValue)), options);
549 return future.takeResult();
550}
551#endif
552
553// blocking filteredReduced() on iterators
554template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
555ResultType blockingFilteredReduced(QThreadPool *pool,
556 Iterator begin,
557 Iterator end,
558 KeepFunctor &&keep,
559 ReduceFunctor &&reduce,
560 ReduceOptions options = ReduceOptions(UnorderedReduce
561 | SequentialReduce))
562{
563 QFuture<ResultType> future =
564 filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
565 std::forward<ReduceFunctor>(reduce), options);
566 return future.takeResult();
567}
568
569template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
570ResultType blockingFilteredReduced(Iterator begin,
571 Iterator end,
572 KeepFunctor &&keep,
573 ReduceFunctor &&reduce,
574 ReduceOptions options = ReduceOptions(UnorderedReduce
575 | SequentialReduce))
576{
577 QFuture<ResultType> future =
578 filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
579 std::forward<ReduceFunctor>(reduce), options);
580 return future.takeResult();
581}
582
583#ifdef Q_CLANG_QDOC
584template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
585 typename InitialValueType>
586#else
587template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
588 typename InitialValueType,
589 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
590#endif
591ResultType blockingFilteredReduced(QThreadPool *pool,
592 Iterator begin,
593 Iterator end,
594 KeepFunctor &&keep,
595 ReduceFunctor &&reduce,
596 InitialValueType &&initialValue,
597 ReduceOptions options = ReduceOptions(UnorderedReduce
598 | SequentialReduce))
599{
600 QFuture<ResultType> future = filteredReduced<ResultType>(
601 pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
602 ResultType(std::forward<InitialValueType>(initialValue)), options);
603 return future.takeResult();
604}
605
606#ifdef Q_CLANG_QDOC
607template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
608 typename InitialValueType>
609#else
610template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
611 typename InitialValueType,
612 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
613#endif
614ResultType blockingFilteredReduced(Iterator begin,
615 Iterator end,
616 KeepFunctor &&keep,
617 ReduceFunctor &&reduce,
618 InitialValueType &&initialValue,
619 ReduceOptions options = ReduceOptions(UnorderedReduce
620 | SequentialReduce))
621{
622 QFuture<ResultType> future = filteredReduced<ResultType>(
623 begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
624 ResultType(std::forward<InitialValueType>(initialValue)), options);
625 return future.takeResult();
626}
627
628#ifndef Q_CLANG_QDOC
629template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
630 typename ResultType =
631 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
632ResultType blockingFilteredReduced(QThreadPool *pool,
633 Iterator begin,
634 Iterator end,
635 KeepFunctor &&keep,
636 ReduceFunctor &&reduce,
637 ReduceOptions options = ReduceOptions(UnorderedReduce
638 | SequentialReduce))
639{
640 QFuture<ResultType> future =
641 filteredReduced<ResultType>(pool, begin, end, std::forward<KeepFunctor>(keep),
642 std::forward<ReduceFunctor>(reduce), options);
643 return future.takeResult();
644}
645
646template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
647 typename ResultType =
648 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
649ResultType blockingFilteredReduced(Iterator begin,
650 Iterator end,
651 KeepFunctor &&keep,
652 ReduceFunctor &&reduce,
653 ReduceOptions options = ReduceOptions(UnorderedReduce
654 | SequentialReduce))
655{
656 QFuture<ResultType> future =
657 filteredReduced<ResultType>(begin, end, std::forward<KeepFunctor>(keep),
658 std::forward<ReduceFunctor>(reduce), options);
659 return future.takeResult();
660}
661
662template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
663 typename ResultType =
664 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
665 typename InitialValueType,
666 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
667ResultType blockingFilteredReduced(QThreadPool *pool,
668 Iterator begin,
669 Iterator end, KeepFunctor &&keep,
670 ReduceFunctor &&reduce,
671 InitialValueType &&initialValue,
672 ReduceOptions options = ReduceOptions(UnorderedReduce
673 | SequentialReduce))
674{
675 QFuture<ResultType> future = filteredReduced<ResultType>(
676 pool, begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
677 ResultType(std::forward<InitialValueType>(initialValue)), options);
678 return future.takeResult();
679}
680
681template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
682 typename ResultType =
683 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
684 typename InitialValueType,
685 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
686ResultType blockingFilteredReduced(Iterator begin,
687 Iterator end,
688 KeepFunctor &&keep,
689 ReduceFunctor &&reduce,
690 InitialValueType &&initialValue,
691 ReduceOptions options = ReduceOptions(UnorderedReduce
692 | SequentialReduce))
693{
694 QFuture<ResultType> future = filteredReduced<ResultType>(
695 begin, end, std::forward<KeepFunctor>(keep), std::forward<ReduceFunctor>(reduce),
696 ResultType(std::forward<InitialValueType>(initialValue)), options);
697 return future.takeResult();
698}
699#endif
700
701// blocking filtered() on sequences
702template <typename Sequence, typename KeepFunctor>
703std::decay_t<Sequence> blockingFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep)
704{
705 return blockingFilteredReduced<std::decay_t<Sequence>>(
706 pool, std::forward<Sequence>(sequence), std::forward<KeepFunctor>(keep),
707 QtPrivate::PushBackWrapper(), OrderedReduce);
708}
709
710template <typename Sequence, typename KeepFunctor>
711std::decay_t<Sequence> blockingFiltered(Sequence &&sequence, KeepFunctor &&keep)
712{
713 return blockingFilteredReduced<std::decay_t<Sequence>>(
714 QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
715 std::forward<KeepFunctor>(keep), QtPrivate::PushBackWrapper(), OrderedReduce);
716}
717
718// blocking filtered() on iterators
719template <typename OutputSequence, typename Iterator, typename KeepFunctor>
720OutputSequence blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep)
721{
722 return blockingFilteredReduced<OutputSequence>(pool, begin, end,
723 std::forward<KeepFunctor>(keep),
724 QtPrivate::PushBackWrapper(), OrderedReduce);
725}
726
727template <typename OutputSequence, typename Iterator, typename KeepFunctor>
728OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor &&keep)
729{
730 return blockingFilteredReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
731 std::forward<KeepFunctor>(keep),
732 QtPrivate::PushBackWrapper(), OrderedReduce);
733}
734
735} // namespace QtConcurrent
736
737QT_END_NAMESPACE
738
739#endif // QT_NO_CONCURRENT
740
741#endif
742