diff options
Diffstat (limited to 'src/concurrent/qtconcurrentiteratekernel.h')
-rw-r--r-- | src/concurrent/qtconcurrentiteratekernel.h | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h index 6caae61816..30033e9c66 100644 --- a/src/concurrent/qtconcurrentiteratekernel.h +++ b/src/concurrent/qtconcurrentiteratekernel.h @@ -93,23 +93,22 @@ template <typename T> class ResultReporter { public: - ResultReporter(ThreadEngine<T> *_threadEngine) - :threadEngine(_threadEngine) + ResultReporter(ThreadEngine<T> *_threadEngine, T &_defaultValue) + : threadEngine(_threadEngine), defaultValue(_defaultValue) { - } void reserveSpace(int resultCount) { currentResultCount = resultCount; - vector.resize(qMax(resultCount, vector.count())); + resizeList(qMax(resultCount, vector.count())); } void reportResults(int begin) { const int useVectorThreshold = 4; // Tunable parameter. if (currentResultCount > useVectorThreshold) { - vector.resize(currentResultCount); + resizeList(currentResultCount); threadEngine->reportResults(vector, begin); } else { for (int i = 0; i < currentResultCount; ++i) @@ -125,6 +124,17 @@ public: int currentResultCount; ThreadEngine<T> *threadEngine; QList<T> vector; + +private: + void resizeList(qsizetype size) + { + if constexpr (std::is_default_constructible_v<T>) + vector.resize(size); + else + vector.resize(size, defaultValue); + } + + T &defaultValue; }; template <> @@ -137,6 +147,22 @@ public: inline void * getPointer() { return nullptr; } }; +template<typename T> +struct DefaultValueContainer +{ + template<typename U = T> + DefaultValueContainer(U &&_value) : value(std::forward<U>(_value)) + { + } + + T value; +}; + +template<> +struct DefaultValueContainer<void> +{ +}; + inline bool selectIteration(std::bidirectional_iterator_tag) { return false; // while @@ -160,11 +186,41 @@ class IterateKernel : public ThreadEngine<T> public: typedef T ResultType; + template<typename U = T, std::enable_if_t<std::is_same_v<U, void>, bool> = true> + IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end) + : ThreadEngine<U>(pool), + begin(_begin), + end(_end), + current(_begin), + iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0), + forIteration(selectIteration(IteratorCategory())), + progressReportingEnabled(true) + { + } + + template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true> IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end) - : ThreadEngine<T>(pool), begin(_begin), end(_end), current(_begin) - , iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0) - , forIteration(selectIteration(IteratorCategory())) - , progressReportingEnabled(true) + : ThreadEngine<U>(pool), + begin(_begin), + end(_end), + current(_begin), + iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0), + forIteration(selectIteration(IteratorCategory())), + progressReportingEnabled(true), + defaultValue(U()) + { + } + + template<typename U = T, std::enable_if_t<!std::is_same_v<U, void>, bool> = true> + IterateKernel(QThreadPool *pool, Iterator _begin, Iterator _end, U &&_defaultValue) + : ThreadEngine<U>(pool), + begin(_begin), + end(_end), + current(_begin), + iterationCount(selectIteration(IteratorCategory()) ? std::distance(_begin, _end) : 0), + forIteration(selectIteration(IteratorCategory())), + progressReportingEnabled(true), + defaultValue(std::forward<U>(_defaultValue)) { } @@ -199,7 +255,7 @@ public: ThreadFunctionResult forThreadFunction() { BlockSizeManager blockSizeManager(ThreadEngineBase::threadPool, iterationCount); - ResultReporter<T> resultReporter(this); + ResultReporter<T> resultReporter = createResultsReporter(); for(;;) { if (this->isCanceled()) @@ -252,7 +308,7 @@ public: if (iteratorThreads.testAndSetAcquire(0, 1) == false) return ThreadFinished; - ResultReporter<T> resultReporter(this); + ResultReporter<T> resultReporter = createResultsReporter(); resultReporter.reserveSpace(1); while (current != end) { @@ -283,6 +339,14 @@ public: return ThreadFinished; } +private: + ResultReporter<T> createResultsReporter() + { + if constexpr (!std::is_same_v<T, void>) + return ResultReporter<T>(this, defaultValue.value); + else + return ResultReporter<T>(this); + } public: const Iterator begin; @@ -294,6 +358,7 @@ public: const int iterationCount; const bool forIteration; bool progressReportingEnabled; + DefaultValueContainer<ResultType> defaultValue; }; } // namespace QtConcurrent |