summaryrefslogtreecommitdiffstats
path: root/src/concurrent/qtconcurrentmapkernel.h
blob: 61b18e5438196b17ba5ac7d87272c3e500225895 (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
// Copyright (C) 2016 The Qt Company Ltd.// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only#ifndef QTCONCURRENT_MAPKERNEL_H#define QTCONCURRENT_MAPKERNEL_H#include <QtConcurrent/qtconcurrent_global.h>#if !defined(QT_NO_CONCURRENT) || defined (Q_QDOC)#include <QtConcurrent/qtconcurrentiteratekernel.h>#include <QtConcurrent/qtconcurrentreducekernel.h>#include <QtConcurrent/qtconcurrentfunctionwrappers.h> QT_BEGIN_NAMESPACE namespace QtConcurrent {// map kernel, works with both parallel-for and parallel-whiletemplate<typename Iterator, typename MapFunctor>class MapKernel :public IterateKernel<Iterator,void>{ MapFunctor map;public:typedefvoid ReturnType;template<typename F = MapFunctor>MapKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map): IterateKernel<Iterator,void>(pool, begin, end),map(std::forward<F>(_map)){ }boolrunIteration(Iterator it,int,void*) override {std::invoke(map, *it);return false;}boolrunIterations(Iterator sequenceBeginIterator,int beginIndex,int endIndex,void*) override { Iterator it = sequenceBeginIterator;std::advance(it, beginIndex);for(int i = beginIndex; i < endIndex; ++i) {runIteration(it, i,nullptr);std::advance(it,1);}return false;}};template<typename ReducedResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor, typename Reducer = ReduceKernel<ReduceFunctor, ReducedResultType,QtPrivate::MapResultType<Iterator, MapFunctor>>>class MappedReducedKernel :public IterateKernel<Iterator, ReducedResultType>{ ReducedResultType &reducedResult; MapFunctor map; ReduceFunctor reduce; Reducer reducer;using IntermediateResultsType =QtPrivate::MapResultType<Iterator, MapFunctor>;public:typedef ReducedResultType ReturnType;template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce, ReduceOptions reduceOptions): IterateKernel<Iterator, ReducedResultType>(pool, begin, end),reducedResult(this->defaultValue.value),map(std::forward<F1>(_map)),reduce(std::forward<F2>(_reduce)),reducer(pool, reduceOptions){ }template<typename F1 = MapFunctor, typename F2 = ReduceFunctor>MappedReducedKernel(QThreadPool *pool, Iterator begin, Iterator end, F1 &&_map, F2 &&_reduce, ReducedResultType &&initialValue, ReduceOptions reduceOptions): IterateKernel<Iterator, ReducedResultType>(pool, begin, end,std::forward<ReducedResultType>(initialValue)),reducedResult(this->defaultValue.value),map(std::forward<F1>(_map)),reduce(std::forward<F2>(_reduce)),reducer(pool, reduceOptions){}boolrunIteration(Iterator it,int index, ReducedResultType *) override { IntermediateResults<IntermediateResultsType> results; results.begin = index; results.end = index +1; results.vector.append(std::invoke(map, *it)); reducer.runReduce(reduce, reducedResult, results);return false;}boolrunIterations(Iterator sequenceBeginIterator,int beginIndex,int endIndex, ReducedResultType *) override { IntermediateResults<IntermediateResultsType> results; results.begin = beginIndex; results.end = endIndex; results.vector.reserve(endIndex - beginIndex); Iterator it = sequenceBeginIterator;std::advance(it, beginIndex);for(int i = beginIndex; i < endIndex; ++i) { results.vector.append(std::invoke(map, *it));std::advance(it,1);} reducer.runReduce(reduce, reducedResult, results);return false;}voidfinish() override { reducer.finish(reduce, reducedResult);}boolshouldThrottleThread() override {return IterateKernel<Iterator, ReducedResultType>::shouldThrottleThread() || reducer.shouldThrottle();}boolshouldStartThread() override {return IterateKernel<Iterator, ReducedResultType>::shouldStartThread() && reducer.shouldStartThread();}typedef ReducedResultType ResultType; ReducedResultType *result() override {return&reducedResult;}};template<typename Iterator, typename MapFunctor>class MappedEachKernel :public IterateKernel<Iterator,QtPrivate::MapResultType<Iterator, MapFunctor>>{ MapFunctor map;using T =QtPrivate::MapResultType<Iterator, MapFunctor>;public:template<typename F = MapFunctor>MappedEachKernel(QThreadPool *pool, Iterator begin, Iterator end, F &&_map): IterateKernel<Iterator, T>(pool, begin, end),map(std::forward<F>(_map)){ }boolrunIteration(Iterator it,int, T *result) override {*result =std::invoke(map, *it);return true;}boolrunIterations(Iterator sequenceBeginIterator,int beginIndex,int endIndex, T *results) override { Iterator it = sequenceBeginIterator;std::advance(it, beginIndex);for(int i = beginIndex; i < endIndex; ++i) {runIteration(it, i, results + (i - beginIndex));std::advance(it,1);}return true;}};//! [qtconcurrentmapkernel-1]template<typename Iterator, typename Functor>inline ThreadEngineStarter<void>startMap(QThreadPool *pool, Iterator begin, Iterator end, Functor &&functor){returnstartThreadEngine(new MapKernel<Iterator,std::decay_t<Functor>>( pool, begin, end,std::forward<Functor>(functor)));}//! [qtconcurrentmapkernel-2]template<typename T, typename Iterator, typename Functor>inline ThreadEngineStarter<T>startMapped(QThreadPool *pool, Iterator begin, Iterator end, Functor &&functor){returnstartThreadEngine(new MappedEachKernel<Iterator,std::decay_t<Functor>>( pool, begin, end,std::forward<Functor>(functor)));}/* The SequnceHolder class is used to hold a reference to the sequence we are working on.*/template<typename Sequence, typename Base, typename Functor>struct SequenceHolder1 :private QtPrivate::SequenceHolder<Sequence>,public Base {template<typename S = Sequence, typename F = Functor>SequenceHolder1(QThreadPool *pool, S &&_sequence, F &&functor):QtPrivate::SequenceHolder<Sequence>(std::forward<S>(_sequence)),Base(pool,this->sequence.cbegin(),this->sequence.cend(),std::forward<F>(functor)){ }voidfinish() override {Base::finish();// Clear the sequence to make sure all temporaries are destroyed// before finished is signaled.this->sequence =Sequence();}};//! [qtconcurrentmapkernel-3]template<typename T, typename Sequence, typename Functor>inline ThreadEngineStarter<T>startMapped(QThreadPool *pool, Sequence &&sequence, Functor &&functor){using DecayedSequence =std::decay_t<Sequence>;using DecayedFunctor =std::decay_t<Functor>;using SequenceHolderType = SequenceHolder1< DecayedSequence, MappedEachKernel<typename DecayedSequence::const_iterator, DecayedFunctor>, DecayedFunctor>;returnstartThreadEngine(newSequenceHolderType(pool,std::forward<Sequence>(sequence),std::forward<Functor>(functor)));}//! [qtconcurrentmapkernel-4]template<typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>inline ThreadEngineStarter<ResultType>startMappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options){using DecayedSequence =std::decay_t<Sequence>;using DecayedMapFunctor =std::decay_t<MapFunctor>;using DecayedReduceFunctor =std::decay_t<ReduceFunctor>;using Iterator = typename DecayedSequence::const_iterator;using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor, DecayedReduceFunctor, Reducer>;using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor, DecayedReduceFunctor>;returnstartThreadEngine(newSequenceHolderType(pool,std::forward<Sequence>(sequence),std::forward<MapFunctor>(mapFunctor),std::forward<ReduceFunctor>(reduceFunctor), options));}//! [qtconcurrentmapkernel-5]template<typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>inline ThreadEngineStarter<ResultType>startMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ReduceOptions options){using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>,std::decay_t<ResultType>, IntermediateType>;using MappedReduceType = MappedReducedKernel<ResultType, Iterator,std::decay_t<MapFunctor>,std::decay_t<ReduceFunctor>, Reducer>;returnstartThreadEngine(newMappedReduceType(pool, begin, end,std::forward<MapFunctor>(mapFunctor),std::forward<ReduceFunctor>(reduceFunctor), options));}//! [qtconcurrentmapkernel-6]template<typename IntermediateType, typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>inline ThreadEngineStarter<ResultType>startMappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options){using DecayedSequence =std::decay_t<Sequence>;using DecayedMapFunctor =std::decay_t<MapFunctor>;using DecayedReduceFunctor =std::decay_t<ReduceFunctor>;using Iterator = typename DecayedSequence::const_iterator;using Reducer = ReduceKernel<DecayedReduceFunctor, ResultType, IntermediateType>;using MappedReduceType = MappedReducedKernel<ResultType, Iterator, DecayedMapFunctor, DecayedReduceFunctor, Reducer>;using SequenceHolderType = SequenceHolder2<DecayedSequence, MappedReduceType, DecayedMapFunctor, DecayedReduceFunctor>;returnstartThreadEngine(newSequenceHolderType(pool,std::forward<Sequence>(sequence),std::forward<MapFunctor>(mapFunctor),std::forward<ReduceFunctor>(reduceFunctor),std::forward<ResultType>(initialValue), options));}//! [qtconcurrentmapkernel-7]template<typename IntermediateType, typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>inline ThreadEngineStarter<ResultType>startMappedReduced(QThreadPool *pool, Iterator begin, Iterator end, MapFunctor &&mapFunctor, ReduceFunctor &&reduceFunctor, ResultType &&initialValue, ReduceOptions options){using Reducer = ReduceKernel<std::decay_t<ReduceFunctor>, ResultType, IntermediateType>;using MappedReduceType = MappedReducedKernel<ResultType, Iterator,std::decay_t<MapFunctor>,std::decay_t<ReduceFunctor>, Reducer>;returnstartThreadEngine(newMappedReduceType(pool, begin, end,std::forward<MapFunctor>(mapFunctor),std::forward<ReduceFunctor>(reduceFunctor),std::forward<ResultType>(initialValue), options));}}// namespace QtConcurrent QT_END_NAMESPACE #endif// QT_NO_CONCURRENT#endif
close