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, KeepFunctor, ReduceFunctor> KernelType;
60 return startThreadEngine(new KernelType(pool, sequence, keep, reduce));
61}
62
63// filter() on sequences
64template <typename Sequence, typename KeepFunctor>
65QFuture<void> filter(QThreadPool *pool, Sequence &sequence, KeepFunctor keep)
66{
67 return filterInternal(pool, sequence, keep, QtPrivate::PushBackWrapper());
68}
69
70template <typename Sequence, typename KeepFunctor>
71QFuture<void> filter(Sequence &sequence, KeepFunctor keep)
72{
73 return filterInternal(QThreadPool::globalInstance(),
74 sequence, keep, QtPrivate::PushBackWrapper());
75}
76
77// filteredReduced() on sequences
78template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
79QFuture<ResultType> filteredReduced(QThreadPool *pool,
80 Sequence &&sequence,
81 KeepFunctor keep,
82 ReduceFunctor reduce,
83 ReduceOptions options = ReduceOptions(UnorderedReduce
84 | SequentialReduce))
85{
86 return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence), keep, reduce,
87 options);
88}
89
90template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
91QFuture<ResultType> filteredReduced(Sequence &&sequence,
92 KeepFunctor keep,
93 ReduceFunctor reduce,
94 ReduceOptions options = ReduceOptions(UnorderedReduce
95 | SequentialReduce))
96{
97 return startFilteredReduced<ResultType>(
98 QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep, reduce, options);
99}
100
101#ifdef Q_CLANG_QDOC
102template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
103 typename InitialValueType>
104#else
105template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
106 typename InitialValueType,
107 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
108#endif
109QFuture<ResultType> filteredReduced(QThreadPool *pool,
110 Sequence &&sequence,
111 KeepFunctor keep,
112 ReduceFunctor reduce,
113 InitialValueType &&initialValue,
114 ReduceOptions options = ReduceOptions(UnorderedReduce
115 | SequentialReduce))
116{
117 return startFilteredReduced<ResultType>(
118 pool, std::forward<Sequence>(sequence), keep, reduce,
119 ResultType(std::forward<InitialValueType>(initialValue)), options);
120}
121
122#ifdef Q_CLANG_QDOC
123template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
124 typename InitialValueType>
125#else
126template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
127 typename InitialValueType,
128 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
129#endif
130QFuture<ResultType> filteredReduced(Sequence &&sequence,
131 KeepFunctor keep,
132 ReduceFunctor reduce,
133 InitialValueType &&initialValue,
134 ReduceOptions options = ReduceOptions(UnorderedReduce
135 | SequentialReduce))
136{
137 return startFilteredReduced<ResultType>(
138 QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep, reduce,
139 ResultType(std::forward<InitialValueType>(initialValue)), options);
140}
141
142#ifndef Q_CLANG_QDOC
143template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
144 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
145QFuture<ResultType> filteredReduced(QThreadPool *pool,
146 Sequence &&sequence,
147 KeepFunctor keep,
148 ReduceFunctor reduce,
149 ReduceOptions options = ReduceOptions(UnorderedReduce
150 | SequentialReduce))
151{
152 return startFilteredReduced<ResultType>(pool, std::forward<Sequence>(sequence), keep, reduce,
153 options);
154}
155
156template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
157 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
158QFuture<ResultType> filteredReduced(Sequence &&sequence,
159 KeepFunctor keep,
160 ReduceFunctor reduce,
161 ReduceOptions options = ReduceOptions(UnorderedReduce
162 | SequentialReduce))
163{
164 return startFilteredReduced<ResultType>(
165 QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep, reduce, options);
166}
167
168template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
169 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
170 typename InitialValueType,
171 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
172QFuture<ResultType> filteredReduced(QThreadPool *pool,
173 Sequence &&sequence,
174 KeepFunctor keep,
175 ReduceFunctor reduce,
176 InitialValueType &&initialValue,
177 ReduceOptions options = ReduceOptions(UnorderedReduce
178 | SequentialReduce))
179{
180 return startFilteredReduced<ResultType>(
181 pool, std::forward<Sequence>(sequence), keep, reduce,
182 ResultType(std::forward<InitialValueType>(initialValue)), options);
183}
184
185template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
186 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
187 typename InitialValueType,
188 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
189QFuture<ResultType> filteredReduced(Sequence &&sequence,
190 KeepFunctor keep,
191 ReduceFunctor reduce,
192 InitialValueType &&initialValue,
193 ReduceOptions options = ReduceOptions(UnorderedReduce
194 | SequentialReduce))
195{
196 return startFilteredReduced<ResultType>(
197 QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep, reduce,
198 ResultType(std::forward<InitialValueType>(initialValue)), options);
199}
200#endif
201
202// filteredReduced() on iterators
203template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
204QFuture<ResultType> filteredReduced(QThreadPool *pool,
205 Iterator begin,
206 Iterator end,
207 KeepFunctor keep,
208 ReduceFunctor reduce,
209 ReduceOptions options = ReduceOptions(UnorderedReduce
210 | SequentialReduce))
211{
212 return startFilteredReduced<ResultType>(pool, begin, end, keep, reduce, options);
213}
214
215template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
216QFuture<ResultType> filteredReduced(Iterator begin,
217 Iterator end,
218 KeepFunctor keep,
219 ReduceFunctor reduce,
220 ReduceOptions options = ReduceOptions(UnorderedReduce
221 | SequentialReduce))
222{
223 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end, keep, reduce,
224 options);
225}
226
227#ifdef Q_CLANG_QDOC
228template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
229 typename InitialValueType>
230#else
231template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
232 typename InitialValueType,
233 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
234#endif
235QFuture<ResultType> filteredReduced(QThreadPool *pool,
236 Iterator begin,
237 Iterator end,
238 KeepFunctor keep,
239 ReduceFunctor reduce,
240 InitialValueType &&initialValue,
241 ReduceOptions options = ReduceOptions(UnorderedReduce
242 | SequentialReduce))
243{
244 return startFilteredReduced<ResultType>(pool, begin, end, keep, reduce,
245 ResultType(std::forward<InitialValueType>(initialValue)), options);
246}
247
248#ifdef Q_CLANG_QDOC
249template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
250 typename InitialValueType>
251#else
252template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
253 typename InitialValueType,
254 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
255#endif
256QFuture<ResultType> filteredReduced(Iterator begin,
257 Iterator end,
258 KeepFunctor keep,
259 ReduceFunctor reduce,
260 InitialValueType &&initialValue,
261 ReduceOptions options = ReduceOptions(UnorderedReduce
262 | SequentialReduce))
263{
264 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end, keep, reduce,
265 ResultType(std::forward<InitialValueType>(initialValue)), options);
266}
267
268#ifndef Q_CLANG_QDOC
269template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
270 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
271QFuture<ResultType> filteredReduced(QThreadPool *pool,
272 Iterator begin,
273 Iterator end,
274 KeepFunctor keep,
275 ReduceFunctor reduce,
276 ReduceOptions options = ReduceOptions(UnorderedReduce
277 | SequentialReduce))
278{
279 return startFilteredReduced<ResultType>(pool, begin, end, keep, reduce, options);
280}
281
282template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
283 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
284QFuture<ResultType> filteredReduced(Iterator begin,
285 Iterator end,
286 KeepFunctor keep,
287 ReduceFunctor reduce,
288 ReduceOptions options = ReduceOptions(UnorderedReduce
289 | SequentialReduce))
290{
291 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(),
292 begin, end, keep, reduce, options);
293}
294
295template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
296 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
297 typename InitialValueType,
298 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
299QFuture<ResultType> filteredReduced(QThreadPool *pool,
300 Iterator begin,
301 Iterator end,
302 KeepFunctor keep,
303 ReduceFunctor reduce,
304 InitialValueType &&initialValue,
305 ReduceOptions options = ReduceOptions(UnorderedReduce
306 | SequentialReduce))
307{
308 return startFilteredReduced<ResultType>(pool, begin, end, keep, reduce,
309 ResultType(std::forward<InitialValueType>(initialValue)), options);
310}
311
312template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
313 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
314 typename InitialValueType,
315 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
316QFuture<ResultType> filteredReduced(Iterator begin,
317 Iterator end,
318 KeepFunctor keep,
319 ReduceFunctor reduce,
320 InitialValueType &&initialValue,
321 ReduceOptions options = ReduceOptions(UnorderedReduce
322 | SequentialReduce))
323{
324 return startFilteredReduced<ResultType>(QThreadPool::globalInstance(), begin, end, keep, reduce,
325 ResultType(std::forward<InitialValueType>(initialValue)), options);
326}
327#endif
328
329// filtered() on sequences
330template <typename Sequence, typename KeepFunctor>
331QFuture<typename std::decay_t<Sequence>::value_type> filtered(QThreadPool *pool,
332 Sequence &&sequence, KeepFunctor keep)
333{
334 return startFiltered(pool, std::forward<Sequence>(sequence), keep);
335}
336
337template <typename Sequence, typename KeepFunctor>
338QFuture<typename std::decay_t<Sequence>::value_type> filtered(Sequence &&sequence, KeepFunctor keep)
339{
340 return startFiltered(QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep);
341}
342
343// filtered() on iterators
344template <typename Iterator, typename KeepFunctor>
345QFuture<typename qValueType<Iterator>::value_type> filtered(QThreadPool *pool,
346 Iterator begin,
347 Iterator end,
348 KeepFunctor keep)
349{
350 return startFiltered(pool, begin, end, keep);
351}
352
353template <typename Iterator, typename KeepFunctor>
354QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin,
355 Iterator end,
356 KeepFunctor keep)
357{
358 return startFiltered(QThreadPool::globalInstance(), begin, end, keep);
359}
360
361// blocking filter() on sequences
362template <typename Sequence, typename KeepFunctor>
363void blockingFilter(QThreadPool *pool, Sequence &sequence, KeepFunctor keep)
364{
365 QFuture<void> future = filter(pool, sequence, keep);
366 future.waitForFinished();
367}
368
369template <typename Sequence, typename KeepFunctor>
370void blockingFilter(Sequence &sequence, KeepFunctor keep)
371{
372 QFuture<void> future = filter(sequence, keep);
373 future.waitForFinished();
374}
375
376// blocking filteredReduced() on sequences
377template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
378ResultType blockingFilteredReduced(QThreadPool *pool,
379 Sequence &&sequence,
380 KeepFunctor keep,
381 ReduceFunctor reduce,
382 ReduceOptions options = ReduceOptions(UnorderedReduce
383 | SequentialReduce))
384{
385 QFuture<ResultType> future = filteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
386 keep, reduce, options);
387 return future.takeResult();
388}
389
390template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor>
391ResultType blockingFilteredReduced(Sequence &&sequence,
392 KeepFunctor keep,
393 ReduceFunctor reduce,
394 ReduceOptions options = ReduceOptions(UnorderedReduce
395 | SequentialReduce))
396{
397 QFuture<ResultType> future =
398 filteredReduced<ResultType>(std::forward<Sequence>(sequence), keep, reduce, options);
399 return future.takeResult();
400}
401
402#ifdef Q_CLANG_QDOC
403template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
404 typename InitialValueType>
405#else
406template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
407 typename InitialValueType,
408 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
409#endif
410ResultType blockingFilteredReduced(QThreadPool *pool,
411 Sequence &&sequence,
412 KeepFunctor keep,
413 ReduceFunctor reduce,
414 InitialValueType &&initialValue,
415 ReduceOptions options = ReduceOptions(UnorderedReduce
416 | SequentialReduce))
417{
418 QFuture<ResultType> future = filteredReduced<ResultType>(
419 pool, std::forward<Sequence>(sequence), keep, reduce,
420 ResultType(std::forward<InitialValueType>(initialValue)), options);
421 return future.takeResult();
422}
423
424#ifdef Q_CLANG_QDOC
425template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
426 typename InitialValueType>
427#else
428template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor,
429 typename InitialValueType,
430 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
431#endif
432ResultType blockingFilteredReduced(Sequence &&sequence,
433 KeepFunctor keep,
434 ReduceFunctor reduce,
435 InitialValueType &&initialValue,
436 ReduceOptions options = ReduceOptions(UnorderedReduce
437 | SequentialReduce))
438{
439 QFuture<ResultType> future = filteredReduced<ResultType>(
440 std::forward<Sequence>(sequence), keep, reduce,
441 ResultType(std::forward<InitialValueType>(initialValue)), options);
442 return future.takeResult();
443}
444
445#ifndef Q_CLANG_QDOC
446template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
447 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
448ResultType blockingFilteredReduced(QThreadPool *pool,
449 Sequence &&sequence,
450 KeepFunctor keep,
451 ReduceFunctor reduce,
452 ReduceOptions options = ReduceOptions(UnorderedReduce
453 | SequentialReduce))
454{
455 QFuture<ResultType> future = filteredReduced<ResultType>(pool, std::forward<Sequence>(sequence),
456 keep, reduce, options);
457 return future.takeResult();
458}
459
460template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
461 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
462ResultType blockingFilteredReduced(Sequence &&sequence,
463 KeepFunctor keep,
464 ReduceFunctor reduce,
465 ReduceOptions options = ReduceOptions(UnorderedReduce
466 | SequentialReduce))
467{
468 QFuture<ResultType> future =
469 filteredReduced<ResultType>(std::forward<Sequence>(sequence), keep, reduce, options);
470 return future.takeResult();
471}
472
473template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
474 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
475 typename InitialValueType,
476 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
477ResultType blockingFilteredReduced(QThreadPool *pool,
478 Sequence &&sequence,
479 KeepFunctor keep,
480 ReduceFunctor reduce,
481 InitialValueType &&initialValue,
482 ReduceOptions options = ReduceOptions(UnorderedReduce
483 | SequentialReduce))
484{
485 QFuture<ResultType> future = filteredReduced<ResultType>(
486 pool, std::forward<Sequence>(sequence), keep, reduce,
487 ResultType(std::forward<InitialValueType>(initialValue)), options);
488 return future.takeResult();
489}
490
491template <typename Sequence, typename KeepFunctor, typename ReduceFunctor,
492 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
493 typename InitialValueType,
494 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
495ResultType blockingFilteredReduced(Sequence &&sequence,
496 KeepFunctor keep,
497 ReduceFunctor reduce,
498 InitialValueType &&initialValue,
499 ReduceOptions options = ReduceOptions(UnorderedReduce
500 | SequentialReduce))
501{
502 QFuture<ResultType> future = filteredReduced<ResultType>(
503 std::forward<Sequence>(sequence), keep, reduce,
504 ResultType(std::forward<InitialValueType>(initialValue)), options);
505 return future.takeResult();
506}
507#endif
508
509// blocking filteredReduced() on iterators
510template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
511ResultType blockingFilteredReduced(QThreadPool *pool,
512 Iterator begin,
513 Iterator end,
514 KeepFunctor keep,
515 ReduceFunctor reduce,
516 ReduceOptions options = ReduceOptions(UnorderedReduce
517 | SequentialReduce))
518{
519 QFuture<ResultType> future =
520 filteredReduced<ResultType>(pool, begin, end, keep, reduce, options);
521 return future.takeResult();
522}
523
524template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor>
525ResultType blockingFilteredReduced(Iterator begin,
526 Iterator end,
527 KeepFunctor keep,
528 ReduceFunctor reduce,
529 ReduceOptions options = ReduceOptions(UnorderedReduce
530 | SequentialReduce))
531{
532 QFuture<ResultType> future = filteredReduced<ResultType>(begin, end, keep, reduce, options);
533 return future.takeResult();
534}
535
536#ifdef Q_CLANG_QDOC
537template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
538 typename InitialValueType>
539#else
540template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
541 typename InitialValueType,
542 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
543#endif
544ResultType blockingFilteredReduced(QThreadPool *pool,
545 Iterator begin,
546 Iterator end,
547 KeepFunctor keep,
548 ReduceFunctor reduce,
549 InitialValueType &&initialValue,
550 ReduceOptions options = ReduceOptions(UnorderedReduce
551 | SequentialReduce))
552{
553 QFuture<ResultType> future = filteredReduced<ResultType>(
554 pool, begin, end, keep, reduce,
555 ResultType(std::forward<InitialValueType>(initialValue)), options);
556 return future.takeResult();
557}
558
559#ifdef Q_CLANG_QDOC
560template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
561 typename InitialValueType>
562#else
563template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor,
564 typename InitialValueType,
565 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
566#endif
567ResultType blockingFilteredReduced(Iterator begin,
568 Iterator end,
569 KeepFunctor keep,
570 ReduceFunctor reduce,
571 InitialValueType &&initialValue,
572 ReduceOptions options = ReduceOptions(UnorderedReduce
573 | SequentialReduce))
574{
575 QFuture<ResultType> future = filteredReduced<ResultType>(
576 begin, end, keep, reduce, ResultType(std::forward<InitialValueType>(initialValue)),
577 options);
578 return future.takeResult();
579}
580
581#ifndef Q_CLANG_QDOC
582template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
583 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
584ResultType blockingFilteredReduced(QThreadPool *pool,
585 Iterator begin,
586 Iterator end,
587 KeepFunctor keep,
588 ReduceFunctor reduce,
589 ReduceOptions options = ReduceOptions(UnorderedReduce
590 | SequentialReduce))
591{
592 QFuture<ResultType> future =
593 filteredReduced<ResultType>(pool, begin, end, keep, reduce, options);
594 return future.takeResult();
595}
596
597template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
598 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType>
599ResultType blockingFilteredReduced(Iterator begin,
600 Iterator end,
601 KeepFunctor keep,
602 ReduceFunctor reduce,
603 ReduceOptions options = ReduceOptions(UnorderedReduce
604 | SequentialReduce))
605{
606 QFuture<ResultType> future = filteredReduced<ResultType>(begin, end, keep, reduce, options);
607 return future.takeResult();
608}
609
610template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
611 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
612 typename InitialValueType,
613 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
614ResultType blockingFilteredReduced(QThreadPool *pool,
615 Iterator begin,
616 Iterator end, KeepFunctor keep,
617 ReduceFunctor reduce,
618 InitialValueType &&initialValue,
619 ReduceOptions options = ReduceOptions(UnorderedReduce
620 | SequentialReduce))
621{
622 QFuture<ResultType> future = filteredReduced<ResultType>(
623 pool, begin, end, keep, reduce,
624 ResultType(std::forward<InitialValueType>(initialValue)), options);
625 return future.takeResult();
626}
627
628template <typename Iterator, typename KeepFunctor, typename ReduceFunctor,
629 typename ResultType = typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType,
630 typename InitialValueType,
631 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
632ResultType blockingFilteredReduced(Iterator begin,
633 Iterator end,
634 KeepFunctor keep,
635 ReduceFunctor reduce,
636 InitialValueType &&initialValue,
637 ReduceOptions options = ReduceOptions(UnorderedReduce
638 | SequentialReduce))
639{
640 QFuture<ResultType> future = filteredReduced<ResultType>(
641 begin, end, keep, reduce, ResultType(std::forward<InitialValueType>(initialValue)),
642 options);
643 return future.takeResult();
644}
645#endif
646
647// blocking filtered() on sequences
648template <typename Sequence, typename KeepFunctor>
649std::decay_t<Sequence> blockingFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor keep)
650{
651 return blockingFilteredReduced<std::decay_t<Sequence>>(
652 pool, std::forward<Sequence>(sequence), keep, QtPrivate::PushBackWrapper(),
653 OrderedReduce);
654}
655
656template <typename Sequence, typename KeepFunctor>
657std::decay_t<Sequence> blockingFiltered(Sequence &&sequence, KeepFunctor keep)
658{
659 return blockingFilteredReduced<std::decay_t<Sequence>>(
660 QThreadPool::globalInstance(), std::forward<Sequence>(sequence), keep,
661 QtPrivate::PushBackWrapper(), OrderedReduce);
662}
663
664// blocking filtered() on iterators
665template <typename OutputSequence, typename Iterator, typename KeepFunctor>
666OutputSequence blockingFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor keep)
667{
668 return blockingFilteredReduced<OutputSequence>(pool, begin, end, keep,
669 QtPrivate::PushBackWrapper(), OrderedReduce);
670}
671
672template <typename OutputSequence, typename Iterator, typename KeepFunctor>
673OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep)
674{
675 return blockingFilteredReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end, keep,
676 QtPrivate::PushBackWrapper(), OrderedReduce);
677}
678
679} // namespace QtConcurrent
680
681QT_END_NAMESPACE
682
683#endif // QT_NO_CONCURRENT
684
685#endif
686