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_MAP_H
41#define QTCONCURRENT_MAP_H
42
43#include <QtConcurrent/qtconcurrent_global.h>
44
45#if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC)
46
47#include <QtConcurrent/qtconcurrentmapkernel.h>
48#include <QtConcurrent/qtconcurrentreducekernel.h>
49#include <QtConcurrent/qtconcurrentfunctionwrappers.h>
50#include <QtCore/qstringlist.h>
51
52QT_BEGIN_NAMESPACE
53
54
55
56namespace QtConcurrent {
57
58// map() on sequences
59template <typename Sequence, typename MapFunctor>
60QFuture<void> map(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map)
61{
62 return startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
63}
64
65template <typename Sequence, typename MapFunctor>
66QFuture<void> map(Sequence &&sequence, MapFunctor &&map)
67{
68 return startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
69 std::forward<MapFunctor>(map));
70}
71
72// map() on iterators
73template <typename Iterator, typename MapFunctor>
74QFuture<void> map(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
75{
76 return startMap(pool, begin, end, std::forward<MapFunctor>(map));
77}
78
79template <typename Iterator, typename MapFunctor>
80QFuture<void> map(Iterator begin, Iterator end, MapFunctor &&map)
81{
82 return startMap(QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
83}
84
85// mappedReduced() for sequences.
86template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
87QFuture<ResultType> mappedReduced(QThreadPool *pool,
88 Sequence &&sequence,
89 MapFunctor &&map,
90 ReduceFunctor &&reduce,
91 ReduceOptions options = ReduceOptions(UnorderedReduce
92 | SequentialReduce))
93{
94 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
95 (pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
96 std::forward<ReduceFunctor>(reduce), options);
97}
98
99template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
100QFuture<ResultType> mappedReduced(Sequence &&sequence,
101 MapFunctor &&map,
102 ReduceFunctor &&reduce,
103 ReduceOptions options = ReduceOptions(UnorderedReduce
104 | SequentialReduce))
105{
106 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
107 (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
108 std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
109}
110
111#ifdef Q_CLANG_QDOC
112template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
113 typename InitialValueType>
114#else
115template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
116 typename InitialValueType,
117 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
118#endif
119QFuture<ResultType> mappedReduced(QThreadPool *pool,
120 Sequence &&sequence,
121 MapFunctor &&map,
122 ReduceFunctor &&reduce,
123 InitialValueType &&initialValue,
124 ReduceOptions options = ReduceOptions(UnorderedReduce
125 | SequentialReduce))
126{
127 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
128 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
129 std::forward<ReduceFunctor>(reduce),
130 ResultType(std::forward<InitialValueType>(initialValue)), options);
131}
132#ifdef Q_CLANG_QDOC
133template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
134 typename InitialValueType>
135#else
136template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
137 typename InitialValueType,
138 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
139#endif
140QFuture<ResultType> mappedReduced(Sequence &&sequence,
141 MapFunctor &&map,
142 ReduceFunctor &&reduce,
143 InitialValueType &&initialValue,
144 ReduceOptions options = ReduceOptions(UnorderedReduce
145 | SequentialReduce))
146{
147 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
148 (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
149 std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
150 ResultType(std::forward<InitialValueType>(initialValue)), options);
151}
152
153template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
154 typename ResultType =
155 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
156QFuture<ResultType> mappedReduced(QThreadPool *pool,
157 Sequence &&sequence,
158 MapFunctor &&map,
159 ReduceFunctor &&reduce,
160 ReduceOptions options = ReduceOptions(UnorderedReduce
161 | SequentialReduce))
162{
163 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
164 (pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
165 std::forward<ReduceFunctor>(reduce), options);
166}
167
168template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
169 typename ResultType =
170 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
171QFuture<ResultType> mappedReduced(Sequence &&sequence,
172 MapFunctor &&map,
173 ReduceFunctor &&reduce,
174 ReduceOptions options = ReduceOptions(UnorderedReduce
175 | SequentialReduce))
176{
177 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
178 (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
179 std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce), options);
180}
181
182#ifdef Q_CLANG_QDOC
183template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
184 typename InitialValueType>
185#else
186template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
187 typename ResultType =
188 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
189 typename InitialValueType,
190 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
191#endif
192QFuture<ResultType> mappedReduced(QThreadPool *pool,
193 Sequence &&sequence,
194 MapFunctor &&map,
195 ReduceFunctor &&reduce,
196 InitialValueType &&initialValue,
197 ReduceOptions options = ReduceOptions(UnorderedReduce
198 | SequentialReduce))
199{
200 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>(
201 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
202 std::forward<ReduceFunctor>(reduce),
203 ResultType(std::forward<InitialValueType>(initialValue)), options);
204}
205
206#ifdef Q_CLANG_QDOC
207template <typename Sequence, typename MapFunctor, typename ReduceFunctor, typename ResultType,
208 typename InitialValueType>
209#else
210template <typename Sequence, typename MapFunctor, typename ReduceFunctor,
211 typename ResultType =
212 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
213 typename InitialValueType,
214 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
215#endif
216QFuture<ResultType> mappedReduced(Sequence &&sequence,
217 MapFunctor &&map,
218 ReduceFunctor &&reduce,
219 InitialValueType &&initialValue,
220 ReduceOptions options = ReduceOptions(UnorderedReduce
221 | SequentialReduce))
222{
223 return startMappedReduced<QtPrivate::MapResultType<Sequence, MapFunctor>, ResultType>
224 (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
225 std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
226 ResultType(std::forward<InitialValueType>(initialValue)), options);
227}
228
229// mappedReduced() for iterators
230template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
231QFuture<ResultType> mappedReduced(QThreadPool *pool,
232 Iterator begin,
233 Iterator end,
234 MapFunctor &&map,
235 ReduceFunctor &&reduce,
236 ReduceOptions options = ReduceOptions(UnorderedReduce
237 | SequentialReduce))
238{
239 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
240 (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
241 options);
242}
243
244template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
245QFuture<ResultType> mappedReduced(Iterator begin,
246 Iterator end,
247 MapFunctor &&map,
248 ReduceFunctor &&reduce,
249 ReduceOptions options = ReduceOptions(UnorderedReduce
250 | SequentialReduce))
251{
252 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
253 (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
254 std::forward<ReduceFunctor>(reduce), options);
255}
256
257#ifdef Q_CLANG_QDOC
258template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
259 typename InitialValueType>
260#else
261template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
262 typename InitialValueType,
263 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
264#endif
265QFuture<ResultType> mappedReduced(QThreadPool *pool,
266 Iterator begin,
267 Iterator end,
268 MapFunctor &&map,
269 ReduceFunctor &&reduce,
270 InitialValueType &&initialValue,
271 ReduceOptions options = ReduceOptions(UnorderedReduce
272 | SequentialReduce))
273{
274 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
275 (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
276 ResultType(std::forward<InitialValueType>(initialValue)), options);
277}
278
279#ifdef Q_CLANG_QDOC
280template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
281 typename InitialValueType>
282#else
283template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
284 typename InitialValueType,
285 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
286#endif
287QFuture<ResultType> mappedReduced(Iterator begin,
288 Iterator end,
289 MapFunctor &&map,
290 ReduceFunctor &&reduce,
291 InitialValueType &&initialValue,
292 ReduceOptions options = ReduceOptions(UnorderedReduce
293 | SequentialReduce))
294{
295 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
296 (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
297 std::forward<ReduceFunctor>(reduce),
298 ResultType(std::forward<InitialValueType>(initialValue)), options);
299}
300
301template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
302 typename ResultType =
303 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
304QFuture<ResultType> mappedReduced(QThreadPool *pool,
305 Iterator begin,
306 Iterator end,
307 MapFunctor &&map,
308 ReduceFunctor &&reduce,
309 ReduceOptions options = ReduceOptions(UnorderedReduce
310 | SequentialReduce))
311{
312 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>(
313 pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
314 options);
315}
316
317template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
318 typename ResultType = typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
319QFuture<ResultType> mappedReduced(Iterator begin,
320 Iterator end,
321 MapFunctor &&map,
322 ReduceFunctor &&reduce,
323 ReduceOptions options = ReduceOptions(UnorderedReduce
324 | SequentialReduce))
325{
326 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
327 (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
328 std::forward<ReduceFunctor>(reduce), options);
329}
330
331#ifdef Q_CLANG_QDOC
332template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
333 typename InitialValueType>
334#else
335template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
336 typename ResultType =
337 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
338 typename InitialValueType,
339 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
340#endif
341QFuture<ResultType> mappedReduced(QThreadPool *pool,
342 Iterator begin,
343 Iterator end,
344 MapFunctor &&map,
345 ReduceFunctor &&reduce,
346 InitialValueType &&initialValue,
347 ReduceOptions options = ReduceOptions(UnorderedReduce
348 | SequentialReduce))
349{
350 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
351 (pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
352 ResultType(std::forward<InitialValueType>(initialValue)), options);
353}
354
355#ifdef Q_CLANG_QDOC
356template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
357 typename InitialValueType>
358#else
359template<typename Iterator, typename MapFunctor, typename ReduceFunctor,
360 typename ResultType =
361 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
362 typename InitialValueType,
363 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
364#endif
365QFuture<ResultType> mappedReduced(Iterator begin,
366 Iterator end,
367 MapFunctor &&map,
368 ReduceFunctor &&reduce,
369 InitialValueType &&initialValue,
370 ReduceOptions options = ReduceOptions(UnorderedReduce
371 | SequentialReduce))
372{
373 return startMappedReduced<QtPrivate::MapResultType<Iterator, MapFunctor>, ResultType>
374 (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map),
375 std::forward<ReduceFunctor>(reduce),
376 ResultType(std::forward<InitialValueType>(initialValue)), options);
377}
378
379// mapped() for sequences
380template <typename Sequence, typename MapFunctor>
381QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
382 QThreadPool *pool,
383 Sequence &&sequence,
384 MapFunctor &&map)
385{
386 return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>(
387 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map));
388}
389
390template <typename Sequence, typename MapFunctor>
391QFuture<QtPrivate::MapResultType<Sequence, MapFunctor>> mapped(
392 Sequence &&sequence,
393 MapFunctor &&map)
394{
395 return startMapped<QtPrivate::MapResultType<Sequence, MapFunctor>>
396 (QThreadPool::globalInstance(), std::forward<Sequence>(sequence),
397 std::forward<MapFunctor>(map));
398}
399
400// mapped() for iterator ranges.
401template <typename Iterator, typename MapFunctor>
402QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
403 QThreadPool *pool,
404 Iterator begin,
405 Iterator end,
406 MapFunctor &&map)
407{
408 return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>(
409 pool, begin, end, std::forward<MapFunctor>(map));
410}
411
412template <typename Iterator, typename MapFunctor>
413QFuture<QtPrivate::MapResultType<Iterator, MapFunctor>> mapped(
414 Iterator begin,
415 Iterator end,
416 MapFunctor &&map)
417{
418 return startMapped<QtPrivate::MapResultType<Iterator, MapFunctor>>
419 (QThreadPool::globalInstance(), begin, end, std::forward<MapFunctor>(map));
420}
421
422// blockingMap() for sequences
423template <typename Sequence, typename MapFunctor>
424void blockingMap(QThreadPool *pool, Sequence &&sequence, MapFunctor map)
425{
426 QFuture<void> future =
427 startMap(pool, sequence.begin(), sequence.end(), std::forward<MapFunctor>(map));
428 future.waitForFinished();
429}
430
431template <typename Sequence, typename MapFunctor>
432void blockingMap(Sequence &&sequence, MapFunctor &&map)
433{
434 QFuture<void> future = startMap(QThreadPool::globalInstance(), sequence.begin(), sequence.end(),
435 std::forward<MapFunctor>(map));
436 future.waitForFinished();
437}
438
439// blockingMap() for iterator ranges
440template <typename Iterator, typename MapFunctor>
441void blockingMap(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
442{
443 QFuture<void> future = startMap(pool, begin, end, map);
444 future.waitForFinished();
445}
446
447template <typename Iterator, typename MapFunctor>
448void blockingMap(Iterator begin, Iterator end, MapFunctor &&map)
449{
450 QFuture<void> future = startMap(QThreadPool::globalInstance(), begin, end,
451 std::forward<MapFunctor>(map));
452 future.waitForFinished();
453}
454
455// blockingMappedReduced() for sequences
456template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
457ResultType blockingMappedReduced(QThreadPool *pool,
458 Sequence &&sequence,
459 MapFunctor &&map,
460 ReduceFunctor &&reduce,
461 ReduceOptions options = ReduceOptions(UnorderedReduce
462 | SequentialReduce))
463{
464 QFuture<ResultType> future =
465 mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
466 std::forward<MapFunctor>(map),
467 std::forward<ReduceFunctor>(reduce), options);
468 return future.takeResult();
469}
470
471template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
472ResultType blockingMappedReduced(Sequence &&sequence,
473 MapFunctor &&map,
474 ReduceFunctor &&reduce,
475 ReduceOptions options = ReduceOptions(UnorderedReduce
476 | SequentialReduce))
477{
478 QFuture<ResultType> future =
479 mappedReduced<ResultType>(std::forward<Sequence>(sequence),
480 std::forward<MapFunctor>(map),
481 std::forward<ReduceFunctor>(reduce), options);
482 return future.takeResult();
483}
484
485#ifdef Q_CLANG_QDOC
486template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
487 typename InitialValueType>
488#else
489template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
490 typename InitialValueType,
491 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
492#endif
493ResultType blockingMappedReduced(QThreadPool *pool,
494 Sequence &&sequence,
495 MapFunctor &&map,
496 ReduceFunctor &&reduce,
497 InitialValueType &&initialValue,
498 ReduceOptions options = ReduceOptions(UnorderedReduce
499 | SequentialReduce))
500{
501 QFuture<ResultType> future = mappedReduced<ResultType>(
502 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
503 std::forward<ReduceFunctor>(reduce),
504 ResultType(std::forward<InitialValueType>(initialValue)), options);
505 return future.takeResult();
506}
507
508#ifdef Q_CLANG_QDOC
509template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
510 typename InitialValueType>
511#else
512template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor,
513 typename InitialValueType,
514 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
515#endif
516ResultType blockingMappedReduced(Sequence &&sequence,
517 MapFunctor &&map,
518 ReduceFunctor &&reduce,
519 InitialValueType &&initialValue,
520 ReduceOptions options = ReduceOptions(UnorderedReduce
521 | SequentialReduce))
522{
523 QFuture<ResultType> future = mappedReduced<ResultType>(
524 std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
525 std::forward<ReduceFunctor>(reduce),
526 ResultType(std::forward<InitialValueType>(initialValue)), options);
527 return future.takeResult();
528}
529
530template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
531 typename ResultType =
532 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
533ResultType blockingMappedReduced(QThreadPool *pool,
534 Sequence &&sequence,
535 MapFunctor &&map,
536 ReduceFunctor &&reduce,
537 ReduceOptions options = ReduceOptions(UnorderedReduce
538 | SequentialReduce))
539{
540 QFuture<ResultType> future =
541 mappedReduced<ResultType>(pool, std::forward<Sequence>(sequence),
542 std::forward<MapFunctor>(map),
543 std::forward<ReduceFunctor>(reduce), options);
544 return future.takeResult();
545}
546
547template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
548 typename ResultType =
549 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
550ResultType blockingMappedReduced(Sequence &&sequence,
551 MapFunctor &&map,
552 ReduceFunctor &&reduce,
553 ReduceOptions options = ReduceOptions(UnorderedReduce
554 | SequentialReduce))
555{
556 QFuture<ResultType> future =
557 mappedReduced<ResultType>(std::forward<Sequence>(sequence),
558 std::forward<MapFunctor>(map),
559 std::forward<ReduceFunctor>(reduce), options);
560 return future.takeResult();
561}
562
563#ifdef Q_CLANG_QDOC
564template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
565 typename InitialValueType>
566#else
567template <typename MapFunctor, typename ReduceFunctor, typename Sequence,
568 typename ResultType =
569 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
570 typename InitialValueType,
571 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
572#endif
573ResultType blockingMappedReduced(QThreadPool *pool,
574 Sequence &&sequence,
575 MapFunctor &&map,
576 ReduceFunctor &&reduce,
577 InitialValueType &&initialValue,
578 ReduceOptions options = ReduceOptions(UnorderedReduce
579 | SequentialReduce))
580{
581 QFuture<ResultType> future = mappedReduced<ResultType>(
582 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
583 std::forward<ReduceFunctor>(reduce),
584 ResultType(std::forward<InitialValueType>(initialValue)), options);
585 return future.takeResult();
586}
587
588#ifdef Q_CLANG_QDOC
589template <typename MapFunctor, typename ReduceFunctor, typename Sequence, typename ResultType,
590 typename InitialValueType>
591#else
592template<typename MapFunctor, typename ReduceFunctor, typename Sequence,
593 typename ResultType =
594 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
595 typename InitialValueType,
596 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
597#endif
598ResultType blockingMappedReduced(Sequence &&sequence,
599 MapFunctor &&map,
600 ReduceFunctor &&reduce,
601 InitialValueType &&initialValue,
602 ReduceOptions options = ReduceOptions(UnorderedReduce
603 | SequentialReduce))
604{
605 QFuture<ResultType> future = mappedReduced<ResultType>(
606 std::forward<Sequence>(sequence), std::forward<MapFunctor>(map),
607 std::forward<ReduceFunctor>(reduce),
608 ResultType(std::forward<InitialValueType>(initialValue)), options);
609 return future.takeResult();
610}
611
612// blockingMappedReduced() for iterator ranges
613template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
614ResultType blockingMappedReduced(QThreadPool *pool,
615 Iterator begin,
616 Iterator end,
617 MapFunctor &&map,
618 ReduceFunctor &&reduce,
619 ReduceOptions options = ReduceOptions(UnorderedReduce
620 | SequentialReduce))
621{
622 QFuture<ResultType> future =
623 mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
624 std::forward<ReduceFunctor>(reduce), options);
625 return future.takeResult();
626}
627
628template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
629ResultType blockingMappedReduced(Iterator begin,
630 Iterator end,
631 MapFunctor &&map,
632 ReduceFunctor &&reduce,
633 ReduceOptions options = ReduceOptions(UnorderedReduce
634 | SequentialReduce))
635{
636 QFuture<ResultType> future =
637 mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
638 std::forward<ReduceFunctor>(reduce), options);
639 return future.takeResult();
640}
641
642#ifdef Q_CLANG_QDOC
643template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
644 typename InitialValueType>
645#else
646template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
647 typename InitialValueType,
648 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
649#endif
650ResultType blockingMappedReduced(QThreadPool *pool,
651 Iterator begin,
652 Iterator end,
653 MapFunctor &&map,
654 ReduceFunctor &&reduce,
655 InitialValueType &&initialValue,
656 ReduceOptions options = ReduceOptions(UnorderedReduce
657 | SequentialReduce))
658{
659 QFuture<ResultType> future = mappedReduced<ResultType>(
660 pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
661 ResultType(std::forward<InitialValueType>(initialValue)),
662 options);
663 return future.takeResult();
664}
665
666#ifdef Q_CLANG_QDOC
667template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
668 typename InitialValueType>
669#else
670template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor,
671 typename InitialValueType,
672 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
673#endif
674ResultType blockingMappedReduced(Iterator begin,
675 Iterator end,
676 MapFunctor &&map,
677 ReduceFunctor &&reduce,
678 InitialValueType &&initialValue,
679 ReduceOptions options = ReduceOptions(UnorderedReduce
680 | SequentialReduce))
681{
682 QFuture<ResultType> future = mappedReduced<ResultType>(
683 begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
684 ResultType(std::forward<InitialValueType>(initialValue)),
685 options);
686 return future.takeResult();
687}
688
689template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
690 typename ResultType =
691 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
692ResultType blockingMappedReduced(QThreadPool *pool,
693 Iterator begin,
694 Iterator end,
695 MapFunctor &&map,
696 ReduceFunctor &&reduce,
697 ReduceOptions options = ReduceOptions(UnorderedReduce
698 | SequentialReduce))
699{
700 QFuture<ResultType> future =
701 mappedReduced<ResultType>(pool, begin, end, std::forward<MapFunctor>(map),
702 std::forward<ReduceFunctor>(reduce), options);
703 return future.takeResult();
704}
705
706template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
707 typename ResultType =
708 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType>
709ResultType blockingMappedReduced(Iterator begin,
710 Iterator end,
711 MapFunctor &&map,
712 ReduceFunctor &&reduce,
713 ReduceOptions options = ReduceOptions(UnorderedReduce
714 | SequentialReduce))
715{
716 QFuture<ResultType> future =
717 mappedReduced<ResultType>(begin, end, std::forward<MapFunctor>(map),
718 std::forward<ReduceFunctor>(reduce), options);
719 return future.takeResult();
720}
721
722#ifdef Q_CLANG_QDOC
723template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
724 typename InitialValueType>
725#else
726template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
727 typename ResultType =
728 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
729 typename InitialValueType,
730 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
731#endif
732ResultType blockingMappedReduced(QThreadPool *pool,
733 Iterator begin,
734 Iterator end,
735 MapFunctor &&map,
736 ReduceFunctor &&reduce,
737 InitialValueType &&initialValue,
738 ReduceOptions options = ReduceOptions(UnorderedReduce
739 | SequentialReduce))
740{
741 QFuture<ResultType> future = mappedReduced<ResultType>(
742 pool, begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
743 ResultType(std::forward<InitialValueType>(initialValue)), options);
744 return future.takeResult();
745}
746
747#ifdef Q_CLANG_QDOC
748template <typename Iterator, typename MapFunctor, typename ReduceFunctor, typename ResultType,
749 typename InitialValueType>
750#else
751template <typename Iterator, typename MapFunctor, typename ReduceFunctor,
752 typename ResultType =
753 typename QtPrivate::ReduceResultType<std::decay_t<ReduceFunctor>>::ResultType,
754 typename InitialValueType,
755 std::enable_if_t<std::is_convertible_v<InitialValueType, ResultType>, int> = 0>
756#endif
757ResultType blockingMappedReduced(Iterator begin,
758 Iterator end,
759 MapFunctor &&map,
760 ReduceFunctor &&reduce,
761 InitialValueType &&initialValue,
762 ReduceOptions options = ReduceOptions(UnorderedReduce
763 | SequentialReduce))
764{
765 QFuture<ResultType> future = mappedReduced<ResultType>(
766 begin, end, std::forward<MapFunctor>(map), std::forward<ReduceFunctor>(reduce),
767 ResultType(std::forward<InitialValueType>(initialValue)), options);
768 return future.takeResult();
769}
770
771// mapped() for sequences with a different putput sequence type.
772template <typename OutputSequence, typename InputSequence, typename MapFunctor>
773OutputSequence blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
774{
775 return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
776 std::forward<MapFunctor>(map),
777 QtPrivate::PushBackWrapper(), OrderedReduce);
778}
779
780template <typename OutputSequence, typename InputSequence, typename MapFunctor>
781OutputSequence blockingMapped(InputSequence &&sequence, MapFunctor &&map)
782{
783 return blockingMappedReduced<OutputSequence>(
784 QThreadPool::globalInstance(), std::forward<InputSequence>(sequence),
785 std::forward<MapFunctor>(map), QtPrivate::PushBackWrapper(), OrderedReduce);
786}
787
788template <typename MapFunctor, typename InputSequence>
789auto blockingMapped(QThreadPool *pool, InputSequence &&sequence, MapFunctor &&map)
790{
791 using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
792 MapFunctor>::ResultType;
793 return blockingMappedReduced<OutputSequence>(pool, std::forward<InputSequence>(sequence),
794 std::forward<MapFunctor>(map),
795 QtPrivate::PushBackWrapper(), OrderedReduce);
796}
797
798template <typename MapFunctor, typename InputSequence>
799auto blockingMapped(InputSequence &&sequence, MapFunctor &&map)
800{
801 using OutputSequence = typename QtPrivate::MapSequenceResultType<std::decay_t<InputSequence>,
802 MapFunctor>::ResultType;
803 return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(),
804 std::forward<InputSequence>(sequence),
805 std::forward<MapFunctor>(map),
806 QtPrivate::PushBackWrapper(), OrderedReduce);
807}
808
809// mapped() for iterator ranges
810template <typename Sequence, typename Iterator, typename MapFunctor>
811Sequence blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
812{
813 return blockingMappedReduced<Sequence>(pool, begin, end, std::forward<MapFunctor>(map),
814 QtPrivate::PushBackWrapper(), OrderedReduce);
815}
816
817template <typename Sequence, typename Iterator, typename MapFunctor>
818Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
819{
820 return blockingMappedReduced<Sequence>(QThreadPool::globalInstance(), begin, end,
821 std::forward<MapFunctor>(map),
822 QtPrivate::PushBackWrapper(), OrderedReduce);
823}
824
825template <typename Iterator, typename MapFunctor>
826auto blockingMapped(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&map)
827{
828 using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
829 return blockingMappedReduced<OutputSequence>(pool, begin, end, std::forward<MapFunctor>(map),
830 QtPrivate::PushBackWrapper(), OrderedReduce);
831}
832
833template <typename Iterator, typename MapFunctor>
834auto blockingMapped(Iterator begin, Iterator end, MapFunctor &&map)
835{
836 using OutputSequence = QtPrivate::MapResultType<Iterator, MapFunctor>;
837 return blockingMappedReduced<OutputSequence>(QThreadPool::globalInstance(), begin, end,
838 std::forward<MapFunctor>(map),
839 QtPrivate::PushBackWrapper(), OrderedReduce);
840}
841
842} // namespace QtConcurrent
843
844
845QT_END_NAMESPACE
846
847#endif // QT_NO_CONCURRENT
848
849#endif
850