File indexing completed on 2025-12-25 09:58:33
0001
0002
0003
0004 #ifndef QTCONCURRENT_MAPKERNEL_H
0005 #define QTCONCURRENT_MAPKERNEL_H
0006
0007 #include <QtConcurrent/qtconcurrent_global.h>
0008
0009 #if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)
0010
0011 #include <QtConcurrent/qtconcurrentiteratekernel.h>
0012 #include <QtConcurrent/qtconcurrentreducekernel.h>
0013 #include <QtConcurrent/qtconcurrentfunctionwrappers.h>
0014
0015 QT_BEGIN_NAMESPACE
0016
0017
0018 namespace QtConcurrent {
0019
0020
0021 template <typename Iterator, typename MapFunctor>
0022 class MapKernel : public IterateKernel<Iterator, void>
0023 {
0024 MapFunctor map;
0025 public:
0026 typedef void ReturnType;
0027 template <typename F = MapFunctor>
0028 MapKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
0029 : IterateKernel<Iterator, void>(pool, begin, end), map(std::forward<F>(_map))
0030 { }
0031
0032 bool runIteration(Iterator it, int, void *) override
0033 {
0034 std::invoke(map, *it);
0035 return false;
0036 }
0037
0038 bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, void *) override
0039 {
0040 Iterator it = sequenceBeginIterator;
0041 std::advance(it, beginIndex);
0042 for (int i = beginIndex; i < endIndex; ++i) {
0043 runIteration(it, i, nullptr);
0044 std::advance(it, 1);
0045 }
0046
0047 return false;
0048 }
0049 };
0050
0051 template <typename ReducedResultType,
0052 typename Iterator,
0053 typename MapFunctor,
0054 typename ReduceFunctor,
0055 typename Reducer = ReduceKernel<ReduceFunctor,
0056 ReducedResultType,
0057 QtPrivate::MapResultType<Iterator, MapFunctor>>>
0058 class MappedReducedKernel : public IterateKernel<Iterator, ReducedResultType>
0059 {
0060 ReducedResultType &reducedResult;
0061 MapFunctor map;
0062 ReduceFunctor reduce;
0063 Reducer reducer;
0064 using IntermediateResultsType = QtPrivate::MapResultType<Iterator, MapFunctor>;
0065
0066 public:
0067 typedef ReducedResultType ReturnType;
0068
0069 template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
0070 MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
0071 ReduceOptions reduceOptions)
0072 : IterateKernel<Iterator, ReducedResultType>(pool, begin, end),
0073 reducedResult(this->defaultValue.value),
0074 map(std::forward<F1>(_map)),
0075 reduce(std::forward<F2>(_reduce)),
0076 reducer(pool, reduceOptions)
0077 { }
0078
0079 template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>
0080 MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce,
0081 ReducedResultType &&initialValue, ReduceOptions reduceOptions)
0082 : IterateKernel<Iterator, ReducedResultType>(pool, begin, end,
0083 std::forward<ReducedResultType>(initialValue)),
0084 reducedResult(this->defaultValue.value),
0085 map(std::forward<F1>(_map)),
0086 reduce(std::forward<F2>(_reduce)),
0087 reducer(pool, reduceOptions)
0088 {
0089 }
0090
0091 bool runIteration(Iterator it, int index, ReducedResultType *) override
0092 {
0093 IntermediateResults<IntermediateResultsType> results;
0094 results.begin = index;
0095 results.end = index + 1;
0096
0097 results.vector.append(std::invoke(map, *it));
0098 reducer.runReduce(reduce, reducedResult, results);
0099 return false;
0100 }
0101
0102 bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, ReducedResultType *) override
0103 {
0104 IntermediateResults<IntermediateResultsType> results;
0105 results.begin = beginIndex;
0106 results.end = endIndex;
0107 results.vector.reserve(endIndex - beginIndex);
0108
0109 Iterator it = sequenceBeginIterator;
0110 std::advance(it, beginIndex);
0111 for (int i = beginIndex; i < endIndex; ++i) {
0112 results.vector.append(std::invoke(map, *it));
0113 std::advance(it, 1);
0114 }
0115
0116 reducer.runReduce(reduce, reducedResult, results);
0117 return false;
0118 }
0119
0120 void finish() override
0121 {
0122 reducer.finish(reduce, reducedResult);
0123 }
0124
0125 bool shouldThrottleThread() override
0126 {
0127 return IterateKernel<Iterator, ReducedResultType>::shouldThrottleThread() || reducer.shouldThrottle();
0128 }
0129
0130 bool shouldStartThread() override
0131 {
0132 return IterateKernel<Iterator, ReducedResultType>::shouldStartThread() && reducer.shouldStartThread();
0133 }
0134
0135 typedef ReducedResultType ResultType;
0136 ReducedResultType *result() override
0137 {
0138 return &reducedResult;
0139 }
0140 };
0141
0142 template <typename Iterator, typename MapFunctor>
0143 class MappedEachKernel : public IterateKernel<Iterator, QtPrivate::MapResultType<Iterator, MapFunctor>>
0144 {
0145 MapFunctor map;
0146 using T = QtPrivate::MapResultType<Iterator, MapFunctor>;
0147
0148 public:
0149 template <typename F = MapFunctor>
0150 MappedEachKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map)
0151 : IterateKernel<Iterator, T>(pool, begin, end), map(std::forward<F>(_map))
0152 { }
0153
0154 bool runIteration(Iterator it, int, T *result) override
0155 {
0156 *result = std::invoke(map, *it);
0157 return true;
0158 }
0159
0160 bool runIterations(Iterator sequenceBeginIterator, int beginIndex, int endIndex, T *results) override
0161 {
0162
0163 Iterator it = sequenceBeginIterator;
0164 std::advance(it, beginIndex);
0165 for (int i = beginIndex; i < endIndex; ++i) {
0166 runIteration(it, i, results + (i - beginIndex));
0167 std::advance(it, 1);
0168 }
0169
0170 return true;
0171 }
0172 };
0173
0174
0175 template <typename Iterator, typename Functor>
0176 inline ThreadEngineStarter<void> startMap(QThreadPool *pool, Iterator begin,
0177 Iterator end, Functor &&functor)
0178 {
0179 return startThreadEngine(new MapKernel<Iterator, std::decay_t<Functor>>(
0180 pool, begin, end, std::forward<Functor>(functor)));
0181 }
0182
0183
0184 template <typename T, typename Iterator, typename Functor>
0185 inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Iterator begin,
0186 Iterator end, Functor &&functor)
0187 {
0188 return startThreadEngine(new MappedEachKernel<Iterator, std::decay_t<Functor>>(
0189 pool, begin, end, std::forward<Functor>(functor)));
0190 }
0191
0192
0193
0194
0195
0196 template <typename Sequence, typename Base, typename Functor>
0197 struct SequenceHolder1 : private QtPrivate::SequenceHolder<Sequence>, public Base
0198 {
0199 template<typename S = Sequence, typename F = Functor>
0200 SequenceHolder1(QThreadPool *pool, S &&_sequence, F &&functor)
0201 : QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),
0202 Base(pool, this->sequence.cbegin(), this->sequence.cend(), std::forward<F>(functor))
0203 { }
0204
0205 void finish() override
0206 {
0207 Base::finish();
0208
0209
0210 this->sequence = Sequence();
0211 }
0212 };
0213
0214
0215 template <typename T, typename Sequence, typename Functor>
0216 inline ThreadEngineStarter<T> startMapped(QThreadPool *pool, Sequence &&sequence,
0217 Functor &&functor)
0218 {
0219 using DecayedSequence = std::decay_t<Sequence>;
0220 using DecayedFunctor = std::decay_t<Functor>;
0221 using SequenceHolderType = SequenceHolder1<
0222 DecayedSequence,
0223 MappedEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
0224 DecayedFunctor>;
0225
0226 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
0227 std::forward<Functor>(functor)));
0228 }
0229
0230
0231 template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
0232 typename ReduceFunctor>
0233 inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
0234 Sequence &&sequence,
0235 MapFunctor &&mapFunctor,
0236 ReduceFunctor &&reduceFunctor,
0237 ReduceOptions options)
0238 {
0239 using DecayedSequence = std::decay_t<Sequence>;
0240 using DecayedMapFunctor = std::decay_t<MapFunctor>;
0241 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
0242 using Iterator = typename DecayedSequence::const_iterator;
0243 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
0244 using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
0245 DecayedReduceFunctor, Reducer>;
0246 using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
0247 DecayedReduceFunctor>;
0248 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
0249 std::forward<MapFunctor>(mapFunctor),
0250 std::forward<ReduceFunctor>(reduceFunctor),
0251 options));
0252 }
0253
0254
0255 template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
0256 typename ReduceFunctor>
0257 inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
0258 Iterator begin,
0259 Iterator end,
0260 MapFunctor &&mapFunctor,
0261 ReduceFunctor &&reduceFunctor,
0262 ReduceOptions options)
0263 {
0264 using Reducer =
0265 ReduceKernel<std::decay_t<ReduceFunctor>, std::decay_t<ResultType>, IntermediateType>;
0266 using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
0267 std::decay_t<ReduceFunctor>, Reducer>;
0268 return startThreadEngine(new MappedReduceType(pool, begin, end,
0269 std::forward<MapFunctor>(mapFunctor),
0270 std::forward<ReduceFunctor>(reduceFunctor),
0271 options));
0272 }
0273
0274
0275 template <typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor,
0276 typename ReduceFunctor>
0277 inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
0278 Sequence &&sequence,
0279 MapFunctor &&mapFunctor,
0280 ReduceFunctor &&reduceFunctor,
0281 ResultType &&initialValue,
0282 ReduceOptions options)
0283 {
0284 using DecayedSequence = std::decay_t<Sequence>;
0285 using DecayedMapFunctor = std::decay_t<MapFunctor>;
0286 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
0287 using Iterator = typename DecayedSequence::const_iterator;
0288 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;
0289 using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor,
0290 DecayedReduceFunctor, Reducer>;
0291 using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor,
0292 DecayedReduceFunctor>;
0293 return startThreadEngine(
0294 new SequenceHolderType(pool, std::forward<Sequence>(sequence),
0295 std::forward<MapFunctor>(mapFunctor),
0296 std::forward<ReduceFunctor>(reduceFunctor),
0297 std::forward<ResultType>(initialValue), options));
0298 }
0299
0300
0301 template <typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor,
0302 typename ReduceFunctor>
0303 inline ThreadEngineStarter<ResultType> startMappedReduced(QThreadPool *pool,
0304 Iterator begin,
0305 Iterator end,
0306 MapFunctor &&mapFunctor,
0307 ReduceFunctor &&reduceFunctor,
0308 ResultType &&initialValue,
0309 ReduceOptions options)
0310 {
0311 using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType, IntermediateType>;
0312 using MappedReduceType = MappedReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
0313 std::decay_t<ReduceFunctor>, Reducer>;
0314 return startThreadEngine(new MappedReduceType(pool, begin, end,
0315 std::forward<MapFunctor>(mapFunctor),
0316 std::forward<ReduceFunctor>(reduceFunctor),
0317 std::forward<ResultType>(initialValue), options));
0318 }
0319
0320 }
0321
0322
0323 QT_END_NAMESPACE
0324
0325 #endif
0326
0327 #endif