1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtConcurrent module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40/*!
41 \namespace QtConcurrent
42 \inmodule QtConcurrent
43 \since 4.4
44 \brief The QtConcurrent namespace provides high-level APIs that make it
45 possible to write multi-threaded programs without using low-level
46 threading primitives.
47
48 See the \l {Qt Concurrent} module documentation for an overview of available
49 functions, or see below for detailed information on each function.
50
51 \inheaderfile QtConcurrent
52 \ingroup thread
53*/
54
55/*!
56 \enum QtConcurrent::ReduceQueueLimits
57 \internal
58 */
59
60/*!
61 \class QtConcurrent::ReduceKernel
62 \inmodule QtConcurrent
63 \internal
64*/
65
66/*!
67 \class QtConcurrent::SequenceHolder2
68 \inmodule QtConcurrent
69 \internal
70*/
71
72/*!
73 \class QtConcurrent::MapKernel
74 \inmodule QtConcurrent
75 \internal
76*/
77
78/*!
79 \class QtConcurrent::MappedReducedKernel
80 \inmodule QtConcurrent
81 \internal
82*/
83
84/*!
85 \class QtConcurrent::MappedEachKernel
86 \inmodule QtConcurrent
87 \internal
88*/
89
90/*!
91 \class QtConcurrent::SequenceHolder1
92 \inmodule QtConcurrent
93 \internal
94*/
95
96/*!
97 \fn [qtconcurrentmapkernel-1] ThreadEngineStarter<void> QtConcurrent::startMap(Iterator begin, Iterator end, Functor functor)
98 \internal
99*/
100
101/*!
102 \fn [qtconcurrentmapkernel-2] ThreadEngineStarter<T> QtConcurrent::startMapped(Iterator begin, Iterator end, Functor functor)
103 \internal
104*/
105
106/*!
107 \fn [qtconcurrentmapkernel-3] ThreadEngineStarter<T> QtConcurrent::startMapped(const Sequence &sequence, Functor functor)
108 \internal
109*/
110
111/*!
112 \fn [qtconcurrentmapkernel-4] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(const Sequence & sequence, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
113 \internal
114*/
115
116/*!
117 \fn [qtconcurrentmapkernel-5] ThreadEngineStarter<ResultType> QtConcurrent::startMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunctor, ReduceFunctor reduceFunctor, ReduceOptions options)
118 \internal
119*/
120
121/*!
122 \enum QtConcurrent::ReduceOption
123 This enum specifies the order of which results from the map or filter
124 function are passed to the reduce function.
125
126 \value UnorderedReduce Reduction is done in an arbitrary order.
127 \value OrderedReduce Reduction is done in the order of the
128 original sequence.
129 \value SequentialReduce Reduction is done sequentially: only one
130 thread will enter the reduce function at a time. (Parallel reduction
131 might be supported in a future version of Qt Concurrent.)
132*/
133
134/*!
135 \page qtconcurrentmap.html
136 \title Concurrent Map and Map-Reduce
137 \ingroup thread
138
139 The QtConcurrent::map(), QtConcurrent::mapped() and
140 QtConcurrent::mappedReduced() functions run computations in parallel on
141 the items in a sequence such as a QList or a QVector. QtConcurrent::map()
142 modifies a sequence in-place, QtConcurrent::mapped() returns a new
143 sequence containing the modified content, and QtConcurrent::mappedReduced()
144 returns a single result.
145
146 These functions are a part of the \l {Qt Concurrent} framework.
147
148 Each of the above functions has a blocking variant that returns
149 the final result instead of a QFuture. You use them in the same
150 way as the asynchronous variants.
151
152 \snippet code/src_concurrent_qtconcurrentmap.cpp 7
153
154 Note that the result types above are not QFuture objects, but real result
155 types (in this case, QList<QImage> and QImage).
156
157 \section1 Concurrent Map
158
159 QtConcurrent::mapped() takes an input sequence and a map function. This map
160 function is then called for each item in the sequence, and a new sequence
161 containing the return values from the map function is returned.
162
163 The map function must be of the form:
164
165 \snippet code/src_concurrent_qtconcurrentmap.cpp 0
166
167 T and U can be any type (and they can even be the same type), but T must
168 match the type stored in the sequence. The function returns the modified
169 or \e mapped content.
170
171 This example shows how to apply a scale function to all the items
172 in a sequence:
173
174 \snippet code/src_concurrent_qtconcurrentmap.cpp 1
175
176 The results of the map are made available through QFuture. See the
177 QFuture and QFutureWatcher documentation for more information on how to
178 use QFuture in your applications.
179
180 If you want to modify a sequence in-place, use QtConcurrent::map(). The
181 map function must then be of the form:
182
183 \snippet code/src_concurrent_qtconcurrentmap.cpp 2
184
185 Note that the return value and return type of the map function are not
186 used.
187
188 Using QtConcurrent::map() is similar to using QtConcurrent::mapped():
189
190 \snippet code/src_concurrent_qtconcurrentmap.cpp 3
191
192 Since the sequence is modified in place, QtConcurrent::map() does not
193 return any results via QFuture. However, you can still use QFuture and
194 QFutureWatcher to monitor the status of the map.
195
196 \section1 Concurrent Map-Reduce
197
198 QtConcurrent::mappedReduced() is similar to QtConcurrent::mapped(), but
199 instead of returning a sequence with the new results, the results are
200 combined into a single value using a reduce function.
201
202 The reduce function must be of the form:
203
204 \snippet code/src_concurrent_qtconcurrentmap.cpp 4
205
206 T is the type of the final result, U is the return type of the map
207 function. Note that the return value and return type of the reduce
208 function are not used.
209
210 Call QtConcurrent::mappedReduced() like this:
211
212 \snippet code/src_concurrent_qtconcurrentmap.cpp 5
213
214 The reduce function will be called once for each result returned by the map
215 function, and should merge the \e{intermediate} into the \e{result}
216 variable. QtConcurrent::mappedReduced() guarantees that only one thread
217 will call reduce at a time, so using a mutex to lock the result variable
218 is not necessary. The QtConcurrent::ReduceOptions enum provides a way to
219 control the order in which the reduction is done. If
220 QtConcurrent::UnorderedReduce is used (the default), the order is
221 undefined, while QtConcurrent::OrderedReduce ensures that the reduction
222 is done in the order of the original sequence.
223
224 \section1 Additional API Features
225
226 \section2 Using Iterators instead of Sequence
227
228 Each of the above functions has a variant that takes an iterator range
229 instead of a sequence. You use them in the same way as the sequence
230 variants:
231
232 \snippet code/src_concurrent_qtconcurrentmap.cpp 6
233
234 \section2 Blocking Variants
235
236 Each of the above functions has a blocking variant that returns
237 the final result instead of a QFuture. You use them in the same
238 way as the asynchronous variants.
239
240 \snippet code/src_concurrent_qtconcurrentmap.cpp 7
241
242 Note that the result types above are not QFuture objects, but real result
243 types (in this case, QList<QImage> and QImage).
244
245 \section2 Using Member Functions
246
247 QtConcurrent::map(), QtConcurrent::mapped(), and
248 QtConcurrent::mappedReduced() accept pointers to member functions.
249 The member function class type must match the type stored in the sequence:
250
251 \snippet code/src_concurrent_qtconcurrentmap.cpp 8
252
253 Note that when using QtConcurrent::mappedReduced(), you can mix the use of
254 normal and member functions freely:
255
256 \snippet code/src_concurrent_qtconcurrentmap.cpp 9
257
258 \section2 Using Function Objects
259
260 QtConcurrent::map(), QtConcurrent::mapped(), and
261 QtConcurrent::mappedReduced() accept function objects
262 for the map function. These function objects can be used to
263 add state to a function call. The result_type typedef must define the
264 result type of the function call operator:
265
266 \snippet code/src_concurrent_qtconcurrentmap.cpp 14
267
268 For the reduce function, function objects are not directly
269 supported. Function objects can, however, be used
270 when the type of the reduction result is explicitly specified:
271
272 \snippet code/src_concurrent_qtconcurrentmap.cpp 11
273
274 \section2 Wrapping Functions that Take Multiple Arguments
275
276 If you want to use a map function that takes more than one argument you can
277 use a lambda function or \c std::bind() to transform it onto a function that
278 takes one argument.
279
280 As an example, we'll use QImage::scaledToWidth():
281
282 \snippet code/src_concurrent_qtconcurrentmap.cpp 10
283
284 scaledToWidth takes three arguments (including the "this" pointer) and
285 can't be used with QtConcurrent::mapped() directly, because
286 QtConcurrent::mapped() expects a function that takes one argument. To use
287 QImage::scaledToWidth() with QtConcurrent::mapped() we have to provide a
288 value for the \e{width} and the \e{transformation mode}:
289
290 \snippet code/src_concurrent_qtconcurrentmap.cpp 13
291*/
292
293/*!
294 \fn template <typename Sequence, typename MapFunctor> QFuture<void> QtConcurrent::map(Sequence &sequence, MapFunctor function)
295
296 Calls \a function once for each item in \a sequence. The \a function is
297 passed a reference to the item, so that any modifications done to the item
298 will appear in \a sequence.
299
300 \sa {Concurrent Map and Map-Reduce}
301*/
302
303/*!
304 \fn template <typename Iterator, typename MapFunctor> QFuture<void> QtConcurrent::map(Iterator begin, Iterator end, MapFunctor function)
305
306 Calls \a function once for each item from \a begin to \a end. The
307 \a function is passed a reference to the item, so that any modifications
308 done to the item will appear in the sequence which the iterators belong to.
309
310 \sa {Concurrent Map and Map-Reduce}
311*/
312
313/*!
314 \fn template <typename Sequence, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(const Sequence &sequence, MapFunctor function)
315
316 Calls \a function once for each item in \a sequence and returns a future
317 with each mapped item as a result. You can use QFuture::const_iterator or
318 QFutureIterator to iterate through the results.
319
320 \sa {Concurrent Map and Map-Reduce}
321*/
322
323/*!
324 \fn template <typename Iterator, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(Iterator begin, Iterator end, MapFunctor function)
325
326 Calls \a function once for each item from \a begin to \a end and returns a
327 future with each mapped item as a result. You can use
328 QFuture::const_iterator or QFutureIterator to iterate through the results.
329
330 \sa {Concurrent Map and Map-Reduce}
331*/
332
333/*!
334 \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
335
336 Calls \a mapFunction once for each item in \a sequence. The return value of
337 each \a mapFunction is passed to \a reduceFunction.
338
339 Note that while \a mapFunction is called concurrently, only one thread at a
340 time will call \a reduceFunction. The order in which \a reduceFunction is
341 called is determined by \a reduceOptions.
342
343 \sa {Concurrent Map and Map-Reduce}
344*/
345
346/*!
347 \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> QtConcurrent::mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
348
349 Calls \a mapFunction once for each item from \a begin to \a end. The return
350 value of each \a mapFunction is passed to \a reduceFunction.
351
352 Note that while \a mapFunction is called concurrently, only one thread at a
353 time will call \a reduceFunction. By default, the order in which
354 \a reduceFunction is called is undefined.
355
356 \note QtConcurrent::OrderedReduce results in the ordered reduction.
357
358 \sa {Concurrent Map and Map-Reduce}
359*/
360
361/*!
362 \fn template <typename Sequence, typename MapFunctor> void QtConcurrent::blockingMap(Sequence &sequence, MapFunctor function)
363
364 Calls \a function once for each item in \a sequence. The \a function is
365 passed a reference to the item, so that any modifications done to the item
366 will appear in \a sequence.
367
368 \note This function will block until all items in the sequence have been processed.
369
370 \sa map(), {Concurrent Map and Map-Reduce}
371*/
372
373/*!
374 \fn template <typename Iterator, typename MapFunctor> void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunctor function)
375
376 Calls \a function once for each item from \a begin to \a end. The
377 \a function is passed a reference to the item, so that any modifications
378 done to the item will appear in the sequence which the iterators belong to.
379
380 \note This function will block until the iterator reaches the end of the
381 sequence being processed.
382
383 \sa map(), {Concurrent Map and Map-Reduce}
384*/
385
386/*!
387 \fn template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence QtConcurrent::blockingMapped(const InputSequence &sequence, MapFunctor function)
388
389 Calls \a function once for each item in \a sequence and returns an OutputSequence containing
390 the results. The type of the results will match the type returned my the MapFunctor.
391
392 \note This function will block until all items in the sequence have been processed.
393
394 \sa mapped(), {Concurrent Map and Map-Reduce}
395*/
396
397/*!
398 \fn template <typename Sequence, typename Iterator, typename MapFunctor> Sequence QtConcurrent::blockingMapped(Iterator begin, Iterator end, MapFunctor function)
399
400 Calls \a function once for each item from \a begin to \a end and returns a
401 container with the results. Specify the type of container as the a template
402 argument, like this:
403
404 \code
405 QList<int> ints = QtConcurrent::blockingMapped<QList<int> >(beginIterator, endIterator, fn);
406 \endcode
407
408 \note This function will block until the iterator reaches the end of the
409 sequence being processed.
410
411 \sa mapped(), {Concurrent Map and Map-Reduce}
412*/
413
414/*!
415 \fn template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
416
417 Calls \a mapFunction once for each item in \a sequence. The return value of
418 each \a mapFunction is passed to \a reduceFunction.
419
420 Note that while \a mapFunction is called concurrently, only one thread at a
421 time will call \a reduceFunction. The order in which \a reduceFunction is
422 called is determined by \a reduceOptions.
423
424 \note This function will block until all items in the sequence have been processed.
425
426 \sa mapped(), {Concurrent Map and Map-Reduce}
427*/
428
429/*!
430 \fn template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType QtConcurrent::blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions)
431
432 Calls \a mapFunction once for each item from \a begin to \a end. The return
433 value of each \a mapFunction is passed to \a reduceFunction.
434
435 Note that while \a mapFunction is called concurrently, only one thread at a
436 time will call \a reduceFunction. The order in which \a reduceFunction is
437 called is undefined.
438
439 \note This function will block until the iterator reaches the end of the
440 sequence being processed.
441
442 \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce}
443*/
444
445/*!
446 \class QtConcurrent::FunctionWrapper0
447 \inmodule QtConcurrent
448 \internal
449*/
450
451/*!
452 \class QtConcurrent::FunctionWrapper1
453 \inmodule QtConcurrent
454 \internal
455*/
456
457/*!
458 \class QtConcurrent::FunctionWrapper2
459 \inmodule QtConcurrent
460 \internal
461*/
462
463/*!
464 \class QtConcurrent::MemberFunctionWrapper
465 \inmodule QtConcurrent
466 \internal
467*/
468
469/*!
470 \class QtConcurrent::MemberFunctionWrapper1
471 \inmodule QtConcurrent
472 \internal
473*/
474
475/*!
476 \class QtConcurrent::ConstMemberFunctionWrapper
477 \inmodule QtConcurrent
478 \internal
479*/
480

source code of qtbase/src/concurrent/qtconcurrentmap.cpp