File indexing completed on 2025-02-21 10:09:50
0001
0002
0003
0004 #ifndef QTCONCURRENT_FILTERKERNEL_H
0005 #define QTCONCURRENT_FILTERKERNEL_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/qtconcurrentmapkernel.h>
0013 #include <QtConcurrent/qtconcurrentreducekernel.h>
0014
0015 QT_BEGIN_NAMESPACE
0016
0017
0018
0019 namespace QtConcurrent {
0020
0021 template <typename T>
0022 struct qValueType
0023 {
0024 typedef typename T::value_type value_type;
0025 };
0026
0027 template <typename T>
0028 struct qValueType<const T*>
0029 {
0030 typedef T value_type;
0031 };
0032
0033 template <typename T>
0034 struct qValueType<T*>
0035 {
0036 typedef T value_type;
0037 };
0038
0039
0040 template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
0041 class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
0042 {
0043 typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
0044 typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
0045 typedef void T;
0046
0047 Sequence reducedResult;
0048 Sequence &sequence;
0049 KeepFunctor keep;
0050 ReduceFunctor reduce;
0051 Reducer reducer;
0052
0053 public:
0054 template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
0055 FilterKernel(QThreadPool *pool, Sequence &_sequence, Keep &&_keep, Reduce &&_reduce)
0056 : IterateKernelType(pool, const_cast<const Sequence &>(_sequence).begin(),
0057 const_cast<const Sequence &>(_sequence).end()), reducedResult(),
0058 sequence(_sequence),
0059 keep(std::forward<Keep>(_keep)),
0060 reduce(std::forward<Reduce>(_reduce)),
0061 reducer(pool, OrderedReduce)
0062 { }
0063
0064 bool runIteration(typename Sequence::const_iterator it, int index, T *) override
0065 {
0066 IntermediateResults<typename Sequence::value_type> results;
0067 results.begin = index;
0068 results.end = index + 1;
0069
0070 if (std::invoke(keep, *it))
0071 results.vector.append(*it);
0072
0073 reducer.runReduce(reduce, reducedResult, results);
0074 return false;
0075 }
0076
0077 bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *) override
0078 {
0079 IntermediateResults<typename Sequence::value_type> results;
0080 results.begin = begin;
0081 results.end = end;
0082 results.vector.reserve(end - begin);
0083
0084
0085 typename Sequence::const_iterator it = sequenceBeginIterator;
0086 std::advance(it, begin);
0087 for (int i = begin; i < end; ++i) {
0088 if (std::invoke(keep, *it))
0089 results.vector.append(*it);
0090 std::advance(it, 1);
0091 }
0092
0093 reducer.runReduce(reduce, reducedResult, results);
0094 return false;
0095 }
0096
0097 void finish() override
0098 {
0099 reducer.finish(reduce, reducedResult);
0100 sequence = std::move(reducedResult);
0101 }
0102
0103 inline bool shouldThrottleThread() override
0104 {
0105 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
0106 }
0107
0108 inline bool shouldStartThread() override
0109 {
0110 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
0111 }
0112
0113 typedef void ReturnType;
0114 typedef void ResultType;
0115 };
0116
0117
0118 template <typename ReducedResultType,
0119 typename Iterator,
0120 typename KeepFunctor,
0121 typename ReduceFunctor,
0122 typename Reducer = ReduceKernel<ReduceFunctor,
0123 ReducedResultType,
0124 typename qValueType<Iterator>::value_type> >
0125 class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
0126 {
0127 ReducedResultType &reducedResult;
0128 KeepFunctor keep;
0129 ReduceFunctor reduce;
0130 Reducer reducer;
0131 typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
0132
0133 public:
0134 template<typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
0135 FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
0136 Reduce &&_reduce, ReduceOptions reduceOption)
0137 : IterateKernelType(pool, begin, end),
0138 reducedResult(this->defaultValue.value),
0139 keep(std::forward<Keep>(_keep)),
0140 reduce(std::forward<Reduce>(_reduce)),
0141 reducer(pool, reduceOption)
0142 { }
0143
0144 template <typename Keep = KeepFunctor, typename Reduce = ReduceFunctor>
0145 FilteredReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep,
0146 Reduce &&_reduce, ReducedResultType &&initialValue,
0147 ReduceOptions reduceOption)
0148 : IterateKernelType(pool, begin, end, std::forward<ReducedResultType>(initialValue)),
0149 reducedResult(this->defaultValue.value),
0150 keep(std::forward<Keep>(_keep)),
0151 reduce(std::forward<Reduce>(_reduce)),
0152 reducer(pool, reduceOption)
0153 {
0154 }
0155
0156 bool runIteration(Iterator it, int index, ReducedResultType *) override
0157 {
0158 IntermediateResults<typename qValueType<Iterator>::value_type> results;
0159 results.begin = index;
0160 results.end = index + 1;
0161
0162 if (std::invoke(keep, *it))
0163 results.vector.append(*it);
0164
0165 reducer.runReduce(reduce, reducedResult, results);
0166 return false;
0167 }
0168
0169 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *) override
0170 {
0171 IntermediateResults<typename qValueType<Iterator>::value_type> results;
0172 results.begin = begin;
0173 results.end = end;
0174 results.vector.reserve(end - begin);
0175
0176 Iterator it = sequenceBeginIterator;
0177 std::advance(it, begin);
0178 for (int i = begin; i < end; ++i) {
0179 if (std::invoke(keep, *it))
0180 results.vector.append(*it);
0181 std::advance(it, 1);
0182 }
0183
0184 reducer.runReduce(reduce, reducedResult, results);
0185 return false;
0186 }
0187
0188 void finish() override
0189 {
0190 reducer.finish(reduce, reducedResult);
0191 }
0192
0193 inline bool shouldThrottleThread() override
0194 {
0195 return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
0196 }
0197
0198 inline bool shouldStartThread() override
0199 {
0200 return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
0201 }
0202
0203 typedef ReducedResultType ReturnType;
0204 typedef ReducedResultType ResultType;
0205 ReducedResultType *result() override
0206 {
0207 return &reducedResult;
0208 }
0209 };
0210
0211
0212 template <typename Iterator, typename KeepFunctor>
0213 class FilteredEachKernel : public IterateKernel<Iterator, typename qValueType<Iterator>::value_type>
0214 {
0215 typedef typename qValueType<Iterator>::value_type T;
0216 typedef IterateKernel<Iterator, T> IterateKernelType;
0217
0218 KeepFunctor keep;
0219
0220 public:
0221 typedef T ReturnType;
0222 typedef T ResultType;
0223
0224 template <typename Keep = KeepFunctor>
0225 FilteredEachKernel(QThreadPool *pool, Iterator begin, Iterator end, Keep &&_keep)
0226 : IterateKernelType(pool, begin, end), keep(std::forward<Keep>(_keep))
0227 { }
0228
0229 void start() override
0230 {
0231 if (this->futureInterface)
0232 this->futureInterface->setFilterMode(true);
0233 IterateKernelType::start();
0234 }
0235
0236 bool runIteration(Iterator it, int index, T *) override
0237 {
0238 if (std::invoke(keep, *it))
0239 this->reportResult(&(*it), index);
0240 else
0241 this->reportResult(nullptr, index);
0242 return false;
0243 }
0244
0245 bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *) override
0246 {
0247 const int count = end - begin;
0248 IntermediateResults<typename qValueType<Iterator>::value_type> results;
0249 results.begin = begin;
0250 results.end = end;
0251 results.vector.reserve(count);
0252
0253 Iterator it = sequenceBeginIterator;
0254 std::advance(it, begin);
0255 for (int i = begin; i < end; ++i) {
0256 if (std::invoke(keep, *it))
0257 results.vector.append(*it);
0258 std::advance(it, 1);
0259 }
0260
0261 this->reportResults(results.vector, begin, count);
0262 return false;
0263 }
0264 };
0265
0266
0267 template <typename Iterator, typename KeepFunctor>
0268 inline
0269 ThreadEngineStarter<typename qValueType<Iterator>::value_type>
0270 startFiltered(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&functor)
0271 {
0272 return startThreadEngine(new FilteredEachKernel<Iterator, std::decay_t<KeepFunctor>>
0273 (pool, begin, end, std::forward<KeepFunctor>(functor)));
0274 }
0275
0276
0277 template <typename Sequence, typename KeepFunctor>
0278 inline decltype(auto) startFiltered(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&functor)
0279 {
0280 using DecayedSequence = std::decay_t<Sequence>;
0281 using DecayedFunctor = std::decay_t<KeepFunctor>;
0282 using SequenceHolderType = SequenceHolder1<DecayedSequence,
0283 FilteredEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>,
0284 DecayedFunctor>;
0285 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
0286 std::forward<KeepFunctor>(functor)));
0287 }
0288
0289
0290 template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
0291 inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
0292 Sequence &&sequence,
0293 MapFunctor &&mapFunctor,
0294 ReduceFunctor &&reduceFunctor,
0295 ReduceOptions options)
0296 {
0297 using DecayedSequence = std::decay_t<Sequence>;
0298 using DecayedMapFunctor = std::decay_t<MapFunctor>;
0299 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
0300 using Iterator = typename DecayedSequence::const_iterator;
0301 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
0302 typename qValueType<Iterator>::value_type>;
0303 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
0304 DecayedReduceFunctor, Reducer>;
0305 using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
0306 DecayedMapFunctor, DecayedReduceFunctor>;
0307 return startThreadEngine(new SequenceHolderType(pool, std::forward<Sequence>(sequence),
0308 std::forward<MapFunctor>(mapFunctor),
0309 std::forward<ReduceFunctor>(reduceFunctor),
0310 options));
0311 }
0312
0313
0314
0315 template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
0316 inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
0317 Iterator begin,
0318 Iterator end,
0319 MapFunctor &&mapFunctor,
0320 ReduceFunctor &&reduceFunctor,
0321 ReduceOptions options)
0322 {
0323 using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
0324 typename qValueType<Iterator>::value_type>;
0325 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
0326 std::decay_t<ReduceFunctor>, Reducer>;
0327 return startThreadEngine(
0328 new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
0329 std::forward<ReduceFunctor>(reduceFunctor), options));
0330 }
0331
0332
0333
0334 template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
0335 inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
0336 Sequence &&sequence,
0337 MapFunctor &&mapFunctor,
0338 ReduceFunctor &&reduceFunctor,
0339 ResultType &&initialValue,
0340 ReduceOptions options)
0341 {
0342 using DecayedSequence = std::decay_t<Sequence>;
0343 using DecayedMapFunctor = std::decay_t<MapFunctor>;
0344 using DecayedReduceFunctor = std::decay_t<ReduceFunctor>;
0345 using Iterator = typename DecayedSequence::const_iterator;
0346 using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType,
0347 typename qValueType<Iterator>::value_type>;
0348 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, DecayedMapFunctor,
0349 DecayedReduceFunctor, Reducer>;
0350 using SequenceHolderType = SequenceHolder2<DecayedSequence, FilteredReduceType,
0351 DecayedMapFunctor, DecayedReduceFunctor>;
0352 return startThreadEngine(new SequenceHolderType(
0353 pool, std::forward<Sequence>(sequence), std::forward<MapFunctor>(mapFunctor),
0354 std::forward<ReduceFunctor>(reduceFunctor), std::forward<ResultType>(initialValue),
0355 options));
0356 }
0357
0358
0359 template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
0360 inline ThreadEngineStarter<ResultType> startFilteredReduced(QThreadPool *pool,
0361 Iterator begin,
0362 Iterator end,
0363 MapFunctor &&mapFunctor,
0364 ReduceFunctor &&reduceFunctor,
0365 ResultType &&initialValue,
0366 ReduceOptions options)
0367 {
0368 using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType,
0369 typename qValueType<Iterator>::value_type>;
0370 using FilteredReduceType = FilteredReducedKernel<ResultType, Iterator, std::decay_t<MapFunctor>,
0371 std::decay_t<ReduceFunctor>, Reducer>;
0372 return startThreadEngine(
0373 new FilteredReduceType(pool, begin, end, std::forward<MapFunctor>(mapFunctor),
0374 std::forward<ReduceFunctor>(reduceFunctor),
0375 std::forward<ResultType>(initialValue), options));
0376 }
0377
0378
0379 }
0380
0381
0382 QT_END_NAMESPACE
0383
0384 #endif
0385
0386 #endif