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 test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include <qtconcurrentmap.h>
29#include <qexception.h>
30
31#include <qdebug.h>
32#include <QThread>
33#include <QMutex>
34
35#include <QtTest/QtTest>
36
37#include "functions.h"
38
39class tst_QtConcurrentMap: public QObject
40{
41 Q_OBJECT
42private slots:
43 void map();
44 void blocking_map();
45 void mapped();
46 void blocking_mapped();
47 void mappedReduced();
48 void blocking_mappedReduced();
49 void assignResult();
50 void functionOverloads();
51 void noExceptFunctionOverloads();
52#ifndef QT_NO_EXCEPTIONS
53 void exceptions();
54#endif
55 void incrementalResults();
56 void noDetach();
57 void stlContainers();
58 void qFutureAssignmentLeak();
59 void stressTest();
60 void persistentResultTest();
61public slots:
62 void throttling();
63};
64
65using namespace QtConcurrent;
66
67void multiplyBy2Immutable(int x)
68{
69 x *= 2;
70}
71
72class MultiplyBy2Immutable
73{
74public:
75 void operator()(int x)
76 {
77 x *= 2;
78 }
79};
80
81void multiplyBy2InPlace(int &x)
82{
83 x *= 2;
84}
85
86class MultiplyBy2InPlace
87{
88public:
89 void operator()(int &x)
90 {
91 x *= 2;
92 }
93};
94
95Q_DECLARE_METATYPE(QList<Number>);
96
97void tst_QtConcurrentMap::map()
98{
99 // functors take arguments by reference, modifying the sequence in place
100 {
101 QList<int> list;
102 list << 1 << 2 << 3;
103
104 // functor
105 QtConcurrent::map(sequence&: list, map: MultiplyBy2InPlace()).waitForFinished();
106 QCOMPARE(list, QList<int>() << 2 << 4 << 6);
107 QtConcurrent::map(begin: list.begin(), end: list.end(), map: MultiplyBy2InPlace()).waitForFinished();
108 QCOMPARE(list, QList<int>() << 4 << 8 << 12);
109
110 // function
111 QtConcurrent::map(sequence&: list, map: multiplyBy2InPlace).waitForFinished();
112 QCOMPARE(list, QList<int>() << 8 << 16 << 24);
113 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace).waitForFinished();
114 QCOMPARE(list, QList<int>() << 16 << 32 << 48);
115
116 // bound function
117 QtConcurrent::map(sequence&: list, map: multiplyBy2InPlace).waitForFinished();
118 QCOMPARE(list, QList<int>() << 32 << 64 << 96);
119 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace).waitForFinished();
120 QCOMPARE(list, QList<int>() << 64 << 128 << 192);
121
122 // member function
123 QList<Number> numberList;
124 numberList << 1 << 2 << 3;
125 QtConcurrent::map(sequence&: numberList, map: &Number::multiplyBy2).waitForFinished();
126 QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6);
127 QtConcurrent::map(begin: numberList.begin(), end: numberList.end(), map: &Number::multiplyBy2).waitForFinished();
128 QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12);
129
130 // lambda
131 QtConcurrent::map(sequence&: list, map: [](int &x){x *= 2;}).waitForFinished();
132 QCOMPARE(list, QList<int>() << 128 << 256 << 384);
133 QtConcurrent::map(begin: list.begin(), end: list.end(), map: [](int &x){x *= 2;}).waitForFinished();
134 QCOMPARE(list, QList<int>() << 256 << 512 << 768);
135 }
136
137 // functors don't take arguments by reference, making these no-ops
138 {
139 QList<int> list;
140 list << 1 << 2 << 3;
141
142 // functor
143 QtConcurrent::map(sequence&: list, map: MultiplyBy2Immutable()).waitForFinished();
144 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
145 QtConcurrent::map(begin: list.begin(), end: list.end(), map: MultiplyBy2Immutable()).waitForFinished();
146 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
147
148 // function
149 QtConcurrent::map(sequence&: list, map: multiplyBy2Immutable).waitForFinished();
150 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
151 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2Immutable).waitForFinished();
152 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
153
154 // bound function
155 QtConcurrent::map(sequence&: list, map: multiplyBy2Immutable).waitForFinished();
156 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
157 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2Immutable).waitForFinished();
158 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
159
160 // lambda
161 QtConcurrent::map(sequence&: list, map: [](int x){x *= 2;}).waitForFinished();
162 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
163 QtConcurrent::map(begin: list.begin(), end: list.end(), map: [](int x){x *= 2;}).waitForFinished();
164 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
165 }
166
167#if QT_DEPRECATED_SINCE(5, 15)
168QT_WARNING_PUSH
169QT_WARNING_DISABLE_DEPRECATED
170 // Linked lists and forward iterators
171 {
172 QLinkedList<int> list;
173 list << 1 << 2 << 3;
174
175 // functor
176 QtConcurrent::map(sequence&: list, map: MultiplyBy2InPlace()).waitForFinished();
177 QCOMPARE(list, QLinkedList<int>() << 2 << 4 << 6);
178 QtConcurrent::map(begin: list.begin(), end: list.end(), map: MultiplyBy2InPlace()).waitForFinished();
179 QCOMPARE(list, QLinkedList<int>() << 4 << 8 << 12);
180
181 // function
182 QtConcurrent::map(sequence&: list, map: multiplyBy2InPlace).waitForFinished();
183 QCOMPARE(list, QLinkedList<int>() << 8 << 16 << 24);
184 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace).waitForFinished();
185 QCOMPARE(list, QLinkedList<int>() << 16 << 32 << 48);
186
187 // bound function
188 QtConcurrent::map(sequence&: list, map: multiplyBy2InPlace).waitForFinished();
189 QCOMPARE(list, QLinkedList<int>() << 32 << 64 << 96);
190 QtConcurrent::map(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace).waitForFinished();
191 QCOMPARE(list, QLinkedList<int>() << 64 << 128 << 192);
192
193 // member function
194 QLinkedList<Number> numberList;
195 numberList << 1 << 2 << 3;
196 QtConcurrent::map(sequence&: numberList, map: &Number::multiplyBy2).waitForFinished();
197 QCOMPARE(numberList, QLinkedList<Number>() << 2 << 4 << 6);
198 QtConcurrent::map(begin: numberList.begin(), end: numberList.end(), map: &Number::multiplyBy2).waitForFinished();
199 QCOMPARE(numberList, QLinkedList<Number>() << 4 << 8 << 12);
200 }
201QT_WARNING_POP
202#endif
203
204#if 0
205 // not allowed: map() with immutable sequences makes no sense
206 {
207 const QList<int> list = QList<int>() << 1 << 2 << 3;
208
209 QtConcurrent::map(list, MultiplyBy2Immutable());
210 QtConcurrent::map(list, multiplyBy2Immutable);
211 QtConcurrent::map(list, multiplyBy2Immutable);
212 }
213#endif
214
215#if 0
216 // not allowed: in place modification of a temp copy (since temp copy goes out of scope)
217 {
218 QList<int> list;
219 list << 1 << 2 << 3;
220
221 QtConcurrent::map(QList<int>(list), MultiplyBy2InPlace());
222 QtConcurrent::map(QList<int>(list), multiplyBy2);
223 QtConcurrent::map(QList<int>(list), multiplyBy2InPlace);
224
225 QList<Number> numberList;
226 numberList << 1 << 2 << 3;
227 QtConcurrent::map(QList<Number>(numberList), &Number::multiplyBy2);
228 }
229#endif
230
231#if 0
232 // not allowed: map() on a const list, where functors try to modify the items in the list
233 {
234 const QList<int> list = QList<int>() << 1 << 2 << 3;;
235
236 QtConcurrent::map(list, MultiplyBy2InPlace());
237 QtConcurrent::map(list, multiplyBy2InPlace);
238 QtConcurrent::map(list, multiplyBy2InPlace);
239
240 const QList<Number> numberList = QList<Number>() << 1 << 2 << 3;
241 QtConcurrent::map(numberList, &Number::multiplyBy2);
242 }
243#endif
244}
245
246void tst_QtConcurrentMap::blocking_map()
247{
248 // functors take arguments by reference, modifying the sequence in place
249 {
250 QList<int> list;
251 list << 1 << 2 << 3;
252
253 // functor
254 QtConcurrent::blockingMap(sequence&: list, map: MultiplyBy2InPlace());
255 QCOMPARE(list, QList<int>() << 2 << 4 << 6);
256 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: MultiplyBy2InPlace());
257 QCOMPARE(list, QList<int>() << 4 << 8 << 12);
258
259 // function
260 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2InPlace);
261 QCOMPARE(list, QList<int>() << 8 << 16 << 24);
262 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace);
263 QCOMPARE(list, QList<int>() << 16 << 32 << 48);
264
265 // bound function
266 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2InPlace);
267 QCOMPARE(list, QList<int>() << 32 << 64 << 96);
268 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace);
269 QCOMPARE(list, QList<int>() << 64 << 128 << 192);
270
271 // member function
272 QList<Number> numberList;
273 numberList << 1 << 2 << 3;
274 QtConcurrent::blockingMap(sequence&: numberList, map: &Number::multiplyBy2);
275 QCOMPARE(numberList, QList<Number>() << 2 << 4 << 6);
276 QtConcurrent::blockingMap(begin: numberList.begin(), end: numberList.end(), map: &Number::multiplyBy2);
277 QCOMPARE(numberList, QList<Number>() << 4 << 8 << 12);
278 }
279
280 // functors don't take arguments by reference, making these no-ops
281 {
282 QList<int> list;
283 list << 1 << 2 << 3;
284
285 // functor
286 QtConcurrent::blockingMap(sequence&: list, map: MultiplyBy2Immutable());
287 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
288 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: MultiplyBy2Immutable());
289 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
290
291 // function
292 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2Immutable);
293 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
294 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2Immutable);
295 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
296
297 // bound function
298 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2Immutable);
299 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
300 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2Immutable);
301 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
302 }
303
304#if QT_DEPRECATED_SINCE(5, 15)
305QT_WARNING_PUSH
306QT_WARNING_DISABLE_DEPRECATED
307 // Linked lists and forward iterators
308 {
309 QLinkedList<int> list;
310 list << 1 << 2 << 3;
311
312 // functor
313 QtConcurrent::blockingMap(sequence&: list, map: MultiplyBy2InPlace());
314 QCOMPARE(list, QLinkedList<int>() << 2 << 4 << 6);
315 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: MultiplyBy2InPlace());
316 QCOMPARE(list, QLinkedList<int>() << 4 << 8 << 12);
317
318 // function
319 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2InPlace);
320 QCOMPARE(list, QLinkedList<int>() << 8 << 16 << 24);
321 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace);
322 QCOMPARE(list, QLinkedList<int>() << 16 << 32 << 48);
323
324 // bound function
325 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2InPlace);
326 QCOMPARE(list, QLinkedList<int>() << 32 << 64 << 96);
327 QtConcurrent::blockingMap(begin: list.begin(), end: list.end(), map: multiplyBy2InPlace);
328 QCOMPARE(list, QLinkedList<int>() << 64 << 128 << 192);
329
330 // member function
331 QLinkedList<Number> numberList;
332 numberList << 1 << 2 << 3;
333 QtConcurrent::blockingMap(sequence&: numberList, map: &Number::multiplyBy2);
334 QCOMPARE(numberList, QLinkedList<Number>() << 2 << 4 << 6);
335 QtConcurrent::blockingMap(begin: numberList.begin(), end: numberList.end(), map: &Number::multiplyBy2);
336 QCOMPARE(numberList, QLinkedList<Number>() << 4 << 8 << 12);
337 }
338QT_WARNING_POP
339#endif
340
341#if 0
342 // not allowed: map() with immutable sequences makes no sense
343 {
344 const QList<int> list = QList<int>() << 1 << 2 << 3;
345
346 QtConcurrent::blockingMap(list, MultiplyBy2Immutable());
347 QtConcurrent::blockkng::map(list, multiplyBy2Immutable);
348 QtConcurrent::blockingMap(list, multiplyBy2Immutable);
349 }
350#endif
351
352#if 0
353 // not allowed: in place modification of a temp copy (since temp copy goes out of scope)
354 {
355 QList<int> list;
356 list << 1 << 2 << 3;
357
358 QtConcurrent::blockingMap(QList<int>(list), MultiplyBy2InPlace());
359 QtConcurrent::blockingMap(QList<int>(list), multiplyBy2);
360 QtConcurrent::blockingMap(QList<int>(list), multiplyBy2InPlace);
361
362 QList<Number> numberList;
363 numberList << 1 << 2 << 3;
364 QtConcurrent::blockingMap(QList<Number>(numberList), &Number::multiplyBy2);
365 }
366#endif
367
368#if 0
369 // not allowed: map() on a const list, where functors try to modify the items in the list
370 {
371 const QList<int> list = QList<int>() << 1 << 2 << 3;;
372
373 QtConcurrent::blockingMap(list, MultiplyBy2InPlace());
374 QtConcurrent::blockingMap(list, multiplyBy2InPlace);
375 QtConcurrent::blockingMap(list, multiplyBy2InPlace);
376
377 const QList<Number> numberList = QList<Number>() << 1 << 2 << 3;
378 QtConcurrent::blockingMap(numberList, &Number::multiplyBy2);
379 }
380#endif
381}
382
383int multiplyBy2(int x)
384{
385 int y = x * 2;
386 return y;
387}
388
389class MultiplyBy2
390{
391public:
392 typedef int result_type;
393
394 int operator()(int x) const
395 {
396 int y = x * 2;
397 return y;
398 }
399};
400
401double intToDouble(int x)
402{
403 return double(x);
404}
405
406class IntToDouble
407{
408public:
409 typedef double result_type;
410
411 double operator()(int x) const
412 {
413 return double(x);
414 }
415};
416
417int stringToInt(const QString &string)
418{
419 return string.toInt();
420}
421
422class StringToInt
423{
424public:
425 typedef int result_type;
426
427 int operator()(const QString &string) const
428 {
429 return string.toInt();
430 }
431};
432
433void tst_QtConcurrentMap::mapped()
434{
435 QList<int> list;
436 list << 1 << 2 << 3;
437 QList<Number> numberList;
438 numberList << 1 << 2 << 3;
439
440 // functor
441 {
442 QList<int> list2 = QtConcurrent::mapped(sequence: list, map: MultiplyBy2()).results();
443 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
444 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
445
446 QList<int> list3 = QtConcurrent::mapped(begin: list.constBegin(),
447 end: list.constEnd(),
448 map: MultiplyBy2()).results();
449 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
450 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
451
452 QList<int> list4 = QtConcurrent::mapped(sequence: QList<int>(list), map: MultiplyBy2()).results();
453 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
454 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
455 }
456
457 // function
458 {
459 QList<int> list2 = QtConcurrent::mapped(sequence: list, map: multiplyBy2).results();
460 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
461 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
462
463 QList<int> list3 = QtConcurrent::mapped(begin: list.constBegin(),
464 end: list.constEnd(),
465 map: multiplyBy2).results();
466 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
467 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
468
469 QList<int> list4 = QtConcurrent::mapped(sequence: QList<int>(list), map: multiplyBy2).results();
470 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
471 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
472 }
473
474 // bound function
475 {
476 QList<int> list2 = QtConcurrent::mapped(sequence: list, map: multiplyBy2).results();
477 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
478 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
479
480 QList<int> list3 = QtConcurrent::mapped(begin: list.constBegin(),
481 end: list.constEnd(),
482 map: multiplyBy2).results();
483 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
484 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
485
486 QList<int> list4 = QtConcurrent::mapped(sequence: QList<int>(list), map: multiplyBy2).results();
487 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
488 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
489 }
490
491 // const member function
492 {
493 QList<Number> numberList2 = QtConcurrent::mapped(sequence: numberList, map: &Number::multipliedBy2)
494 .results();
495 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
496 QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6);
497
498 QList<Number> numberList3 = QtConcurrent::mapped(begin: numberList.constBegin(),
499 end: numberList.constEnd(),
500 map: &Number::multipliedBy2)
501 .results();
502 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
503 QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6);
504
505 QList<Number> numberList4 = QtConcurrent::mapped(sequence: QList<Number>(numberList),
506 map: &Number::multipliedBy2)
507 .results();
508 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
509 QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
510 }
511
512 // change the value_type, same container
513
514 // functor
515 {
516 QList<double> list2 = QtConcurrent::mapped(sequence: list, map: IntToDouble()).results();
517 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
518 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
519
520 QList<double> list3 = QtConcurrent::mapped(begin: list.constBegin(),
521 end: list.constEnd(),
522 map: IntToDouble())
523 .results();
524 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
525 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
526
527 QList<double> list4 = QtConcurrent::mapped(sequence: QList<int>(list),
528 map: IntToDouble())
529 .results();
530 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
531 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
532 }
533
534 // function
535 {
536 QList<double> list2 = QtConcurrent::mapped(sequence: list, map: intToDouble).results();
537 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
538 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
539
540 QList<double> list3 = QtConcurrent::mapped(begin: list.constBegin(),
541 end: list.constEnd(),
542 map: intToDouble)
543 .results();
544 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
545 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
546
547 QList<double> list4 = QtConcurrent::mapped(sequence: QList<int>(list), map: intToDouble).results();
548 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
549 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
550 }
551
552 // bound function
553 {
554 QList<double> list2 = QtConcurrent::mapped(sequence: list, map: intToDouble).results();
555 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
556 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
557
558 QList<double> list3 = QtConcurrent::mapped(begin: list.constBegin(),
559 end: list.constEnd(),
560 map: intToDouble)
561 .results();
562 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
563 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
564
565
566 QList<double> list4 = QtConcurrent::mapped(sequence: QList<int>(list),
567 map: intToDouble)
568 .results();
569 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
570 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
571 }
572
573 // const member function
574 {
575 QList<QString> list2 = QtConcurrent::mapped(sequence: numberList, map: &Number::toString).results();
576 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
577 QCOMPARE(list2, QList<QString>() << "1" << "2" << "3");
578
579 QList<QString> list3 = QtConcurrent::mapped(begin: numberList.constBegin(),
580 end: numberList.constEnd(),
581 map: &Number::toString)
582 .results();
583 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
584 QCOMPARE(list3, QList<QString>() << "1" << "2" << "3");
585
586 QList<QString> list4 = QtConcurrent::mapped(sequence: QList<Number>(numberList), map: &Number::toString)
587 .results();
588 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
589 QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
590 }
591
592 // change the value_type
593 {
594 QList<QString> strings = QStringList() << "1" << "2" << "3";
595 QList<int> list = QtConcurrent::mapped(sequence: strings, map: StringToInt()).results();
596 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
597
598 QList<int> list2 = QtConcurrent::mapped(begin: strings.constBegin(),
599 end: strings.constEnd(),
600 map: StringToInt())
601 .results();
602 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
603 }
604 {
605 QList<QString> strings = QStringList() << "1" << "2" << "3";
606 QList<int> list = QtConcurrent::mapped(sequence: strings, map: stringToInt).results();
607 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
608
609 QList<int> list2 = QtConcurrent::mapped(begin: strings.constBegin(),
610 end: strings.constEnd(),
611 map: stringToInt).results();
612 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
613 }
614
615 {
616 QList<int> numberList2 = QtConcurrent::mapped(sequence: numberList, map: &Number::toInt).results();
617 QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3);
618
619 QList<int> numberList3 = QtConcurrent::mapped(begin: numberList.constBegin(),
620 end: numberList.constEnd(),
621 map: &Number::toInt)
622 .results();
623 QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
624 }
625
626 // change the value_type from QStringList
627 {
628 QStringList strings = QStringList() << "1" << "2" << "3";
629 QList<int> list = QtConcurrent::mapped(sequence: strings, map: StringToInt()).results();
630 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
631
632 QList<int> list2 = QtConcurrent::mapped(begin: strings.constBegin(),
633 end: strings.constEnd(),
634 map: StringToInt())
635 .results();
636 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
637 }
638 {
639 QStringList strings = QStringList() << "1" << "2" << "3";
640 QList<int> list = QtConcurrent::mapped(sequence: strings, map: stringToInt).results();
641 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
642
643 QList<int> list2 = QtConcurrent::mapped(begin: strings.constBegin(),
644 end: strings.constEnd(),
645 map: stringToInt)
646 .results();
647 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
648 }
649
650#if QT_DEPRECATED_SINCE(5, 15)
651QT_WARNING_PUSH
652QT_WARNING_DISABLE_DEPRECATED
653
654 QLinkedList<int> linkedList;
655 linkedList << 1 << 2 << 3;
656 QLinkedList<Number> numberLinkedList;
657 numberLinkedList << 1 << 2 << 3;
658
659 // functor
660 {
661 QList<int> list2 = QtConcurrent::mapped(sequence: linkedList, map: MultiplyBy2()).results();
662 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
663 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
664
665 QList<int> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
666 end: linkedList.constEnd(),
667 map: MultiplyBy2()).results();
668 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
669 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
670
671 QList<int> list4 =
672 QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList), map: MultiplyBy2()).results();
673 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
674 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
675 }
676
677 // function
678 {
679 QList<int> list2 = QtConcurrent::mapped(sequence: linkedList, map: multiplyBy2).results();
680 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
681 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
682
683 QList<int> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
684 end: linkedList.constEnd(),
685 map: multiplyBy2).results();
686 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
687 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
688
689 QList<int> list4 =
690 QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList), map: multiplyBy2).results();
691 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
692 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
693 }
694
695 // bound function
696 {
697 QList<int> list2 = QtConcurrent::mapped(sequence: linkedList, map: multiplyBy2).results();
698 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
699 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
700
701 QList<int> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
702 end: linkedList.constEnd(),
703 map: multiplyBy2)
704 .results();
705 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
706 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
707
708 QList<int> list4 = QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList), map: multiplyBy2)
709 .results();
710 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
711 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
712 }
713
714 // const member function
715 {
716 QList<Number> numberList2 = QtConcurrent::mapped(sequence: numberLinkedList, map: &Number::multipliedBy2)
717 .results();
718 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
719 QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6);
720
721 QList<Number> numberList3 = QtConcurrent::mapped(begin: numberLinkedList.constBegin(),
722 end: numberLinkedList.constEnd(),
723 map: &Number::multipliedBy2)
724 .results();
725 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
726 QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6);
727
728 QList<Number> numberList4 = QtConcurrent::mapped(sequence: QLinkedList<Number>(numberLinkedList),
729 map: &Number::multipliedBy2)
730 .results();
731 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
732 QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
733 }
734
735 // change the value_type, same container
736
737 // functor
738 {
739 QList<double> list2 = QtConcurrent::mapped(sequence: linkedList, map: IntToDouble()).results();
740 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
741 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
742
743 QList<double> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
744 end: linkedList.constEnd(),
745 map: IntToDouble())
746 .results();
747 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
748 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
749
750 QList<double> list4 = QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList),
751 map: IntToDouble())
752 .results();
753 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
754 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
755 }
756
757 // function
758 {
759 QList<double> list2 = QtConcurrent::mapped(sequence: linkedList, map: intToDouble).results();
760 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
761 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
762
763 QList<double> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
764 end: linkedList.constEnd(),
765 map: intToDouble)
766 .results();
767 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
768 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
769
770 QList<double> list4 = QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList), map: intToDouble)
771 .results();
772 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
773 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
774 }
775
776 // bound function
777 {
778 QList<double> list2 = QtConcurrent::mapped(sequence: linkedList, map: intToDouble).results();
779 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
780 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
781
782 QList<double> list3 = QtConcurrent::mapped(begin: linkedList.constBegin(),
783 end: linkedList.constEnd(),
784 map: intToDouble)
785 .results();
786 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
787 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
788
789
790 QList<double> list4 = QtConcurrent::mapped(sequence: QLinkedList<int>(linkedList),
791 map: intToDouble)
792 .results();
793 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
794 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
795 }
796
797 // const member function
798 {
799 QList<QString> list2 = QtConcurrent::mapped(sequence: numberLinkedList, map: &Number::toString).results();
800 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
801 QCOMPARE(list2, QList<QString>() << "1" << "2" << "3");
802
803 QList<QString> list3 = QtConcurrent::mapped(begin: numberLinkedList.constBegin(),
804 end: numberLinkedList.constEnd(),
805 map: &Number::toString)
806 .results();
807 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
808 QCOMPARE(list3, QList<QString>() << "1" << "2" << "3");
809
810 QList<QString> list4 = QtConcurrent::mapped(sequence: QLinkedList<Number>(numberLinkedList),
811 map: &Number::toString)
812 .results();
813 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
814 QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
815 }
816QT_WARNING_POP
817#endif
818}
819
820void tst_QtConcurrentMap::blocking_mapped()
821{
822 QList<int> list;
823 list << 1 << 2 << 3;
824 QList<Number> numberList;
825 numberList << 1 << 2 << 3;
826
827 // functor
828 {
829 QList<int> list2 = QtConcurrent::blockingMapped(sequence: list, map: MultiplyBy2());
830 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
831 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
832
833 QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(begin: list.constBegin(),
834 end: list.constEnd(),
835 map: MultiplyBy2());
836 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
837 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
838
839 QList<int> list4 = QtConcurrent::blockingMapped(sequence: QList<int>(list), map: MultiplyBy2());
840 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
841 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
842 }
843
844 // function
845 {
846 QList<int> list2 = QtConcurrent::blockingMapped(sequence: list, map: multiplyBy2);
847 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
848 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
849
850 QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(begin: list.constBegin(),
851 end: list.constEnd(),
852 map: multiplyBy2);
853 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
854 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
855
856 QList<int> list4 = QtConcurrent::blockingMapped(sequence: QList<int>(list), map: multiplyBy2);
857 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
858 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
859 }
860
861 // bound function
862 {
863 QList<int> list2 = QtConcurrent::blockingMapped(sequence: list, map: multiplyBy2);
864 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
865 QCOMPARE(list2, QList<int>() << 2 << 4 << 6);
866
867 QList<int> list3 = QtConcurrent::blockingMapped<QList<int> >(begin: list.constBegin(),
868 end: list.constEnd(),
869 map: multiplyBy2);
870 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
871 QCOMPARE(list3, QList<int>() << 2 << 4 << 6);
872
873 QList<int> list4 = QtConcurrent::blockingMapped(sequence: QList<int>(list), map: multiplyBy2);
874 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
875 QCOMPARE(list4, QList<int>() << 2 << 4 << 6);
876 }
877
878 // const member function
879 {
880 QList<Number> numberList2 = QtConcurrent::blockingMapped(sequence: numberList, map: &Number::multipliedBy2);
881 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
882 QCOMPARE(numberList2, QList<Number>() << 2 << 4 << 6);
883
884 QList<Number> numberList3 = QtConcurrent::blockingMapped<QList<Number> >(begin: numberList.constBegin(),
885 end: numberList.constEnd(),
886 map: &Number::multipliedBy2);
887 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
888 QCOMPARE(numberList3, QList<Number>() << 2 << 4 << 6);
889
890 QList<Number> numberList4 = QtConcurrent::blockingMapped(sequence: QList<Number>(numberList),
891 map: &Number::multipliedBy2);
892 QCOMPARE(numberList, QList<Number>() << 1 << 2 << 3);
893 QCOMPARE(numberList4, QList<Number>() << 2 << 4 << 6);
894 }
895
896 // change the value_type, same container
897
898 // functor
899 {
900 QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(sequence: list, map: IntToDouble());
901 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
902 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
903
904 QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(begin: list.constBegin(),
905 end: list.constEnd(),
906 map: IntToDouble());
907 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
908 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
909
910 QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(sequence: QList<int>(list),
911 map: IntToDouble());
912 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
913 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
914 }
915
916 // function
917 {
918 QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(sequence: list, map: intToDouble);
919 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
920 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
921
922 QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(begin: list.constBegin(),
923 end: list.constEnd(),
924 map: intToDouble);
925 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
926 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
927
928 QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(sequence: QList<int>(list), map: intToDouble);
929 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
930 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
931 }
932
933 // bound function
934 {
935 QList<double> list2 = QtConcurrent::blockingMapped<QList<double> >(sequence: list, map: intToDouble);
936 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
937 QCOMPARE(list2, QList<double>() << 1.0 << 2.0 << 3.0);
938
939 QList<double> list3 = QtConcurrent::blockingMapped<QList<double> >(begin: list.constBegin(),
940 end: list.constEnd(),
941 map: intToDouble);
942 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
943 QCOMPARE(list3, QList<double>() << 1.0 << 2.0 << 3.0);
944
945
946 QList<double> list4 = QtConcurrent::blockingMapped<QList<double> >(sequence: QList<int>(list),
947 map: intToDouble);
948 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
949 QCOMPARE(list4, QList<double>() << 1.0 << 2.0 << 3.0);
950 }
951
952 // const member function
953 {
954 QList<QString> list2 =
955 QtConcurrent::blockingMapped<QList<QString> >(sequence: numberList, map: &Number::toString);
956 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
957 QCOMPARE(list2, QList<QString>() << "1" << "2" << "3");
958
959 QList<QString> list3 = QtConcurrent::blockingMapped<QList<QString> >(begin: numberList.constBegin(),
960 end: numberList.constEnd()
961 , map: &Number::toString);
962 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
963 QCOMPARE(list3, QList<QString>() << "1" << "2" << "3");
964
965 QList<QString> list4 =
966 QtConcurrent::blockingMapped<QList<QString> >(sequence: QList<Number>(numberList), map: &Number::toString);
967 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
968 QCOMPARE(list4, QList<QString>() << "1" << "2" << "3");
969 }
970
971 // change the value_type
972 {
973 QList<QString> strings = QStringList() << "1" << "2" << "3";
974 QList<int> list = QtConcurrent::blockingMapped(sequence: strings, map: StringToInt());
975 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
976
977 QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(begin: strings.constBegin(),
978 end: strings.constEnd(),
979 map: StringToInt());
980 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
981 }
982 {
983 QList<QString> strings = QStringList() << "1" << "2" << "3";
984 QList<int> list = QtConcurrent::blockingMapped(sequence: strings, map: stringToInt);
985 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
986
987 QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(begin: strings.constBegin(),
988 end: strings.constEnd(),
989 map: stringToInt);
990 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
991 }
992
993 {
994 QList<int> numberList2 = QtConcurrent::blockingMapped(sequence: numberList, map: &Number::toInt);
995 QCOMPARE(numberList2, QList<int>() << 1 << 2 << 3);
996
997 QList<int> numberList3 = QtConcurrent::blockingMapped<QList<int> >(begin: numberList.constBegin(),
998 end: numberList.constEnd(),
999 map: &Number::toInt);
1000 QCOMPARE(numberList3, QList<int>() << 1 << 2 << 3);
1001 }
1002
1003 // change the value_type from QStringList
1004 {
1005 QStringList strings = QStringList() << "1" << "2" << "3";
1006 QList<int> list = QtConcurrent::blockingMapped(sequence: strings, map: StringToInt());
1007 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1008
1009 QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(begin: strings.constBegin(),
1010 end: strings.constEnd(),
1011 map: StringToInt());
1012 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
1013 }
1014 {
1015 QStringList strings = QStringList() << "1" << "2" << "3";
1016 QList<int> list = QtConcurrent::blockingMapped(sequence: strings, map: stringToInt);
1017 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1018
1019 QList<int> list2 = QtConcurrent::blockingMapped<QList<int> >(begin: strings.constBegin(),
1020 end: strings.constEnd(),
1021 map: stringToInt);
1022 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
1023 }
1024
1025 // functor
1026 {
1027 QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(sequence: list, map: IntToDouble());
1028 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1029 QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0);
1030
1031 QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(begin: list.constBegin(),
1032 end: list.constEnd(),
1033 map: IntToDouble());
1034 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1035 QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0);
1036
1037 QVector<double> list4 = QtConcurrent::blockingMapped<QVector<double> >(sequence: QList<int>(list),
1038 map: IntToDouble());
1039 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1040 QCOMPARE(list4, QVector<double>() << 1.0 << 2.0 << 3.0);
1041
1042 QStringList strings = QStringList() << "1" << "2" << "3";
1043 QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(sequence: strings, map: StringToInt());
1044 QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
1045
1046 QVector<int> list6 = QtConcurrent::blockingMapped<QVector<int> >(begin: strings.constBegin(),
1047 end: strings.constEnd(),
1048 map: StringToInt());
1049 QCOMPARE(list6, QVector<int>() << 1 << 2 << 3);
1050
1051 QVector<int> list7 = QtConcurrent::blockingMapped<QVector<int> >(sequence: QStringList(strings),
1052 map: StringToInt());
1053 QCOMPARE(list7, QVector<int>() << 1 << 2 << 3);
1054 }
1055
1056 // function
1057 {
1058 QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(sequence: list, map: intToDouble);
1059 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1060 QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0);
1061
1062 QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(begin: list.constBegin(),
1063 end: list.constEnd(),
1064 map: intToDouble);
1065 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1066 QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0);
1067
1068 QVector<double> list4 = QtConcurrent::blockingMapped<QVector<double> >(sequence: QList<int>(list),
1069 map: intToDouble);
1070 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1071 QCOMPARE(list4, QVector<double>() << 1.0 << 2.0 << 3.0);
1072
1073 QStringList strings = QStringList() << "1" << "2" << "3";
1074 QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(sequence: strings, map: stringToInt);
1075 QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
1076
1077 QVector<int> list6 = QtConcurrent::blockingMapped<QVector<int> >(begin: strings.constBegin(),
1078 end: strings.constEnd(),
1079 map: stringToInt);
1080 QCOMPARE(list6, QVector<int>() << 1 << 2 << 3);
1081
1082 QVector<int> list7 = QtConcurrent::blockingMapped<QVector<int> >(sequence: QStringList(strings),
1083 map: stringToInt);
1084 QCOMPARE(list7, QVector<int>() << 1 << 2 << 3);
1085 }
1086
1087 // bound function
1088 {
1089 QVector<double> list2 = QtConcurrent::blockingMapped<QVector<double> >(sequence: list, map: intToDouble);
1090 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1091 QCOMPARE(list2, QVector<double>() << 1.0 << 2.0 << 3.0);
1092
1093 QVector<double> list3 = QtConcurrent::blockingMapped<QVector<double> >(sequence: QList<int>(list), map: intToDouble);
1094 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1095 QCOMPARE(list3, QVector<double>() << 1.0 << 2.0 << 3.0);
1096
1097 QStringList strings = QStringList() << "1" << "2" << "3";
1098 QVector<int> list4 = QtConcurrent::blockingMapped<QVector<int> >(sequence: strings, map: stringToInt);
1099 QCOMPARE(list4, QVector<int>() << 1 << 2 << 3);
1100
1101 QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(sequence: QStringList(strings), map: stringToInt);
1102 QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
1103 }
1104
1105 // const member function
1106 {
1107 QVector<QString> list2 = QtConcurrent::blockingMapped<QVector<QString> >(sequence: numberList, map: &Number::toString);
1108 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1109 QCOMPARE(list2, QVector<QString>() << "1" << "2" << "3");
1110
1111 QVector<QString> list3 =
1112 QtConcurrent::blockingMapped<QVector<QString> >(sequence: QList<Number>(numberList), map: &Number::toString);
1113 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1114 QCOMPARE(list3, QVector<QString>() << "1" << "2" << "3");
1115
1116 // not allowed: const member function where all arguments have default values
1117#if 0
1118 QStringList strings = QStringList() << "1" << "2" << "3";
1119 QVector<int> list4 = QtConcurrent::blockingMapped<QVector<int> >(strings, &QString::toInt);
1120 QCOMPARE(list4, QVector<int>() << 1 << 2 << 3);
1121
1122 QVector<int> list5 = QtConcurrent::blockingMapped<QVector<int> >(QStringList(strings), &QString::toInt);
1123 QCOMPARE(list5, QVector<int>() << 1 << 2 << 3);
1124#endif
1125 }
1126
1127#if QT_DEPRECATED_SINCE(5, 15)
1128QT_WARNING_PUSH
1129QT_WARNING_DISABLE_DEPRECATED
1130
1131 QLinkedList<int> linkedList;
1132 linkedList << 1 << 2 << 3;
1133 QLinkedList<Number> numberLinkedList;
1134 numberLinkedList << 1 << 2 << 3;
1135
1136 // functor
1137 {
1138 QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(sequence: linkedList, map: MultiplyBy2());
1139 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1140 QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6);
1141
1142 QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(begin: linkedList.constBegin(),
1143 end: linkedList.constEnd(),
1144 map: MultiplyBy2());
1145 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1146 QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6);
1147
1148 QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(sequence: QLinkedList<int>(linkedList), map: MultiplyBy2());
1149 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1150 QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6);
1151 }
1152
1153 // function
1154 {
1155 QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(sequence: linkedList, map: multiplyBy2);
1156 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1157 QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6);
1158
1159 QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(begin: linkedList.constBegin(),
1160 end: linkedList.constEnd(),
1161 map: multiplyBy2);
1162 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1163 QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6);
1164
1165 QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(sequence: QLinkedList<int>(linkedList), map: multiplyBy2);
1166 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1167 QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6);
1168 }
1169
1170 // bound function
1171 {
1172 QLinkedList<int> linkedList2 = QtConcurrent::blockingMapped(sequence: linkedList, map: multiplyBy2);
1173 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1174 QCOMPARE(linkedList2, QLinkedList<int>() << 2 << 4 << 6);
1175
1176 QLinkedList<int> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<int> >(begin: linkedList.constBegin(),
1177 end: linkedList.constEnd(),
1178 map: multiplyBy2);
1179 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1180 QCOMPARE(linkedList3, QLinkedList<int>() << 2 << 4 << 6);
1181
1182 QLinkedList<int> linkedList4 = QtConcurrent::blockingMapped(sequence: QLinkedList<int>(linkedList), map: multiplyBy2);
1183 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1184 QCOMPARE(linkedList4, QLinkedList<int>() << 2 << 4 << 6);
1185 }
1186
1187 // const member function
1188 {
1189 QLinkedList<Number> numberLinkedList2 = QtConcurrent::blockingMapped(sequence: numberLinkedList, map: &Number::multipliedBy2);
1190 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
1191 QCOMPARE(numberLinkedList2, QLinkedList<Number>() << 2 << 4 << 6);
1192
1193 QLinkedList<Number> numberLinkedList3 = QtConcurrent::blockingMapped<QLinkedList<Number> >(begin: numberLinkedList.constBegin(),
1194 end: numberLinkedList.constEnd(),
1195 map: &Number::multipliedBy2);
1196 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
1197 QCOMPARE(numberLinkedList3, QLinkedList<Number>() << 2 << 4 << 6);
1198
1199 QLinkedList<Number> numberLinkedList4 = QtConcurrent::blockingMapped(sequence: QLinkedList<Number>(numberLinkedList),
1200 map: &Number::multipliedBy2);
1201 QCOMPARE(numberLinkedList, QLinkedList<Number>() << 1 << 2 << 3);
1202 QCOMPARE(numberLinkedList4, QLinkedList<Number>() << 2 << 4 << 6);
1203 }
1204
1205 // change the value_type, same container
1206
1207 // functor
1208 {
1209 QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: linkedList, map: IntToDouble());
1210 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1211 QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1212
1213 QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(begin: linkedList.constBegin(),
1214 end: linkedList.constEnd(),
1215 map: IntToDouble());
1216 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1217 QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1218
1219 QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: QLinkedList<int>(linkedList),
1220 map: IntToDouble());
1221 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1222 QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1223 }
1224
1225 // function
1226 {
1227 QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: linkedList, map: intToDouble);
1228 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1229 QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1230
1231 QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(begin: linkedList.constBegin(),
1232 end: linkedList.constEnd(),
1233 map: intToDouble);
1234 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1235 QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1236
1237 QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: QLinkedList<int>(linkedList), map: intToDouble);
1238 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1239 QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1240 }
1241
1242 // bound function
1243 {
1244 QLinkedList<double> linkedList2 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: linkedList, map: intToDouble);
1245 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1246 QCOMPARE(linkedList2, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1247
1248 QLinkedList<double> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<double> >(begin: linkedList.constBegin(),
1249 end: linkedList.constEnd(),
1250 map: intToDouble);
1251 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1252 QCOMPARE(linkedList3, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1253
1254
1255 QLinkedList<double> linkedList4 = QtConcurrent::blockingMapped<QLinkedList<double> >(sequence: QLinkedList<int>(linkedList),
1256 map: intToDouble);
1257 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1258 QCOMPARE(linkedList4, QLinkedList<double>() << 1.0 << 2.0 << 3.0);
1259 }
1260
1261 // const member function
1262 {
1263 QLinkedList<QString> linkedList2 =
1264 QtConcurrent::blockingMapped<QLinkedList<QString> >(sequence: numberLinkedList, map: &Number::toString);
1265 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1266 QCOMPARE(linkedList2, QLinkedList<QString>() << "1" << "2" << "3");
1267
1268 QLinkedList<QString> linkedList3 = QtConcurrent::blockingMapped<QLinkedList<QString> >(begin: numberLinkedList.constBegin(),
1269 end: numberLinkedList.constEnd()
1270 , map: &Number::toString);
1271 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1272 QCOMPARE(linkedList3, QLinkedList<QString>() << "1" << "2" << "3");
1273
1274 QLinkedList<QString> linkedList4 =
1275 QtConcurrent::blockingMapped<QLinkedList<QString> >(sequence: QLinkedList<Number>(numberLinkedList), map: &Number::toString);
1276 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1277 QCOMPARE(linkedList4, QLinkedList<QString>() << "1" << "2" << "3");
1278 }
1279
1280QT_WARNING_POP
1281#endif
1282}
1283
1284int intSquare(int x)
1285{
1286 return x * x;
1287}
1288
1289class IntSquare
1290{
1291public:
1292 typedef int result_type;
1293
1294 int operator()(int x)
1295 {
1296 return x * x;
1297 }
1298};
1299
1300void tst_QtConcurrentMap::mappedReduced()
1301{
1302 QList<int> list;
1303 list << 1 << 2 << 3;
1304 QList<Number> numberList;
1305 numberList << 1 << 2 << 3;
1306
1307 // test Q_DECLARE_OPERATORS_FOR_FLAGS
1308 QtConcurrent::ReduceOptions opt = (QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce);
1309 QVERIFY(opt);
1310
1311 // functor-functor
1312 {
1313 int sum = QtConcurrent::mappedReduced<int>(sequence: list, map: IntSquare(), reduce: IntSumReduce());
1314 QCOMPARE(sum, 14);
1315 int sum2 = QtConcurrent::mappedReduced<int>(begin: list.constBegin(),
1316 end: list.constEnd(),
1317 map: IntSquare(),
1318 reduce: IntSumReduce());
1319 QCOMPARE(sum2, 14);
1320
1321 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QList<int>(list), map: IntSquare(), reduce: IntSumReduce());
1322 QCOMPARE(sum3, 14);
1323
1324 int sum4 = QtConcurrent::mappedReduced<int>(sequence: list, map: intSquare, reduce: intSumReduce);
1325 QCOMPARE(sum4, 14);
1326 int sum5 = QtConcurrent::mappedReduced<int>(begin: list.constBegin(),
1327 end: list.constEnd(),
1328 map: intSquare,
1329 reduce: intSumReduce);
1330 QCOMPARE(sum5, 14);
1331
1332 int sum6 = QtConcurrent::mappedReduced<int>(sequence: QList<int>(list),
1333 map: intSquare,
1334 reduce: intSumReduce);
1335 QCOMPARE(sum6, 14);
1336 }
1337
1338 // function-functor
1339 {
1340 int sum = QtConcurrent::mappedReduced<int>(sequence: list, map: intSquare, reduce: IntSumReduce());
1341 QCOMPARE(sum, 14);
1342 int sum2 = QtConcurrent::mappedReduced<int>(begin: list.constBegin(),
1343 end: list.constEnd(),
1344 map: intSquare,
1345 reduce: IntSumReduce());
1346 QCOMPARE(sum2, 14);
1347
1348 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QList<int>(list), map: intSquare, reduce: IntSumReduce());
1349 QCOMPARE(sum3, 14);
1350 }
1351
1352 // functor-function
1353 {
1354 int sum = QtConcurrent::mappedReduced(sequence: list, map: IntSquare(), reduce: intSumReduce);
1355 QCOMPARE(sum, 14);
1356 int sum2 = QtConcurrent::mappedReduced(begin: list.constBegin(),
1357 end: list.constEnd(),
1358 map: IntSquare(),
1359 reduce: intSumReduce);
1360 QCOMPARE(sum2, 14);
1361
1362 int sum3 = QtConcurrent::mappedReduced(sequence: QList<int>(list), map: IntSquare(), reduce: intSumReduce);
1363 QCOMPARE(sum3, 14);
1364 }
1365
1366 // function-function
1367 {
1368 int sum = QtConcurrent::mappedReduced(sequence: list, map: intSquare, reduce: intSumReduce);
1369 QCOMPARE(sum, 14);
1370 int sum2 = QtConcurrent::mappedReduced(begin: list.constBegin(),
1371 end: list.constEnd(),
1372 map: intSquare,
1373 reduce: intSumReduce);
1374 QCOMPARE(sum2, 14);
1375
1376 int sum3 = QtConcurrent::mappedReduced(sequence: QList<int>(list), map: intSquare, reduce: intSumReduce);
1377 QCOMPARE(sum3, 14);
1378 }
1379
1380 // functor-member
1381 {
1382 QList<int> list2 = QtConcurrent::mappedReduced(sequence: list,
1383 map: IntSquare(),
1384 reduce: &QList<int>::push_back,
1385 options: OrderedReduce);
1386 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1387 QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
1388
1389 QList<int> list3 = QtConcurrent::mappedReduced(begin: list.constBegin(),
1390 end: list.constEnd(),
1391 map: IntSquare(),
1392 reduce: &QList<int>::push_back,
1393 options: OrderedReduce);
1394 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1395 QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
1396
1397 QList<int> list4 = QtConcurrent::mappedReduced(sequence: QList<int>(list),
1398 map: IntSquare(),
1399 reduce: &QList<int>::push_back,
1400 options: OrderedReduce);
1401 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1402 QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
1403 }
1404
1405 // member-functor
1406 {
1407 int sum = QtConcurrent::mappedReduced<int>(sequence: numberList, map: &Number::toInt, reduce: IntSumReduce());
1408 QCOMPARE(sum, 6);
1409 int sum2 = QtConcurrent::mappedReduced<int>(begin: numberList.constBegin(),
1410 end: numberList.constEnd(),
1411 map: &Number::toInt,
1412 reduce: IntSumReduce());
1413 QCOMPARE(sum2, 6);
1414
1415 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QList<Number>(numberList),
1416 map: &Number::toInt,
1417 reduce: IntSumReduce());
1418 QCOMPARE(sum3, 6);
1419 }
1420
1421 // member-member
1422 {
1423 QList<int> list2 = QtConcurrent::mappedReduced(sequence: numberList,
1424 map: &Number::toInt,
1425 reduce: &QList<int>::push_back,
1426 options: OrderedReduce);
1427 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
1428
1429 QList<int> list3 = QtConcurrent::mappedReduced(begin: numberList.constBegin(),
1430 end: numberList.constEnd(),
1431 map: &Number::toInt,
1432 reduce: &QList<int>::push_back,
1433 options: OrderedReduce);
1434 QCOMPARE(list3, QList<int>() << 1 << 2 << 3);
1435
1436 QList<int> list4 = QtConcurrent::mappedReduced(sequence: QList<Number>(numberList),
1437 map: &Number::toInt,
1438 reduce: &QList<int>::push_back, options: OrderedReduce);
1439 QCOMPARE(list4, QList<int>() << 1 << 2 << 3);
1440 }
1441
1442 // function-member
1443 {
1444 QList<int> list2 = QtConcurrent::mappedReduced(sequence: list,
1445 map: intSquare,
1446 reduce: &QList<int>::push_back,
1447 options: OrderedReduce);
1448 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1449 QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
1450
1451 QList<int> list3 = QtConcurrent::mappedReduced(begin: list.constBegin(),
1452 end: list.constEnd(),
1453 map: intSquare,
1454 reduce: &QList<int>::push_back,
1455 options: OrderedReduce);
1456 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1457 QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
1458
1459 QList<int> list4 = QtConcurrent::mappedReduced(sequence: QList<int>(list),
1460 map: intSquare,
1461 reduce: &QList<int>::push_back,
1462 options: OrderedReduce);
1463 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1464 QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
1465 }
1466
1467 // member-function
1468 {
1469 int sum = QtConcurrent::mappedReduced(sequence: numberList,
1470 map: &Number::toInt,
1471 reduce: intSumReduce);
1472 QCOMPARE(sum, 6);
1473 int sum2 = QtConcurrent::mappedReduced(begin: numberList.constBegin(),
1474 end: numberList.constEnd(),
1475 map: &Number::toInt,
1476 reduce: intSumReduce);
1477 QCOMPARE(sum2, 6);
1478
1479 int sum3 = QtConcurrent::mappedReduced(sequence: QList<Number>(numberList),
1480 map: &Number::toInt,
1481 reduce: intSumReduce);
1482 QCOMPARE(sum3, 6);
1483 }
1484
1485#if QT_DEPRECATED_SINCE(5, 15)
1486QT_WARNING_PUSH
1487QT_WARNING_DISABLE_DEPRECATED
1488
1489 QLinkedList<int> linkedList;
1490 linkedList << 1 << 2 << 3;
1491 QLinkedList<Number> numberLinkedList;
1492 numberLinkedList << 1 << 2 << 3;
1493
1494 // functor-functor
1495 {
1496 int sum = QtConcurrent::mappedReduced<int>(sequence: linkedList, map: IntSquare(), reduce: IntSumReduce());
1497 QCOMPARE(sum, 14);
1498 int sum2 = QtConcurrent::mappedReduced<int>(begin: linkedList.constBegin(),
1499 end: linkedList.constEnd(),
1500 map: IntSquare(),
1501 reduce: IntSumReduce());
1502 QCOMPARE(sum2, 14);
1503
1504 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<int>(linkedList), map: IntSquare(), reduce: IntSumReduce());
1505 QCOMPARE(sum3, 14);
1506
1507 int sum4 = QtConcurrent::mappedReduced<int>(sequence: linkedList, map: intSquare, reduce: intSumReduce);
1508 QCOMPARE(sum4, 14);
1509 int sum5 = QtConcurrent::mappedReduced<int>(begin: linkedList.constBegin(),
1510 end: linkedList.constEnd(),
1511 map: intSquare,
1512 reduce: intSumReduce);
1513 QCOMPARE(sum5, 14);
1514
1515 int sum6 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<int>(linkedList),
1516 map: intSquare,
1517 reduce: intSumReduce);
1518 QCOMPARE(sum6, 14);
1519 }
1520
1521 // function-functor
1522 {
1523 int sum = QtConcurrent::mappedReduced<int>(sequence: linkedList, map: intSquare, reduce: IntSumReduce());
1524 QCOMPARE(sum, 14);
1525 int sum2 = QtConcurrent::mappedReduced<int>(begin: linkedList.constBegin(),
1526 end: linkedList.constEnd(),
1527 map: intSquare,
1528 reduce: IntSumReduce());
1529 QCOMPARE(sum2, 14);
1530
1531 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<int>(linkedList), map: intSquare, reduce: IntSumReduce());
1532 QCOMPARE(sum3, 14);
1533 }
1534
1535 // functor-function
1536 {
1537 int sum = QtConcurrent::mappedReduced(sequence: linkedList, map: IntSquare(), reduce: intSumReduce);
1538 QCOMPARE(sum, 14);
1539 int sum2 = QtConcurrent::mappedReduced(begin: linkedList.constBegin(),
1540 end: linkedList.constEnd(),
1541 map: IntSquare(),
1542 reduce: intSumReduce);
1543 QCOMPARE(sum2, 14);
1544
1545 int sum3 = QtConcurrent::mappedReduced(sequence: QLinkedList<int>(linkedList), map: IntSquare(), reduce: intSumReduce);
1546 QCOMPARE(sum3, 14);
1547 }
1548
1549 // function-function
1550 {
1551 int sum = QtConcurrent::mappedReduced(sequence: linkedList, map: intSquare, reduce: intSumReduce);
1552 QCOMPARE(sum, 14);
1553 int sum2 = QtConcurrent::mappedReduced(begin: linkedList.constBegin(),
1554 end: linkedList.constEnd(),
1555 map: intSquare,
1556 reduce: intSumReduce);
1557 QCOMPARE(sum2, 14);
1558
1559 int sum3 = QtConcurrent::mappedReduced(sequence: QLinkedList<int>(linkedList), map: intSquare, reduce: intSumReduce);
1560 QCOMPARE(sum3, 14);
1561 }
1562
1563 // functor-member
1564 {
1565 QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(sequence: linkedList,
1566 map: IntSquare(),
1567 reduce: &QLinkedList<int>::push_back,
1568 options: OrderedReduce);
1569 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1570 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9);
1571
1572 QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(begin: linkedList.constBegin(),
1573 end: linkedList.constEnd(),
1574 map: IntSquare(),
1575 reduce: &QLinkedList<int>::push_back,
1576 options: OrderedReduce);
1577 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1578 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9);
1579
1580 QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(sequence: QLinkedList<int>(linkedList),
1581 map: IntSquare(),
1582 reduce: &QLinkedList<int>::push_back,
1583 options: OrderedReduce);
1584 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1585 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9);
1586 }
1587
1588 // member-functor
1589 {
1590 int sum = QtConcurrent::mappedReduced<int>(sequence: numberLinkedList, map: &Number::toInt, reduce: IntSumReduce());
1591 QCOMPARE(sum, 6);
1592 int sum2 = QtConcurrent::mappedReduced<int>(begin: numberLinkedList.constBegin(),
1593 end: numberLinkedList.constEnd(),
1594 map: &Number::toInt,
1595 reduce: IntSumReduce());
1596 QCOMPARE(sum2, 6);
1597
1598 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<Number>(numberLinkedList),
1599 map: &Number::toInt,
1600 reduce: IntSumReduce());
1601 QCOMPARE(sum3, 6);
1602 }
1603
1604 // member-member
1605 {
1606 QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(sequence: numberLinkedList,
1607 map: &Number::toInt,
1608 reduce: &QLinkedList<int>::push_back,
1609 options: OrderedReduce);
1610 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 2 << 3);
1611
1612 QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(begin: numberLinkedList.constBegin(),
1613 end: numberLinkedList.constEnd(),
1614 map: &Number::toInt,
1615 reduce: &QLinkedList<int>::push_back,
1616 options: OrderedReduce);
1617 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 2 << 3);
1618
1619 QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(sequence: QLinkedList<Number>(numberLinkedList),
1620 map: &Number::toInt,
1621 reduce: &QLinkedList<int>::push_back, options: OrderedReduce);
1622 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 2 << 3);
1623 }
1624
1625 // function-member
1626 {
1627 QLinkedList<int> linkedList2 = QtConcurrent::mappedReduced(sequence: linkedList,
1628 map: intSquare,
1629 reduce: &QLinkedList<int>::append,
1630 options: OrderedReduce);
1631 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1632 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9);
1633
1634 QLinkedList<int> linkedList3 = QtConcurrent::mappedReduced(begin: linkedList.constBegin(),
1635 end: linkedList.constEnd(),
1636 map: intSquare,
1637 reduce: &QLinkedList<int>::append,
1638 options: OrderedReduce);
1639 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1640 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9);
1641
1642 QLinkedList<int> linkedList4 = QtConcurrent::mappedReduced(sequence: QLinkedList<int>(linkedList),
1643 map: intSquare,
1644 reduce: &QLinkedList<int>::append,
1645 options: OrderedReduce);
1646 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1647 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9);
1648 }
1649
1650 // member-function
1651 {
1652 int sum = QtConcurrent::mappedReduced(sequence: numberLinkedList,
1653 map: &Number::toInt,
1654 reduce: intSumReduce);
1655 QCOMPARE(sum, 6);
1656 int sum2 = QtConcurrent::mappedReduced(begin: numberLinkedList.constBegin(),
1657 end: numberLinkedList.constEnd(),
1658 map: &Number::toInt,
1659 reduce: intSumReduce);
1660 QCOMPARE(sum2, 6);
1661
1662 int sum3 = QtConcurrent::mappedReduced(sequence: QLinkedList<Number>(numberLinkedList),
1663 map: &Number::toInt,
1664 reduce: intSumReduce);
1665 QCOMPARE(sum3, 6);
1666 }
1667
1668 // linked lists
1669 {
1670
1671 QLinkedList<int> list;
1672 list << 1 << 2 << 3;
1673
1674 QLinkedList<Number> numberList;
1675 numberList << 1 << 2 << 3;
1676
1677 int sum = QtConcurrent::mappedReduced<int>(sequence: list, map: IntSquare(), reduce: IntSumReduce());
1678 QCOMPARE(sum, 14);
1679 int sum2 = QtConcurrent::mappedReduced<int>(begin: list.constBegin(),
1680 end: list.constEnd(),
1681 map: IntSquare(),
1682 reduce: IntSumReduce());
1683 QCOMPARE(sum2, 14);
1684
1685 int sum3 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<int>(list), map: IntSquare(), reduce: IntSumReduce());
1686 QCOMPARE(sum3, 14);
1687
1688 int sum4 = QtConcurrent::mappedReduced<int>(sequence: list, map: intSquare, reduce: intSumReduce);
1689 QCOMPARE(sum4, 14);
1690 int sum5 = QtConcurrent::mappedReduced<int>(begin: list.constBegin(),
1691 end: list.constEnd(),
1692 map: intSquare,
1693 reduce: intSumReduce);
1694 QCOMPARE(sum5, 14);
1695
1696 int sum6 = QtConcurrent::mappedReduced<int>(sequence: QLinkedList<int>(list),
1697 map: intSquare,
1698 reduce: intSumReduce);
1699 QCOMPARE(sum6, 14);
1700 }
1701
1702QT_WARNING_POP
1703#endif
1704
1705 // ### the same as above, with an initial result value
1706}
1707
1708void tst_QtConcurrentMap::blocking_mappedReduced()
1709{
1710 QList<int> list;
1711 list << 1 << 2 << 3;
1712 QList<Number> numberList;
1713 numberList << 1 << 2 << 3;
1714
1715 // functor-functor
1716 {
1717 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: list, map: IntSquare(), reduce: IntSumReduce());
1718 QCOMPARE(sum, 14);
1719 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: list.constBegin(),
1720 end: list.constEnd(),
1721 map: IntSquare(),
1722 reduce: IntSumReduce());
1723 QCOMPARE(sum2, 14);
1724
1725 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QList<int>(list), map: IntSquare(), reduce: IntSumReduce());
1726 QCOMPARE(sum3, 14);
1727
1728 int sum4 = QtConcurrent::blockingMappedReduced<int>(sequence: list, map: intSquare, reduce: intSumReduce);
1729 QCOMPARE(sum4, 14);
1730 int sum5 = QtConcurrent::blockingMappedReduced<int>(begin: list.constBegin(),
1731 end: list.constEnd(),
1732 map: intSquare,
1733 reduce: intSumReduce);
1734 QCOMPARE(sum5, 14);
1735
1736 int sum6 = QtConcurrent::blockingMappedReduced<int>(sequence: QList<int>(list),
1737 map: intSquare,
1738 reduce: intSumReduce);
1739 QCOMPARE(sum6, 14);
1740 }
1741
1742 // function-functor
1743 {
1744 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: list, map: intSquare, reduce: IntSumReduce());
1745 QCOMPARE(sum, 14);
1746 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: list.constBegin(),
1747 end: list.constEnd(),
1748 map: intSquare,
1749 reduce: IntSumReduce());
1750 QCOMPARE(sum2, 14);
1751
1752 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QList<int>(list), map: intSquare, reduce: IntSumReduce());
1753 QCOMPARE(sum3, 14);
1754 }
1755
1756 // functor-function
1757 {
1758 int sum = QtConcurrent::blockingMappedReduced(sequence: list, map: IntSquare(), reduce: intSumReduce);
1759 QCOMPARE(sum, 14);
1760 int sum2 = QtConcurrent::blockingMappedReduced(begin: list.constBegin(),
1761 end: list.constEnd(),
1762 map: IntSquare(),
1763 reduce: intSumReduce);
1764 QCOMPARE(sum2, 14);
1765
1766 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QList<int>(list), map: IntSquare(), reduce: intSumReduce);
1767 QCOMPARE(sum3, 14);
1768 }
1769
1770 // function-function
1771 {
1772 int sum = QtConcurrent::blockingMappedReduced(sequence: list, map: intSquare, reduce: intSumReduce);
1773 QCOMPARE(sum, 14);
1774 int sum2 = QtConcurrent::blockingMappedReduced(begin: list.constBegin(),
1775 end: list.constEnd(),
1776 map: intSquare,
1777 reduce: intSumReduce);
1778 QCOMPARE(sum2, 14);
1779
1780 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QList<int>(list), map: intSquare, reduce: intSumReduce);
1781 QCOMPARE(sum3, 14);
1782 }
1783
1784 // functor-member
1785 {
1786 QList<int> list2 = QtConcurrent::blockingMappedReduced(sequence: list,
1787 map: IntSquare(),
1788 reduce: &QList<int>::push_back,
1789 options: OrderedReduce);
1790 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1791 QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
1792
1793 QList<int> list3 = QtConcurrent::blockingMappedReduced(begin: list.constBegin(),
1794 end: list.constEnd(),
1795 map: IntSquare(),
1796 reduce: &QList<int>::push_back,
1797 options: OrderedReduce);
1798 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1799 QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
1800
1801 QList<int> list4 = QtConcurrent::blockingMappedReduced(sequence: QList<int>(list),
1802 map: IntSquare(),
1803 reduce: &QList<int>::push_back,
1804 options: OrderedReduce);
1805 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1806 QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
1807 }
1808
1809 // member-functor
1810 {
1811 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: numberList, map: &Number::toInt,
1812 reduce: IntSumReduce());
1813 QCOMPARE(sum, 6);
1814 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: numberList.constBegin(),
1815 end: numberList.constEnd(),
1816 map: &Number::toInt,
1817 reduce: IntSumReduce());
1818 QCOMPARE(sum2, 6);
1819
1820 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QList<Number>(numberList),
1821 map: &Number::toInt,
1822 reduce: IntSumReduce());
1823 QCOMPARE(sum3, 6);
1824 }
1825
1826 // member-member
1827 {
1828 QList<int> list2 = QtConcurrent::blockingMappedReduced(sequence: numberList,
1829 map: &Number::toInt,
1830 reduce: &QList<int>::push_back,
1831 options: OrderedReduce);
1832 QCOMPARE(list2, QList<int>() << 1 << 2 << 3);
1833
1834 QList<int> list3 = QtConcurrent::blockingMappedReduced(begin: numberList.constBegin(),
1835 end: numberList.constEnd(),
1836 map: &Number::toInt,
1837 reduce: &QList<int>::push_back,
1838 options: OrderedReduce);
1839 QCOMPARE(list3, QList<int>() << 1 << 2 << 3);
1840
1841 QList<int> list4 = QtConcurrent::blockingMappedReduced(sequence: QList<Number>(numberList),
1842 map: &Number::toInt,
1843 reduce: &QList<int>::push_back, options: OrderedReduce);
1844 QCOMPARE(list4, QList<int>() << 1 << 2 << 3);
1845 }
1846
1847 // function-member
1848 {
1849 QList<int> list2 = QtConcurrent::blockingMappedReduced(sequence: list,
1850 map: intSquare,
1851 reduce: &QList<int>::push_back,
1852 options: OrderedReduce);
1853 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1854 QCOMPARE(list2, QList<int>() << 1 << 4 << 9);
1855
1856 QList<int> list3 = QtConcurrent::blockingMappedReduced(begin: list.constBegin(),
1857 end: list.constEnd(),
1858 map: intSquare,
1859 reduce: &QList<int>::push_back,
1860 options: OrderedReduce);
1861 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1862 QCOMPARE(list3, QList<int>() << 1 << 4 << 9);
1863
1864 QList<int> list4 = QtConcurrent::blockingMappedReduced(sequence: QList<int>(list),
1865 map: intSquare,
1866 reduce: &QList<int>::push_back,
1867 options: OrderedReduce);
1868 QCOMPARE(list, QList<int>() << 1 << 2 << 3);
1869 QCOMPARE(list4, QList<int>() << 1 << 4 << 9);
1870 }
1871
1872 // member-function
1873 {
1874 int sum = QtConcurrent::blockingMappedReduced(sequence: numberList,
1875 map: &Number::toInt,
1876 reduce: intSumReduce);
1877 QCOMPARE(sum, 6);
1878 int sum2 = QtConcurrent::blockingMappedReduced(begin: numberList.constBegin(),
1879 end: numberList.constEnd(),
1880 map: &Number::toInt,
1881 reduce: intSumReduce);
1882 QCOMPARE(sum2, 6);
1883
1884 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QList<Number>(numberList),
1885 map: &Number::toInt,
1886 reduce: intSumReduce);
1887 QCOMPARE(sum3, 6);
1888 }
1889
1890#if QT_DEPRECATED_SINCE(5, 15)
1891QT_WARNING_PUSH
1892QT_WARNING_DISABLE_DEPRECATED
1893
1894 QLinkedList<int> linkedList;
1895 linkedList << 1 << 2 << 3;
1896 QLinkedList<Number> numberLinkedList;
1897 numberLinkedList << 1 << 2 << 3;
1898
1899 // functor-functor
1900 {
1901 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: linkedList, map: IntSquare(), reduce: IntSumReduce());
1902 QCOMPARE(sum, 14);
1903 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: linkedList.constBegin(),
1904 end: linkedList.constEnd(),
1905 map: IntSquare(),
1906 reduce: IntSumReduce());
1907 QCOMPARE(sum2, 14);
1908
1909 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<int>(linkedList), map: IntSquare(), reduce: IntSumReduce());
1910 QCOMPARE(sum3, 14);
1911
1912 int sum4 = QtConcurrent::blockingMappedReduced<int>(sequence: linkedList, map: intSquare, reduce: intSumReduce);
1913 QCOMPARE(sum4, 14);
1914 int sum5 = QtConcurrent::blockingMappedReduced<int>(begin: linkedList.constBegin(),
1915 end: linkedList.constEnd(),
1916 map: intSquare,
1917 reduce: intSumReduce);
1918 QCOMPARE(sum5, 14);
1919
1920 int sum6 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<int>(linkedList),
1921 map: intSquare,
1922 reduce: intSumReduce);
1923 QCOMPARE(sum6, 14);
1924 }
1925
1926 // function-functor
1927 {
1928 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: linkedList, map: intSquare, reduce: IntSumReduce());
1929 QCOMPARE(sum, 14);
1930 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: linkedList.constBegin(),
1931 end: linkedList.constEnd(),
1932 map: intSquare,
1933 reduce: IntSumReduce());
1934 QCOMPARE(sum2, 14);
1935
1936 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<int>(linkedList), map: intSquare, reduce: IntSumReduce());
1937 QCOMPARE(sum3, 14);
1938 }
1939
1940 // functor-function
1941 {
1942 int sum = QtConcurrent::blockingMappedReduced(sequence: linkedList, map: IntSquare(), reduce: intSumReduce);
1943 QCOMPARE(sum, 14);
1944 int sum2 = QtConcurrent::blockingMappedReduced(begin: linkedList.constBegin(),
1945 end: linkedList.constEnd(),
1946 map: IntSquare(),
1947 reduce: intSumReduce);
1948 QCOMPARE(sum2, 14);
1949
1950 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<int>(linkedList), map: IntSquare(), reduce: intSumReduce);
1951 QCOMPARE(sum3, 14);
1952 }
1953
1954 // function-function
1955 {
1956 int sum = QtConcurrent::blockingMappedReduced(sequence: linkedList, map: intSquare, reduce: intSumReduce);
1957 QCOMPARE(sum, 14);
1958 int sum2 = QtConcurrent::blockingMappedReduced(begin: linkedList.constBegin(),
1959 end: linkedList.constEnd(),
1960 map: intSquare,
1961 reduce: intSumReduce);
1962 QCOMPARE(sum2, 14);
1963
1964 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<int>(linkedList), map: intSquare, reduce: intSumReduce);
1965 QCOMPARE(sum3, 14);
1966 }
1967
1968 // functor-member
1969 {
1970 QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(sequence: linkedList,
1971 map: IntSquare(),
1972 reduce: &QLinkedList<int>::append,
1973 options: OrderedReduce);
1974 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1975 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9);
1976
1977 QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(begin: linkedList.constBegin(),
1978 end: linkedList.constEnd(),
1979 map: IntSquare(),
1980 reduce: &QLinkedList<int>::append,
1981 options: OrderedReduce);
1982 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1983 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9);
1984
1985 QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<int>(linkedList),
1986 map: IntSquare(),
1987 reduce: &QLinkedList<int>::append,
1988 options: OrderedReduce);
1989 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
1990 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9);
1991 }
1992
1993 // member-functor
1994 {
1995 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: numberLinkedList, map: &Number::toInt, reduce: IntSumReduce());
1996 QCOMPARE(sum, 6);
1997 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: numberLinkedList.constBegin(),
1998 end: numberLinkedList.constEnd(),
1999 map: &Number::toInt,
2000 reduce: IntSumReduce());
2001 QCOMPARE(sum2, 6);
2002
2003 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<Number>(numberLinkedList),
2004 map: &Number::toInt,
2005 reduce: IntSumReduce());
2006 QCOMPARE(sum3, 6);
2007 }
2008
2009 // member-member
2010 {
2011 QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(sequence: numberLinkedList,
2012 map: &Number::toInt,
2013 reduce: &QLinkedList<int>::append,
2014 options: OrderedReduce);
2015 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 2 << 3);
2016
2017 QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(begin: numberLinkedList.constBegin(),
2018 end: numberLinkedList.constEnd(),
2019 map: &Number::toInt,
2020 reduce: &QLinkedList<int>::append,
2021 options: OrderedReduce);
2022 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 2 << 3);
2023
2024 QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<Number>(numberLinkedList),
2025 map: &Number::toInt,
2026 reduce: &QLinkedList<int>::append, options: OrderedReduce);
2027 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 2 << 3);
2028 }
2029
2030 // function-member
2031 {
2032 QLinkedList<int> linkedList2 = QtConcurrent::blockingMappedReduced(sequence: linkedList,
2033 map: intSquare,
2034 reduce: &QLinkedList<int>::append,
2035 options: OrderedReduce);
2036 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
2037 QCOMPARE(linkedList2, QLinkedList<int>() << 1 << 4 << 9);
2038
2039 QLinkedList<int> linkedList3 = QtConcurrent::blockingMappedReduced(begin: linkedList.constBegin(),
2040 end: linkedList.constEnd(),
2041 map: intSquare,
2042 reduce: &QLinkedList<int>::append,
2043 options: OrderedReduce);
2044 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
2045 QCOMPARE(linkedList3, QLinkedList<int>() << 1 << 4 << 9);
2046
2047 QLinkedList<int> linkedList4 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<int>(linkedList),
2048 map: intSquare,
2049 reduce: &QLinkedList<int>::append,
2050 options: OrderedReduce);
2051 QCOMPARE(linkedList, QLinkedList<int>() << 1 << 2 << 3);
2052 QCOMPARE(linkedList4, QLinkedList<int>() << 1 << 4 << 9);
2053 }
2054
2055 // member-function
2056 {
2057 int sum = QtConcurrent::blockingMappedReduced(sequence: numberLinkedList,
2058 map: &Number::toInt,
2059 reduce: intSumReduce);
2060 QCOMPARE(sum, 6);
2061 int sum2 = QtConcurrent::blockingMappedReduced(begin: numberLinkedList.constBegin(),
2062 end: numberLinkedList.constEnd(),
2063 map: &Number::toInt,
2064 reduce: intSumReduce);
2065 QCOMPARE(sum2, 6);
2066
2067 int sum3 = QtConcurrent::blockingMappedReduced(sequence: QLinkedList<Number>(numberLinkedList),
2068 map: &Number::toInt,
2069 reduce: intSumReduce);
2070 QCOMPARE(sum3, 6);
2071 }
2072
2073 // linked lists
2074 {
2075
2076 QLinkedList<int> list;
2077 list << 1 << 2 << 3;
2078
2079 QLinkedList<Number> numberList;
2080 numberList << 1 << 2 << 3;
2081
2082 int sum = QtConcurrent::blockingMappedReduced<int>(sequence: list, map: IntSquare(), reduce: IntSumReduce());
2083 QCOMPARE(sum, 14);
2084 int sum2 = QtConcurrent::blockingMappedReduced<int>(begin: list.constBegin(),
2085 end: list.constEnd(),
2086 map: IntSquare(),
2087 reduce: IntSumReduce());
2088 QCOMPARE(sum2, 14);
2089
2090 int sum3 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<int>(list), map: IntSquare(), reduce: IntSumReduce());
2091 QCOMPARE(sum3, 14);
2092
2093 int sum4 = QtConcurrent::blockingMappedReduced<int>(sequence: list, map: intSquare, reduce: intSumReduce);
2094 QCOMPARE(sum4, 14);
2095 int sum5 = QtConcurrent::blockingMappedReduced<int>(begin: list.constBegin(),
2096 end: list.constEnd(),
2097 map: intSquare,
2098 reduce: intSumReduce);
2099 QCOMPARE(sum5, 14);
2100
2101 int sum6 = QtConcurrent::blockingMappedReduced<int>(sequence: QLinkedList<int>(list),
2102 map: intSquare,
2103 reduce: intSumReduce);
2104 QCOMPARE(sum6, 14);
2105 }
2106
2107QT_WARNING_POP
2108#endif
2109
2110 // ### the same as above, with an initial result value
2111}
2112
2113int sleeper(int val)
2114{
2115 QTest::qSleep(ms: 100);
2116 return val;
2117}
2118
2119void tst_QtConcurrentMap::assignResult()
2120{
2121 const QList<int> startList = QList<int>() << 0 << 1 << 2;
2122 QList<int> list = QtConcurrent::blockingMapped(sequence: startList, map: sleeper);
2123 QCOMPARE(list.at(0), 0);
2124 QCOMPARE(list.at(1), 1);
2125}
2126
2127int fnConst(const int &i)
2128{
2129 return i;
2130}
2131
2132int fn(int &i)
2133{
2134 return i;
2135}
2136
2137int fnConstNoExcept(const int &i) noexcept
2138{
2139 return i;
2140}
2141
2142int fnNoExcept(int &i) noexcept
2143{
2144 return i;
2145}
2146
2147QString changeTypeConst(const int &)
2148{
2149 return QString();
2150}
2151
2152QString changeType(int &)
2153{
2154 return QString();
2155}
2156
2157QString changeTypeConstNoExcept(const int &) noexcept
2158{
2159 return QString();
2160}
2161
2162QString changeTypeNoExcept(int &) noexcept
2163{
2164 return QString();
2165}
2166
2167int changeTypeQStringListConst(const QStringList &)
2168{
2169 return 0;
2170}
2171
2172int changeTypeQStringList(QStringList &)
2173{
2174 return 0;
2175}
2176
2177int changeTypeQStringListConstNoExcept(const QStringList &) noexcept
2178{
2179 return 0;
2180}
2181
2182int changeTypeQStringListNoExcept(QStringList &) noexcept
2183{
2184 return 0;
2185}
2186
2187class MemFnTester
2188{
2189public:
2190 MemFnTester() {}
2191
2192 MemFnTester fn()
2193 {
2194 return MemFnTester();
2195 }
2196
2197 MemFnTester fnConst() const
2198 {
2199 return MemFnTester();
2200 }
2201
2202 QString changeType()
2203 {
2204 return QString();
2205 }
2206
2207 QString changeTypeConst() const
2208 {
2209 return QString();
2210 }
2211
2212 MemFnTester fnNoExcept() noexcept
2213 {
2214 return MemFnTester();
2215 }
2216
2217 MemFnTester fnConstNoExcept() const noexcept
2218 {
2219 return MemFnTester();
2220 }
2221
2222 QString changeTypeNoExcept() noexcept
2223 {
2224 return QString();
2225 }
2226
2227 QString changeTypeConstNoExcept() const noexcept
2228 {
2229 return QString();
2230 }
2231};
2232
2233Q_DECLARE_METATYPE(QVector<MemFnTester>);
2234Q_DECLARE_METATYPE(QList<MemFnTester>);
2235
2236void tst_QtConcurrentMap::functionOverloads()
2237{
2238 QList<int> intList;
2239 const QList<int> constIntList;
2240 QList<MemFnTester> classList;
2241 const QList<MemFnTester> constMemFnTesterList;
2242
2243 QtConcurrent::mapped(sequence: intList, map: fnConst);
2244 QtConcurrent::mapped(sequence: constIntList, map: fnConst);
2245 QtConcurrent::mapped(sequence: classList, map: &MemFnTester::fnConst);
2246 QtConcurrent::mapped(sequence: constMemFnTesterList, map: &MemFnTester::fnConst);
2247
2248 QtConcurrent::blockingMapped<QVector<int> >(sequence: intList, map: fnConst);
2249 QtConcurrent::blockingMapped<QVector<int> >(sequence: constIntList, map: fnConst);
2250 QtConcurrent::blockingMapped<QVector<MemFnTester> >(sequence: classList, map: &MemFnTester::fnConst);
2251 QtConcurrent::blockingMapped<QVector<MemFnTester> >(sequence: constMemFnTesterList, map: &MemFnTester::fnConst);
2252
2253 QtConcurrent::blockingMapped<QList<QString> >(sequence: intList, map: changeTypeConst);
2254 QtConcurrent::blockingMapped<QList<QString> >(sequence: constIntList, map: changeTypeConst);
2255 QtConcurrent::blockingMapped<QList<QString> >(sequence: classList, map: &MemFnTester::changeTypeConst);
2256 QtConcurrent::blockingMapped<QList<QString> >(sequence: constMemFnTesterList, map: &MemFnTester::changeTypeConst);
2257}
2258
2259void tst_QtConcurrentMap::noExceptFunctionOverloads()
2260{
2261 QList<int> intList;
2262 const QList<int> constIntList;
2263 QList<MemFnTester> classList;
2264 const QList<MemFnTester> constMemFnTesterList;
2265
2266 QtConcurrent::mapped(sequence: intList, map: fnConstNoExcept);
2267 QtConcurrent::mapped(sequence: constIntList, map: fnConstNoExcept);
2268 QtConcurrent::mapped(sequence: classList, map: &MemFnTester::fnConstNoExcept);
2269 QtConcurrent::mapped(sequence: constMemFnTesterList, map: &MemFnTester::fnConstNoExcept);
2270
2271 QtConcurrent::blockingMapped<QVector<int> >(sequence: intList, map: fnConstNoExcept);
2272 QtConcurrent::blockingMapped<QVector<int> >(sequence: constIntList, map: fnConstNoExcept);
2273 QtConcurrent::blockingMapped<QVector<MemFnTester> >(sequence: classList, map: &MemFnTester::fnConstNoExcept);
2274 QtConcurrent::blockingMapped<QVector<MemFnTester> >(sequence: constMemFnTesterList, map: &MemFnTester::fnConstNoExcept);
2275
2276 QtConcurrent::blockingMapped<QList<QString> >(sequence: intList, map: changeTypeConstNoExcept);
2277 QtConcurrent::blockingMapped<QList<QString> >(sequence: constIntList, map: changeTypeConstNoExcept);
2278 QtConcurrent::blockingMapped<QList<QString> >(sequence: classList, map: &MemFnTester::changeTypeConstNoExcept);
2279 QtConcurrent::blockingMapped<QList<QString> >(sequence: constMemFnTesterList, map: &MemFnTester::changeTypeConstNoExcept);
2280}
2281
2282QAtomicInt currentInstanceCount;
2283QAtomicInt peakInstanceCount;
2284class InstanceCounter
2285{
2286public:
2287 inline InstanceCounter()
2288 { currentInstanceCount.fetchAndAddRelaxed(valueToAdd: 1); updatePeak(); }
2289 inline ~InstanceCounter()
2290 { currentInstanceCount.fetchAndAddRelaxed(valueToAdd: -1);}
2291 inline InstanceCounter(const InstanceCounter &)
2292 { currentInstanceCount.fetchAndAddRelaxed(valueToAdd: 1); updatePeak(); }
2293
2294 void updatePeak()
2295 {
2296 forever {
2297 const int localPeak = peakInstanceCount.loadRelaxed();
2298 const int localCurrent = currentInstanceCount.loadRelaxed();
2299 if (localCurrent <= localPeak)
2300 break;
2301 if (peakInstanceCount.testAndSetOrdered(expectedValue: localPeak, newValue: localCurrent))
2302 break;
2303 }
2304 }
2305};
2306
2307InstanceCounter slowMap(const InstanceCounter &in)
2308{
2309 QTest::qSleep(ms: 2);
2310 return in;
2311}
2312
2313InstanceCounter fastMap(const InstanceCounter &in)
2314{
2315 QTest::qSleep(ms: QRandomGenerator::global()->bounded(highest: 2) + 1);
2316 return in;
2317}
2318
2319void slowReduce(int &result, const InstanceCounter&)
2320{
2321 QTest::qSleep(ms: QRandomGenerator::global()->bounded(highest: 4) + 1);
2322 ++result;
2323}
2324
2325void fastReduce(int &result, const InstanceCounter&)
2326{
2327 ++result;
2328}
2329
2330void tst_QtConcurrentMap::throttling()
2331{
2332 const int itemcount = 100;
2333 const int allowedTemporaries = QThread::idealThreadCount() * 40;
2334
2335 {
2336 currentInstanceCount.storeRelaxed(newValue: 0);
2337 peakInstanceCount.storeRelaxed(newValue: 0);
2338
2339 QList<InstanceCounter> instances;
2340 for (int i = 0; i < itemcount; ++i)
2341 instances.append(t: InstanceCounter());
2342
2343 QCOMPARE(currentInstanceCount.loadRelaxed(), itemcount);
2344
2345 int results = QtConcurrent::blockingMappedReduced(sequence: instances, map: slowMap, reduce: fastReduce);
2346 QCOMPARE(results, itemcount);
2347 QCOMPARE(currentInstanceCount.loadRelaxed(), itemcount);
2348 QVERIFY(peakInstanceCount.loadRelaxed() < itemcount + allowedTemporaries);
2349 }
2350
2351 {
2352 QCOMPARE(currentInstanceCount.loadRelaxed(), 0);
2353 peakInstanceCount.storeRelaxed(newValue: 0);
2354
2355 QList<InstanceCounter> instances;
2356 for (int i = 0; i < itemcount; ++i)
2357 instances.append(t: InstanceCounter());
2358
2359 QCOMPARE(currentInstanceCount.loadRelaxed(), itemcount);
2360 int results = QtConcurrent::blockingMappedReduced(sequence: instances, map: fastMap, reduce: slowReduce);
2361
2362 QCOMPARE(results, itemcount);
2363 QCOMPARE(currentInstanceCount.loadRelaxed(), itemcount);
2364 QVERIFY(peakInstanceCount.loadRelaxed() < itemcount + allowedTemporaries);
2365 }
2366}
2367
2368#ifndef QT_NO_EXCEPTIONS
2369void throwMapper(int &e)
2370{
2371 Q_UNUSED(e);
2372 throw QException();
2373}
2374
2375void tst_QtConcurrentMap::exceptions()
2376{
2377 bool caught = false;
2378 try {
2379 QList<int> list = QList<int>() << 1 << 2 << 3;
2380 QtConcurrent::map(sequence&: list, map: throwMapper).waitForFinished();
2381 } catch (const QException &) {
2382 caught = true;
2383 }
2384 if (!caught)
2385 QFAIL("did not get exception");
2386}
2387#endif
2388
2389int mapper(const int &i)
2390{
2391 QTest::qWait(ms: 1);
2392 return i;
2393}
2394
2395void tst_QtConcurrentMap::incrementalResults()
2396{
2397 const int count = 200;
2398 QList<int> ints;
2399 for (int i=0; i < count; ++i)
2400 ints << i;
2401
2402 QFuture<int> future = QtConcurrent::mapped(sequence: ints, map: mapper);
2403
2404 QList<int> results;
2405
2406 while (future.isFinished() == false) {
2407 for (int i = 0; i < future.resultCount(); ++i) {
2408 results += future.resultAt(index: i);
2409 }
2410
2411 QTest::qWait(ms: 1);
2412 }
2413
2414 QCOMPARE(future.isFinished(), true);
2415 QCOMPARE(future.resultCount(), count);
2416 QCOMPARE(future.results().count(), count);
2417}
2418
2419/*
2420 Test that mapped does not cause deep copies when holding
2421 references to Qt containers.
2422*/
2423void tst_QtConcurrentMap::noDetach()
2424{
2425 {
2426 QList<int> l = QList<int>() << 1;
2427 QVERIFY(l.isDetached());
2428
2429 QList<int> ll = l;
2430 QVERIFY(!l.isDetached());
2431
2432 QtConcurrent::mapped(sequence: l, map: mapper).waitForFinished();
2433
2434 QVERIFY(!l.isDetached());
2435 QVERIFY(!ll.isDetached());
2436
2437 QtConcurrent::mappedReduced(sequence: l, map: mapper, reduce: intSumReduce).waitForFinished();
2438
2439 QVERIFY(!l.isDetached());
2440 QVERIFY(!ll.isDetached());
2441
2442 QtConcurrent::map(sequence&: l, map: multiplyBy2Immutable).waitForFinished();
2443 QVERIFY(l.isDetached());
2444 QVERIFY(ll.isDetached());
2445 }
2446 {
2447 const QList<int> l = QList<int>() << 1;
2448 QVERIFY(l.isDetached());
2449
2450 const QList<int> ll = l;
2451 QVERIFY(!l.isDetached());
2452
2453 QtConcurrent::mapped(sequence: l, map: mapper).waitForFinished();
2454
2455 QVERIFY(!l.isDetached());
2456 QVERIFY(!ll.isDetached());
2457
2458 QtConcurrent::mappedReduced(sequence: l, map: mapper, reduce: intSumReduce).waitForFinished();
2459
2460 QVERIFY(!l.isDetached());
2461 QVERIFY(!ll.isDetached());
2462 }
2463
2464}
2465
2466void tst_QtConcurrentMap::stlContainers()
2467{
2468 std::vector<int> vector;
2469 vector.push_back(x: 1);
2470 vector.push_back(x: 2);
2471
2472 std::vector<int> vector2 = QtConcurrent::blockingMapped<std::vector<int> >(sequence: vector, map: mapper);
2473 QCOMPARE(vector2.size(), (std::vector<int>::size_type)(2));
2474
2475 std::list<int> list;
2476 list.push_back(x: 1);
2477 list.push_back(x: 2);
2478
2479 std::list<int> list2 = QtConcurrent::blockingMapped<std::list<int> >(sequence: list, map: mapper);
2480 QCOMPARE(list2.size(), (std::vector<int>::size_type)(2));
2481
2482 QtConcurrent::mapped(sequence: list, map: mapper).waitForFinished();
2483
2484 QtConcurrent::blockingMap(sequence&: list, map: multiplyBy2Immutable);
2485}
2486
2487InstanceCounter ic_fn(const InstanceCounter & ic)
2488{
2489 return InstanceCounter(ic);
2490}
2491
2492// Verify that held results are deleted when a future is
2493// assigned over with operator ==
2494void tst_QtConcurrentMap::qFutureAssignmentLeak()
2495{
2496 currentInstanceCount.storeRelaxed(newValue: 0);
2497 peakInstanceCount.storeRelaxed(newValue: 0);
2498 QFuture<InstanceCounter> future;
2499 {
2500 QList<InstanceCounter> list;
2501 for (int i=0;i<1000;++i)
2502 list += InstanceCounter();
2503 future = QtConcurrent::mapped(sequence: list, map: ic_fn);
2504 future.waitForFinished();
2505
2506 future = QtConcurrent::mapped(sequence: list, map: ic_fn);
2507 future.waitForFinished();
2508
2509 future = QtConcurrent::mapped(sequence: list, map: ic_fn);
2510 future.waitForFinished();
2511 }
2512
2513 // Use QTRY_COMPARE because QtConcurrent::ThreadEngine::asynchronousFinish()
2514 // deletes its internals after signaling finished, so it might still be holding
2515 // on to copies of InstanceCounter for a short while.
2516 QTRY_COMPARE(currentInstanceCount.loadRelaxed(), 1000);
2517 future = QFuture<InstanceCounter>();
2518 QTRY_COMPARE(currentInstanceCount.loadRelaxed(), 0);
2519}
2520
2521inline void increment(int &num)
2522{
2523 ++num;
2524}
2525
2526inline int echo(const int &num)
2527{
2528 return num;
2529}
2530
2531void add(int &result, const int &sum)
2532{
2533 result += sum;
2534}
2535
2536void tst_QtConcurrentMap::stressTest()
2537{
2538 const int listSize = 1000;
2539 const int sum = (listSize - 1) * (listSize / 2);
2540 QList<int> list;
2541
2542
2543 for (int i = 0; i < listSize; ++i) {
2544 list.append(t: i);
2545 }
2546
2547 for (int i =0 ; i < 100; ++i) {
2548 QList<int> result = QtConcurrent::blockingMapped(sequence: list, map: echo);
2549 for (int j = 0; j < listSize; ++j)
2550 QCOMPARE(result.at(j), j);
2551 }
2552
2553 for (int i = 0 ; i < 100; ++i) {
2554 int result = QtConcurrent::blockingMappedReduced(sequence: list, map: echo, reduce: add);
2555 QCOMPARE(result, sum);
2556 }
2557
2558 for (int i = 0 ; i < 100; ++i) {
2559 QtConcurrent::map(sequence&: list, map: increment).waitForFinished();
2560 for (int j = 0; j < listSize; ++j)
2561 QCOMPARE(list.at(j), i + j + 1);
2562 }
2563}
2564
2565struct LockedCounter
2566{
2567 LockedCounter(QMutex *mutex, QAtomicInt *ai)
2568 : mtx(mutex),
2569 ref(ai) {}
2570
2571 typedef int result_type;
2572 int operator()(int x)
2573 {
2574 QMutexLocker locker(mtx);
2575 ref->ref();
2576 return ++x;
2577 }
2578
2579 QMutex *mtx;
2580 QAtomicInt *ref;
2581};
2582
2583// The Thread engine holds the last reference
2584// to the QFuture, so this should not leak
2585// or fail.
2586void tst_QtConcurrentMap::persistentResultTest()
2587{
2588 QFuture<void> voidFuture;
2589 QMutex mtx;
2590 QAtomicInt ref;
2591 LockedCounter lc(&mtx, &ref);
2592 QList<int> list;
2593 {
2594 list << 1 << 2 << 3;
2595 mtx.lock();
2596 QFuture<int> future = QtConcurrent::mapped(sequence: list
2597 ,map: lc);
2598 voidFuture = future;
2599 }
2600 QCOMPARE(ref.loadAcquire(), 0);
2601 mtx.unlock(); // Unblock
2602 voidFuture.waitForFinished();
2603 QCOMPARE(ref.loadAcquire(), 3);
2604}
2605
2606QTEST_MAIN(tst_QtConcurrentMap)
2607#include "tst_qtconcurrentmap.moc"
2608

source code of qtbase/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp