Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-25 09:58:33

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
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 // map kernel, works with both parallel-for and parallel-while
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 //! [qtconcurrentmapkernel-1]
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 //! [qtconcurrentmapkernel-2]
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     The SequnceHolder class is used to hold a reference to the
0194     sequence we are working on.
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         // Clear the sequence to make sure all temporaries are destroyed
0209         // before finished is signaled.
0210         this->sequence = Sequence();
0211     }
0212 };
0213 
0214 //! [qtconcurrentmapkernel-3]
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 //! [qtconcurrentmapkernel-4]
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 //! [qtconcurrentmapkernel-5]
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 //! [qtconcurrentmapkernel-6]
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 //! [qtconcurrentmapkernel-7]
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 } // namespace QtConcurrent
0321 
0322 
0323 QT_END_NAMESPACE
0324 
0325 #endif // QT_NO_CONCURRENT
0326 
0327 #endif