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 | |