From 1cbd41790691c880794a07ec7b0a192d6cb0e7d8 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 24 May 2023 18:06:54 +0200 Subject: [PATCH] Utils: Remove functiontraits.h, mapreduce.h and runextensions.h Change-Id: I61d0f95d4120c0de0045c1a817fd13a09eeb5402 Reviewed-by: Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot --- src/libs/utils/CMakeLists.txt | 4 - src/libs/utils/QtConcurrentTools | 4 - src/libs/utils/functiontraits.h | 169 ----- src/libs/utils/mapreduce.h | 594 ------------------ src/libs/utils/runextensions.cpp | 23 - src/libs/utils/runextensions.h | 479 -------------- src/libs/utils/utils.qbs | 5 - src/plugins/projectexplorer/buildstep.cpp | 2 +- .../qmakeprojectmanager/qmakeparsernodes.cpp | 1 - tests/auto/CMakeLists.txt | 2 - tests/auto/auto.qbs | 1 - tests/auto/mapreduce/CMakeLists.txt | 4 - tests/auto/mapreduce/mapreduce.qbs | 10 - tests/auto/mapreduce/tst_mapreduce.cpp | 345 ---------- tests/auto/runextensions/CMakeLists.txt | 4 - tests/auto/runextensions/runextensions.qbs | 10 - .../auto/runextensions/tst_runextensions.cpp | 540 ---------------- 17 files changed, 1 insertion(+), 2196 deletions(-) delete mode 100644 src/libs/utils/QtConcurrentTools delete mode 100644 src/libs/utils/functiontraits.h delete mode 100644 src/libs/utils/mapreduce.h delete mode 100644 src/libs/utils/runextensions.cpp delete mode 100644 src/libs/utils/runextensions.h delete mode 100644 tests/auto/mapreduce/CMakeLists.txt delete mode 100644 tests/auto/mapreduce/mapreduce.qbs delete mode 100644 tests/auto/mapreduce/tst_mapreduce.cpp delete mode 100644 tests/auto/runextensions/CMakeLists.txt delete mode 100644 tests/auto/runextensions/runextensions.qbs delete mode 100644 tests/auto/runextensions/tst_runextensions.cpp diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 883727de72d..1e9affd09fd 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -6,7 +6,6 @@ add_qtc_library(Utils SOURCES ../3rdparty/span/span.hpp ../3rdparty/tl_expected/include/tl/expected.hpp - QtConcurrentTools algorithm.h ansiescapecodehandler.cpp ansiescapecodehandler.h appinfo.cpp appinfo.h @@ -66,7 +65,6 @@ add_qtc_library(Utils flowlayout.cpp flowlayout.h fsengine/fsengine.cpp fsengine/fsengine.h fsengine/fileiconprovider.cpp fsengine/fileiconprovider.h - functiontraits.h futuresynchronizer.cpp futuresynchronizer.h fuzzymatcher.cpp fuzzymatcher.h genericconstants.h @@ -93,7 +91,6 @@ add_qtc_library(Utils listmodel.h listutils.h macroexpander.cpp macroexpander.h - mapreduce.h mathutils.cpp mathutils.h mimeutils.h minimizableinfobars.cpp @@ -143,7 +140,6 @@ add_qtc_library(Utils ranges.h reloadpromptutils.cpp reloadpromptutils.h removefiledialog.cpp removefiledialog.h - runextensions.cpp runextensions.h savefile.cpp savefile.h scopedswap.h scopedtimer.cpp scopedtimer.h diff --git a/src/libs/utils/QtConcurrentTools b/src/libs/utils/QtConcurrentTools deleted file mode 100644 index bbec0a89f09..00000000000 --- a/src/libs/utils/QtConcurrentTools +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "runextensions.h" diff --git a/src/libs/utils/functiontraits.h b/src/libs/utils/functiontraits.h deleted file mode 100644 index 8b052d3e882..00000000000 --- a/src/libs/utils/functiontraits.h +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Utils { - -/* - struct functionTraits - { - using ResultType; // Return type of Function - struct argument - { - using type; // type of Function argument at index (starting with 0) - } - } - - struct functionTakesArgument; - - Is derived from std::true_type if Function takes an argument of type ArgumentType at index. - Otherwise derived from std::false_type. -*/ - -//////////////////// -// functionTraits -//////////////////// - -// for callables. defined below. -template -struct functionTraits; - -// function -template -struct functionTraits -{ - using ResultType = Result; - static const unsigned arity = sizeof...(Args); // TODO const -> constexpr with MSVC2015 - - template - struct argument - { - using type = typename std::tuple_element>::type; - }; -}; - -// function pointer -template -struct functionTraits : public functionTraits -{ -}; - -// const function pointer -template -struct functionTraits : public functionTraits -{ -}; - -// member function -template -struct functionTraits : public functionTraits -{ -}; - -// const member function -template -struct functionTraits : public functionTraits -{ -}; - -// const pointer to member function -template -struct functionTraits : public functionTraits -{ -}; - -// const pointer to const member function -template -struct functionTraits : public functionTraits -{ -}; - -// TODO: enable lvalue and rvalue ref member function later (MSVC 2015?) -//// lvalue ref member function -//template -//struct functionTraits : public functionTraits -//{ -//}; - -//// const lvalue ref member function -//template -//struct functionTraits : public functionTraits -//{ -//}; - -//// rvalue ref member function -//template -//struct functionTraits : public functionTraits -//{ -//}; - -// callables. only works if operator() is not overloaded. -template -struct functionTraits -{ - using callableTraits = functionTraits; - using ResultType = typename callableTraits::ResultType; - static const unsigned arity = callableTraits::arity - 1; // ignore object pointer arg // TODO const -> constexpr with MSVC2015 - - template - struct argument - { - using type = typename callableTraits::template argument::type; // ignore object pointer arg - }; -}; - -// lvalue ref callables -template -struct functionTraits : public functionTraits -{ -}; - -// const lvalue ref callables -template -struct functionTraits : public functionTraits -{ -}; - -// rvalue ref callables -template -struct functionTraits : public functionTraits -{ -}; - -template -using functionResult_t = typename functionTraits::ResultType; - -//////////////////// -// functionTakesArgument -//////////////////// -namespace Internal { - -template -struct functionTakesArgumentArityDispatch; - -template -struct functionTakesArgumentArityDispatch - : public std::false_type -{ -}; - -template -struct functionTakesArgumentArityDispatch - : public std::is_same::template argument::type> -{ -}; - -} // Internal - -template -struct functionTakesArgument : public Internal::functionTakesArgumentArityDispatch< - std::integral_constant::arity > index)>, - Function, index, T> -{ -}; - -} // Utils diff --git a/src/libs/utils/mapreduce.h b/src/libs/utils/mapreduce.h deleted file mode 100644 index 891f0083c52..00000000000 --- a/src/libs/utils/mapreduce.h +++ /dev/null @@ -1,594 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "utils_global.h" - -#include "algorithm.h" -#include "runextensions.h" - -#include - -#include - -namespace Utils { - -enum class MapReduceOption -{ - Ordered, - Unordered -}; - -namespace Internal { - -class QTCREATOR_UTILS_EXPORT MapReduceObject : public QObject -{ - Q_OBJECT -}; - -template -class MapReduceBase : public MapReduceObject -{ -protected: - static const int MAX_PROGRESS = 1000000; - // either const or non-const reference wrapper for items from the iterator - using ItemReferenceWrapper = std::reference_wrapper< - std::remove_reference_t::reference>>; - -public: - MapReduceBase(QFutureInterface &futureInterface, ForwardIterator begin, ForwardIterator end, - MapFunction &&map, State &state, ReduceFunction &&reduce, - MapReduceOption option, QThreadPool *pool, int size) - : m_futureInterface(futureInterface), - m_iterator(begin), - m_end(end), - m_map(std::forward(map)), - m_state(state), - m_reduce(std::forward(reduce)), - m_threadPool(pool), - m_handleProgress(size >= 0), - m_size(size), - m_option(option) - { - if (!m_threadPool) - m_threadPool = new QThreadPool(this); - if (m_handleProgress) // progress is handled by us - m_futureInterface.setProgressRange(0, MAX_PROGRESS); - connect(&m_selfWatcher, &QFutureWatcher::canceled, - this, &MapReduceBase::cancelAll); - m_selfWatcher.setFuture(QFuture(futureInterface.future())); - } - - void exec() - { - // do not enter event loop for empty containers or if already canceled - if (!m_futureInterface.isCanceled() && schedule()) - m_loop.exec(); - } - -protected: - virtual void reduce(QFutureWatcher *watcher, int index) = 0; - - bool schedule() - { - bool didSchedule = false; - while (m_iterator != m_end - && m_mapWatcher.size() < std::max(m_threadPool->maxThreadCount(), 1)) { - didSchedule = true; - auto watcher = new QFutureWatcher(); - connect(watcher, &QFutureWatcher::finished, this, [this, watcher] { - mapFinished(watcher); - }); - if (m_handleProgress) { - connect(watcher, &QFutureWatcher::progressValueChanged, - this, &MapReduceBase::updateProgress); - connect(watcher, &QFutureWatcher::progressRangeChanged, - this, &MapReduceBase::updateProgress); - } - m_mapWatcher.append(watcher); - m_watcherIndex.append(m_currentIndex); - ++m_currentIndex; - watcher->setFuture(runAsync(m_threadPool, std::cref(m_map), - ItemReferenceWrapper(*m_iterator))); - ++m_iterator; - } - return didSchedule; - } - - void mapFinished(QFutureWatcher *watcher) - { - int index = m_mapWatcher.indexOf(watcher); - int watcherIndex = m_watcherIndex.at(index); - m_mapWatcher.removeAt(index); // remove so we can schedule next one - m_watcherIndex.removeAt(index); - bool didSchedule = false; - if (!m_futureInterface.isCanceled()) { - // first schedule the next map... - didSchedule = schedule(); - ++m_successfullyFinishedMapCount; - updateProgress(); - // ...then reduce - reduce(watcher, watcherIndex); - } - delete watcher; - if (!didSchedule && m_mapWatcher.isEmpty()) - m_loop.quit(); - } - - void updateProgress() - { - if (!m_handleProgress) // cannot compute progress - return; - if (m_size == 0 || m_successfullyFinishedMapCount == m_size) { - m_futureInterface.setProgressValue(MAX_PROGRESS); - return; - } - if (!m_futureInterface.isProgressUpdateNeeded()) - return; - const double progressPerMap = MAX_PROGRESS / double(m_size); - double progress = m_successfullyFinishedMapCount * progressPerMap; - for (const QFutureWatcher *watcher : std::as_const(m_mapWatcher)) { - if (watcher->progressMinimum() != watcher->progressMaximum()) { - const double range = watcher->progressMaximum() - watcher->progressMinimum(); - progress += (watcher->progressValue() - watcher->progressMinimum()) / range * progressPerMap; - } - } - m_futureInterface.setProgressValue(int(progress)); - } - - void cancelAll() - { - for (QFutureWatcher *watcher : std::as_const(m_mapWatcher)) - watcher->cancel(); - } - - QFutureWatcher m_selfWatcher; - QFutureInterface &m_futureInterface; - ForwardIterator m_iterator; - const ForwardIterator m_end; - MapFunction m_map; - State &m_state; - ReduceFunction m_reduce; - QEventLoop m_loop; - QThreadPool *m_threadPool; // for reusing threads - QList *> m_mapWatcher; - QList m_watcherIndex; - int m_currentIndex = 0; - const bool m_handleProgress; - const int m_size; - int m_successfullyFinishedMapCount = 0; - MapReduceOption m_option; -}; - -// non-void result of map function. -template -class MapReduce : public MapReduceBase -{ - using BaseType = MapReduceBase; -public: - MapReduce(QFutureInterface &futureInterface, ForwardIterator begin, ForwardIterator end, - MapFunction &&map, State &state, ReduceFunction &&reduce, MapReduceOption option, - QThreadPool *pool, int size) - : BaseType(futureInterface, begin, end, std::forward(map), state, - std::forward(reduce), option, pool, size) - { - } - -protected: - void reduce(QFutureWatcher *watcher, int index) override - { - if (BaseType::m_option == MapReduceOption::Unordered) { - reduceOne(watcher->future().results()); - } else { - if (m_nextIndex == index) { - // handle this result and all directly following - reduceOne(watcher->future().results()); - ++m_nextIndex; - while (!m_pendingResults.isEmpty() && m_pendingResults.firstKey() == m_nextIndex) { - reduceOne(m_pendingResults.take(m_nextIndex)); - ++m_nextIndex; - } - } else { - // add result to pending results - m_pendingResults.insert(index, watcher->future().results()); - } - } - } - -private: - void reduceOne(const QList &results) - { - const int resultCount = results.size(); - for (int i = 0; i < resultCount; ++i) { - Internal::runAsyncImpl(BaseType::m_futureInterface, BaseType::m_reduce, - BaseType::m_state, results.at(i)); - } - } - - QMap> m_pendingResults; - int m_nextIndex = 0; -}; - -// specialization for void result of map function. Reducing is a no-op. -template -class MapReduce : public MapReduceBase -{ - using BaseType = MapReduceBase; -public: - MapReduce(QFutureInterface &futureInterface, ForwardIterator begin, ForwardIterator end, - MapFunction &&map, State &state, ReduceFunction &&reduce, MapReduceOption option, - QThreadPool *pool, int size) - : BaseType(futureInterface, begin, end, std::forward(map), state, - std::forward(reduce), option, pool, size) - { - } - -protected: - void reduce(QFutureWatcher *, int) override - { - } - -}; - -template -functionResult_t -callWithMaybeFutureInterfaceDispatch(std::false_type, QFutureInterface &, - Function &&function, Args&&... args) -{ - return function(std::forward(args)...); -} - -template -functionResult_t -callWithMaybeFutureInterfaceDispatch(std::true_type, QFutureInterface &futureInterface, - Function &&function, Args&&... args) -{ - return function(futureInterface, std::forward(args)...); -} - -template -functionResult_t -callWithMaybeFutureInterface(QFutureInterface &futureInterface, - Function &&function, Args&&... args) -{ - return callWithMaybeFutureInterfaceDispatch( - functionTakesArgument&>(), - futureInterface, std::forward(function), std::forward(args)...); -} - -template -void blockingIteratorMapReduce(QFutureInterface &futureInterface, ForwardIterator begin, ForwardIterator end, - InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option, QThreadPool *pool, int size) -{ - auto state = callWithMaybeFutureInterface - (futureInterface, std::forward(init)); - MapReduce::type, MapFunction, decltype(state), ReduceResult, ReduceFunction> - mr(futureInterface, begin, end, std::forward(map), state, - std::forward(reduce), option, pool, size); - mr.exec(); - callWithMaybeFutureInterface&> - (futureInterface, std::forward(cleanup), state); -} - -template -void blockingContainerMapReduce(QFutureInterface &futureInterface, Container &&container, - InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option, QThreadPool *pool) -{ - blockingIteratorMapReduce(futureInterface, std::begin(container), std::end(container), - std::forward(init), std::forward(map), - std::forward(reduce), - std::forward(cleanup), - option, pool, static_cast(container.size())); -} - -template -void blockingContainerRefMapReduce(QFutureInterface &futureInterface, - std::reference_wrapper containerWrapper, - InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option, QThreadPool *pool) -{ - blockingContainerMapReduce(futureInterface, containerWrapper.get(), - std::forward(init), std::forward(map), - std::forward(reduce), - std::forward(cleanup), - option, pool); -} - -template -static void *dummyInit() { return nullptr; } - -// copies or moves state to member, and then moves it to the result of the call operator -template -struct StateWrapper { - using StateResult = std::decay_t; // State is const& or & for lvalues - StateWrapper(State &&state) : m_state(std::forward(state)) { } - StateResult operator()() - { - return std::move(m_state); // invalidates m_state - } - - StateResult m_state; -}; - -// copies or moves reduce function to member, calls the reduce function with state and mapped value -template -struct ReduceWrapper { - using Reduce = std::decay_t; - ReduceWrapper(ReduceFunction &&reduce) : m_reduce(std::forward(reduce)) { } - void operator()(QFutureInterface &, StateResult &state, const MapResult &mapResult) - { - m_reduce(state, mapResult); - } - - Reduce m_reduce; -}; - -template -struct DummyReduce { - MapResult operator()(void *, const MapResult &result) const { return result; } -}; -template <> -struct DummyReduce { - void operator()() const { } // needed for resultType with MSVC2013 -}; - -template -static void dummyCleanup(void *) { } - -template -static void cleanupReportingState(QFutureInterface &fi, StateResult &state) -{ - fi.reportResult(state); -} - -} // Internal - -template ::type> -QFuture -mapReduce(ForwardIterator begin, ForwardIterator end, InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, - int size = -1) -{ - return runAsync(priority, - Internal::blockingIteratorMapReduce< - ForwardIterator, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t>, - begin, end, std::forward(init), std::forward(map), - std::forward(reduce), std::forward(cleanup), - option, pool, size); -} - -/*! - Calls the map function on all items in \a container in parallel through Utils::runAsync. - - The reduce function is called in the mapReduce thread with each of the reported results from - the map function, in arbitrary order, but never in parallel. - It gets passed a reference to a user defined state object, and a result from the map function. - If it takes a QFutureInterface reference as its first argument, it can report results - for the mapReduce operation through that. Otherwise, any values returned by the reduce function - are reported as results of the mapReduce operation. - - The init function is called in the mapReduce thread before the actual mapping starts, - and must return the initial state object for the reduce function. It gets the QFutureInterface - of the mapReduce operation passed as an argument. - - The cleanup function is called in the mapReduce thread after all map and reduce calls have - finished, with the QFutureInterface of the mapReduce operation and the final state object - as arguments, and can be used to clean up any resources, or report a final result of the - mapReduce. - - Container - - StateType InitFunction(QFutureInterface&) - or - StateType InitFunction() - - void MapFunction(QFutureInterface&, const ItemType&) - or - MapResultType MapFunction(const ItempType&) - - void ReduceFunction(QFutureInterface&, StateType&, const MapResultType&) - or - ReduceResultType ReduceFunction(StateType&, const MapResultType&) - - void CleanUpFunction(QFutureInterface&, StateType&) - or - void CleanUpFunction(StateType&) - - Notes: - \list - \li Container can be a move-only type or a temporary. If it is a lvalue reference, it will - be copied to the mapReduce thread. You can avoid that by using - the version that takes iterators, or by using std::ref/cref to pass a reference_wrapper. - \li ItemType can be a move-only type, if the map function takes (const) references to ItemType. - \li StateType can be a move-only type. - \li The init, map, reduce and cleanup functions can be move-only types and are moved to the - mapReduce thread if they are rvalues. - \endlist - - */ -template ::type> -QFuture -mapReduce(Container &&container, InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return runAsync(priority, - Internal::blockingContainerMapReduce< - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t>, - std::forward(container), - std::forward(init), std::forward(map), - std::forward(reduce), std::forward(cleanup), - option, pool); -} - -template ::type> -QFuture -mapReduce(std::reference_wrapper containerWrapper, InitFunction &&init, MapFunction &&map, - ReduceFunction &&reduce, CleanUpFunction &&cleanup, - MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return runAsync(priority, - Internal::blockingContainerRefMapReduce< - Container, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t, - std::decay_t>, - containerWrapper, - std::forward(init), std::forward(map), - std::forward(reduce), std::forward(cleanup), - option, pool); -} - -template , // State = T& or const T& for lvalues, so decay that away - typename MapResult = typename Internal::resultType::type> -QFuture -mapReduce(ForwardIterator begin, ForwardIterator end, MapFunction &&map, State &&initialState, - ReduceFunction &&reduce, MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, - int size = -1) -{ - return mapReduce(begin, end, - Internal::StateWrapper(std::forward(initialState)), - std::forward(map), - Internal::ReduceWrapper(std::forward(reduce)), - &Internal::cleanupReportingState, - option, pool, priority, size); -} - -template , // State = T& or const T& for lvalues, so decay that away - typename MapResult = typename Internal::resultType::type> -QFuture -mapReduce(Container &&container, MapFunction &&map, State &&initialState, ReduceFunction &&reduce, - MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return mapReduce(std::forward(container), - Internal::StateWrapper(std::forward(initialState)), - std::forward(map), - Internal::ReduceWrapper(std::forward(reduce)), - &Internal::cleanupReportingState, - option, pool, priority); -} - -template , // State = T& or const T& for lvalues, so decay that away - typename MapResult = typename Internal::resultType::type> -Q_REQUIRED_RESULT -StateResult -mappedReduced(ForwardIterator begin, ForwardIterator end, MapFunction &&map, State &&initialState, - ReduceFunction &&reduce, MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, - int size = -1) -{ - return mapReduce(begin, end, - std::forward(map), std::forward(initialState), - std::forward(reduce), - option, pool, priority, size).result(); -} - -template , // State = T& or const T& for lvalues, so decay that away - typename MapResult = typename Internal::resultType::type> -Q_REQUIRED_RESULT -StateResult -mappedReduced(Container &&container, MapFunction &&map, State &&initialState, ReduceFunction &&reduce, - MapReduceOption option = MapReduceOption::Unordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return mapReduce(std::forward(container), std::forward(map), - std::forward(initialState), std::forward(reduce), - option, pool, priority).result(); -} - -template ::type> -QFuture -map(ForwardIterator begin, ForwardIterator end, MapFunction &&map, - MapReduceOption option = MapReduceOption::Ordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, - int size = -1) -{ - return mapReduce(begin, end, - &Internal::dummyInit, - std::forward(map), - Internal::DummyReduce(), - &Internal::dummyCleanup, - option, pool, priority, size); -} - -template ::type> -QFuture -map(Container &&container, MapFunction &&map, MapReduceOption option = MapReduceOption::Ordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return mapReduce(std::forward(container), - Internal::dummyInit, - std::forward(map), - Internal::DummyReduce(), - Internal::dummyCleanup, - option, pool, priority); -} - -template class ResultContainer, typename ForwardIterator, typename MapFunction, - typename MapResult = typename Internal::resultType::type> -Q_REQUIRED_RESULT -ResultContainer -mapped(ForwardIterator begin, ForwardIterator end, MapFunction &&mapFun, - MapReduceOption option = MapReduceOption::Ordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority, int size = -1) -{ - return Utils::transform(map(begin, end, - std::forward(mapFun), - option, pool, priority, size).results(), - [](const MapResult &r) { return r; }); -} - -template class ResultContainer, typename Container, typename MapFunction, - typename MapResult = typename Internal::resultType::type> -Q_REQUIRED_RESULT -ResultContainer -mapped(Container &&container, MapFunction &&mapFun, - MapReduceOption option = MapReduceOption::Ordered, - QThreadPool *pool = nullptr, QThread::Priority priority = QThread::InheritPriority) -{ - return Utils::transform(map(container, - std::forward(mapFun), - option, pool, priority).results(), - [](const MapResult &r) { return r; }); -} - -} // Utils diff --git a/src/libs/utils/runextensions.cpp b/src/libs/utils/runextensions.cpp deleted file mode 100644 index efcd73a643e..00000000000 --- a/src/libs/utils/runextensions.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "runextensions.h" - -namespace Utils { -namespace Internal { - -RunnableThread::RunnableThread(QRunnable *runnable, QObject *parent) - : QThread(parent), - m_runnable(runnable) -{ -} - -void RunnableThread::run() -{ - m_runnable->run(); - if (m_runnable->autoDelete()) - delete m_runnable; -} - -} // Internal -} // Utils diff --git a/src/libs/utils/runextensions.h b/src/libs/utils/runextensions.h deleted file mode 100644 index 6505b12a9cf..00000000000 --- a/src/libs/utils/runextensions.h +++ /dev/null @@ -1,479 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "utils_global.h" - -#include "functiontraits.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -// hasCallOperator & Co must be outside of any namespace -// because of internal compiler error with MSVC2015 Update 2 - -using testCallOperatorYes = char; -using testCallOperatorNo = struct { char foo[2]; }; - -template -static testCallOperatorYes testCallOperator(decltype(&C::operator())); - -template -static testCallOperatorNo testCallOperator(...); - -template -struct hasCallOperator -{ - static const bool value = (sizeof(testCallOperator(nullptr)) == sizeof(testCallOperatorYes)); -}; - -namespace Utils { - -namespace Internal { - -/* - resultType::type - - Returns the type of results that would be reported by a callable of type F - when called through the runAsync methods. I.e. the ResultType in - - void f(QFutureInterface &fi, ...) - ResultType f(...) - - Returns void if F is not callable, and if F is a callable that does not take - a QFutureInterface& as its first parameter and returns void. -*/ - -template -struct resultType; - -template -struct resultTypeWithArgument; - -template -struct resultTypeTakesArguments; - -template -struct resultTypeIsMemberFunction; - -template -struct resultTypeIsFunctionLike; - -template -struct resultTypeHasCallOperator; - -template -struct resultTypeWithArgument&> -{ - using type = ResultType; -}; - -template -struct resultTypeWithArgument -{ - using type = functionResult_t; -}; - -template -struct resultTypeTakesArguments - : public resultTypeWithArgument::template argument::type> -{ -}; - -template -struct resultTypeTakesArguments -{ - using type = functionResult_t; -}; - -template -struct resultTypeIsFunctionLike - : public resultTypeTakesArguments::arity > 0)> -{ -}; - -template -struct resultTypeIsMemberFunction - : public resultTypeTakesArguments::arity > 1)> -{ -}; - -template -struct resultTypeIsMemberFunction -{ - using type = void; -}; - -template -struct resultTypeIsFunctionLike - : public resultTypeIsMemberFunction::value> -{ -}; - -template -struct resultTypeHasCallOperator - : public resultTypeIsFunctionLike>>::value> -{ -}; - -template -struct resultTypeHasCallOperator - : public resultTypeTakesArguments::arity > 0)> -{ -}; - -template -struct resultType - : public resultTypeHasCallOperator::value> -{ -}; - -template -struct resultType : public resultType -{ -}; - -template -struct resultType : public resultType -{ -}; - -template -struct resultType : public resultType -{ -}; - -template -struct resultType> : public resultType -{ -}; -template -struct resultType> : public resultType -{ -}; - -/* - Callable object that wraps a member function pointer with the object it - will be called on. -*/ - -template -class MemberCallable; - -template -class MemberCallable -{ -public: - MemberCallable(Result(Obj::* function)(Args...) const, const Obj *obj) - : m_function(function), - m_obj(obj) - { - } - - Result operator()(Args&&... args) const - { - return ((*m_obj).*m_function)(std::forward(args)...); - } - -private: - Result(Obj::* m_function)(Args...) const; - const Obj *m_obj; -}; - -template -class MemberCallable -{ -public: - MemberCallable(Result(Obj::* function)(Args...), Obj *obj) - : m_function(function), - m_obj(obj) - { - } - - Result operator()(Args&&... args) const - { - return ((*m_obj).*m_function)(std::forward(args)...); - } - -private: - Result(Obj::* m_function)(Args...); - Obj *m_obj; -}; - -/* - Helper functions for runAsync that run in the started thread. -*/ - -// void function that does not take QFutureInterface -template -void runAsyncReturnVoidDispatch(std::true_type, QFutureInterface &, Function &&function, Args&&... args) -{ - function(std::forward(args)...); -} - -// non-void function that does not take QFutureInterface -template -void runAsyncReturnVoidDispatch(std::false_type, QFutureInterface &futureInterface, Function &&function, Args&&... args) -{ - futureInterface.reportResult(function(std::forward(args)...)); -} - -// function that takes QFutureInterface -template -void runAsyncQFutureInterfaceDispatch(std::true_type, QFutureInterface &futureInterface, Function &&function, Args&&... args) -{ - function(futureInterface, std::forward(args)...); -} - -// function that does not take QFutureInterface -template -void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface &futureInterface, Function &&function, Args&&... args) -{ - runAsyncReturnVoidDispatch(std::is_void>(), - futureInterface, std::forward(function), std::forward(args)...); -} - -// function, function pointer, or other callable object that is no member pointer -template >::value> - > -void runAsyncMemberDispatch(QFutureInterface &futureInterface, Function &&function, Args&&... args) -{ - runAsyncQFutureInterfaceDispatch(functionTakesArgument&>(), - futureInterface, std::forward(function), std::forward(args)...); -} - -// Function = member function -template >::value> - > -void runAsyncMemberDispatch(QFutureInterface &futureInterface, Function &&function, Obj &&obj, Args&&... args) -{ - // Wrap member function with object into callable - runAsyncImpl(futureInterface, - MemberCallable>(std::forward(function), std::forward(obj)), - std::forward(args)...); -} - -// cref to function/callable -template -void runAsyncImpl(QFutureInterface &futureInterface, - std::reference_wrapper functionWrapper, Args&&... args) -{ - runAsyncMemberDispatch(futureInterface, functionWrapper.get(), std::forward(args)...); -} - -// function/callable, no cref -template -void runAsyncImpl(QFutureInterface &futureInterface, - Function &&function, Args&&... args) -{ - runAsyncMemberDispatch(futureInterface, std::forward(function), - std::forward(args)...); -} -/* - AsyncJob is a QRunnable that wraps a function with the - arguments that are passed to it when it is run in a thread. -*/ - -template -std::decay_t -decayCopy(T&& v) -{ - return std::forward(v); -} - -template -class AsyncJob : public QRunnable -{ -public: - AsyncJob(Function &&function, Args&&... args) - // decay copy like std::thread - : data(decayCopy(std::forward(function)), decayCopy(std::forward(args))...) - { - // we need to report it as started even though it isn't yet, because someone might - // call waitForFinished on the future, which does _not_ block if the future is not started - futureInterface.setRunnable(this); - futureInterface.reportStarted(); - } - - ~AsyncJob() override - { - // QThreadPool can delete runnables even if they were never run (e.g. QThreadPool::clear). - // Since we reported them as started, we make sure that we always report them as finished. - // reportFinished only actually sends the signal if it wasn't already finished. - futureInterface.reportFinished(); - } - - QFuture future() { return futureInterface.future(); } - - void run() override - { - if (priority != QThread::InheritPriority) - if (QThread *thread = QThread::currentThread()) - if (thread != qApp->thread()) - thread->setPriority(priority); - if (futureInterface.isCanceled()) { - futureInterface.reportFinished(); - return; - } - runHelper(std::make_index_sequence::value>()); - } - - void setThreadPool(QThreadPool *pool) - { - futureInterface.setThreadPool(pool); - } - - void setThreadPriority(QThread::Priority p) - { - priority = p; - } - -private: - using Data = std::tuple, std::decay_t...>; - - template - void runHelper(std::index_sequence) - { - // invalidates data, which is moved into the call - runAsyncImpl(futureInterface, std::move(std::get(data))...); - if (futureInterface.isPaused()) - futureInterface.waitForResume(); - futureInterface.reportFinished(); - } - - Data data; - QFutureInterface futureInterface; - QThread::Priority priority = QThread::InheritPriority; -}; - -class QTCREATOR_UTILS_EXPORT RunnableThread : public QThread -{ -public: - explicit RunnableThread(QRunnable *runnable, QObject *parent = nullptr); - -protected: - void run() override; - -private: - QRunnable *m_runnable; -}; - -template::type> -QFuture runAsync_internal(QThreadPool *pool, - QThread::Priority priority, - Function &&function, - Args &&... args) -{ - auto job = new Internal::AsyncJob - (std::forward(function), std::forward(args)...); - job->setThreadPriority(priority); - QFuture future = job->future(); - if (pool) { - job->setThreadPool(pool); - pool->start(job); - } else { - auto thread = new Internal::RunnableThread(job); - thread->moveToThread(qApp->thread()); // make sure thread gets deleteLater on main thread - QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater); - thread->start(priority); - } - return future; -} - -} // Internal - -/*! - The interface of \c {runAsync} is similar to the std::thread constructor and \c {std::invoke}. - - The \a function argument can be a member function, - an object with \c {operator()} (with no overloads), - a \c {std::function}, lambda, function pointer or function reference. - The \a args are passed to the function call after they are copied/moved to the thread. - - The \a function can take a \c {QFutureInterface&} as its first argument, followed by - other custom arguments which need to be passed to this function. - If it does not take a \c {QFutureInterface&} as its first argument - and its return type is not void, the function call's result is reported to the QFuture. - If \a function is a (non-static) member function, the first argument in \a args is expected - to be the object that the function is called on. - - If a thread \a pool is given, the function is run there. Otherwise a new, independent thread - is started. - - \sa std::thread - \sa std::invoke - \sa QThreadPool - \sa QThread::Priority - */ -template ::type> -QFuture -runAsync(QThreadPool *pool, QThread::Priority priority, Function &&function, Args&&... args) -{ - return Internal::runAsync_internal(pool, - priority, - std::forward(function), - std::forward(args)...); -} - -/*! - Runs \a function with \a args in a new thread with given thread \a priority. - \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) - \sa QThread::Priority - */ -template ::type> -QFuture -runAsync(QThread::Priority priority, Function &&function, Args&&... args) -{ - return runAsync(static_cast(nullptr), priority, - std::forward(function), std::forward(args)...); -} - -/*! - Runs \a function with \a args in a new thread with thread priority QThread::InheritPriority. - \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) - \sa QThread::Priority - */ -template , QThreadPool>::value - && !std::is_same, QThread::Priority>::value - >, - typename ResultType = typename Internal::resultType::type> -QFuture -runAsync(Function &&function, Args&&... args) -{ - return runAsync(static_cast(nullptr), - QThread::InheritPriority, std::forward(function), - std::forward(args)...); -} - -/*! - Runs \a function with \a args in a thread \a pool with thread priority QThread::InheritPriority. - \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) - \sa QThread::Priority - */ -template , QThread::Priority>::value>, - typename ResultType = typename Internal::resultType::type> -QFuture -runAsync(QThreadPool *pool, Function &&function, Args&&... args) -{ - return runAsync(pool, QThread::InheritPriority, std::forward(function), - std::forward(args)...); -} - -} // namespace Utils diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index c39aef1cdef..f9e22e82bfd 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -40,7 +40,6 @@ Project { Depends { name: "ptyqt" } files: [ - "QtConcurrentTools", "algorithm.h", "ansiescapecodehandler.cpp", "ansiescapecodehandler.h", @@ -147,7 +146,6 @@ Project { "fixedsizeclicklabel.h", "flowlayout.cpp", "flowlayout.h", - "functiontraits.h", "futuresynchronizer.cpp", "futuresynchronizer.h", "fuzzymatcher.cpp", @@ -193,7 +191,6 @@ Project { "listutils.h", "macroexpander.cpp", "macroexpander.h", - "mapreduce.h", "mathutils.cpp", "mathutils.h", "mimeutils.h", @@ -270,8 +267,6 @@ Project { "reloadpromptutils.h", "removefiledialog.cpp", "removefiledialog.h", - "runextensions.cpp", - "runextensions.h", "savefile.cpp", "savefile.h", "scopedswap.h", diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp index d896836a500..5e6f3bcd781 100644 --- a/src/plugins/projectexplorer/buildstep.cpp +++ b/src/plugins/projectexplorer/buildstep.cpp @@ -39,7 +39,7 @@ \c init() is called in the GUI thread and can be used to query the project for any information you need. - \c run() is run via Utils::runAsync in a separate thread. If you need an + \c run() is run via Utils::asyncRun in a separate thread. If you need an event loop, you need to create it yourself. */ diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 31a55faab01..f3e234b02d8 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 5dcd026a7af..7b53a20004d 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -13,11 +13,9 @@ add_subdirectory(filesearch) add_subdirectory(haskell) add_subdirectory(json) add_subdirectory(languageserverprotocol) -add_subdirectory(mapreduce) add_subdirectory(pointeralgorithm) add_subdirectory(profilewriter) add_subdirectory(qml) -add_subdirectory(runextensions) add_subdirectory(sdktool) add_subdirectory(solutions) add_subdirectory(texteditor) diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index 603b5cd1b15..a21b61fc0cd 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -20,7 +20,6 @@ Project { "languageserverprotocol/languageserverprotocol.qbs", "profilewriter/profilewriter.qbs", "qml/qml.qbs", - "runextensions/runextensions.qbs", "sdktool/sdktool.qbs", "solutions/solutions.qbs", "texteditor/texteditor.qbs", diff --git a/tests/auto/mapreduce/CMakeLists.txt b/tests/auto/mapreduce/CMakeLists.txt deleted file mode 100644 index 5a57f3c6761..00000000000 --- a/tests/auto/mapreduce/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_qtc_test(tst_mapreduce - DEPENDS Utils - SOURCES tst_mapreduce.cpp -) diff --git a/tests/auto/mapreduce/mapreduce.qbs b/tests/auto/mapreduce/mapreduce.qbs deleted file mode 100644 index 63502117b02..00000000000 --- a/tests/auto/mapreduce/mapreduce.qbs +++ /dev/null @@ -1,10 +0,0 @@ -import qbs - -QtcAutotest { - name: "Map reduce autotest" - Depends { name: "Utils" } - - files: [ - "tst_mapreduce.cpp", - ] -} diff --git a/tests/auto/mapreduce/tst_mapreduce.cpp b/tests/auto/mapreduce/tst_mapreduce.cpp deleted file mode 100644 index df1f8e1986b..00000000000 --- a/tests/auto/mapreduce/tst_mapreduce.cpp +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include -#include - -#include -#include - -#if !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2015 -#define SUPPORTS_MOVE -#endif - -class tst_MapReduce : public QObject -{ - Q_OBJECT - -private slots: - void mapReduce(); - void mapReduceRvalueContainer(); - void map(); - void orderedMapReduce(); -#ifdef SUPPORTS_MOVE - void moveOnlyType(); -#endif -}; - -static int returnxx(int x) -{ - return x*x; -} - -static void returnxxThroughFutureInterface(QFutureInterface &fi, int x) -{ - fi.reportResult(x*x); -} - -void tst_MapReduce::mapReduce() -{ - QThreadPool pool; - const auto initWithFutureInterface = [](QFutureInterface &fi) -> double { - fi.reportResult(0.); - return 0.; - }; - const auto reduceWithFutureInterface = [](QFutureInterface &fi, double &state, int value) { - state += value; - fi.reportResult(value); - }; - const auto reduceWithReturn = [](double &state, int value) -> double { - state += value; - return value; - }; - const auto cleanupWithFutureInterface = [](QFutureInterface &fi, double &state) { - state /= 2.; - fi.reportResult(state); - }; - - { - // map without future interface - QList results = Utils::mapReduce(QVector({1, 2, 3, 4, 5}), - initWithFutureInterface, - returnxx, - reduceWithFutureInterface, - cleanupWithFutureInterface) - .results(); - Utils::sort(results); // mapping order is undefined - QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // map with future interface - QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - initWithFutureInterface, returnxxThroughFutureInterface, - reduceWithFutureInterface, cleanupWithFutureInterface) - .results(); - Utils::sort(results); // mapping order is undefined - QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // reduce without future interface - QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface) - .results(); - Utils::sort(results); // mapping order is undefined - QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // reduce with threadpool - QList results = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface, - Utils::MapReduceOption::Unordered, &pool) - .results(); - Utils::sort(results); // mapping order is undefined - QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // lvalue ref container - QList container({1, 2, 3, 4, 5}); - QList results = Utils::mapReduce(container, - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface) - .results(); - Utils::sort(results); // mapping order is undefined - QCOMPARE(results, QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // std::cref - QList container({1, 2, 3, 4, 5}); - QCOMPARE(Utils::mapReduce(std::cref(container), - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface, - Utils::MapReduceOption::Ordered).results(), - QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // std::cref with threadpool - QList container({1, 2, 3, 4, 5}); - QCOMPARE(Utils::mapReduce(std::cref(container), - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface, - Utils::MapReduceOption::Ordered, &pool).results(), - QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // std::ref - QList container({1, 2, 3, 4, 5}); - QCOMPARE(Utils::mapReduce(std::ref(container), - initWithFutureInterface, returnxx, - reduceWithReturn, cleanupWithFutureInterface, - Utils::MapReduceOption::Ordered).results(), - QList({0., 1., 4., 9., 16., 25., 27.5})); - } - { - // init and cleanup without future interface - QCOMPARE(Utils::mapReduce(QList({1, 2, 3}), - []() { return 0.; }, - [](int v) { return v*2; }, - [](double &state, int v) { return state += v/4.; }, - [](double &) { }, - Utils::MapReduceOption::Ordered).results(), - QList({.5, 1.5, 3.})); - } - { - // simplified map reduce without init and cleanup - QCOMPARE(Utils::mapReduce(QList({QLatin1String("blubb"), QLatin1String("foo"), QLatin1String("blah")}), - [](const QString &val) { return val.size(); }, - 90., - [](double &state, int val) { - state /= double(val); - }, - Utils::MapReduceOption::Ordered).result(), - 1.5); - } - { - // simplified map reduce without init and cleanup with threadpool - QCOMPARE(Utils::mapReduce(QList({QLatin1String("blubb"), QLatin1String("foo"), QLatin1String("blah")}), - [](const QString &val) { return val.size(); }, - 90., - [](double &state, int val) { - state /= double(val); - }, - Utils::MapReduceOption::Ordered, &pool).result(), - 1.5); - } - { - // simplified map reduce - // std::cref - QList container({1, 2, 3}); - QCOMPARE(Utils::mapReduce(std::cref(container), [](int val) { return 2*val; }, 10, - [](int &state, int val) { state += val; }).result(), - 22); - } - { - // simplified map reduce - // std::cref with threadpool - QList container({1, 2, 3}); - QCOMPARE(Utils::mapReduce(std::cref(container), [](int val) { return 2*val; }, 10, - [](int &state, int val) { state += val; }, - Utils::MapReduceOption::Unordered, &pool).result(), - 22); - } - { - // simplified map reduce - // std::ref - QList container({1, 2, 3}); - QCOMPARE(Utils::mapReduce(std::ref(container), [](int &val) { return 2*val; }, 10, - [](int &state, int val) { state += val; }).result(), - 22); - } - { - // blocking mapReduce = mappedReduced - QCOMPARE(Utils::mappedReduced(QList({1, 2, 3}), [](int &val) { return 2*val; }, 10, - [](int &state, int val) { state += val; }), - 22); - } - { - // blocking mapReduce = mappedReduced - // with threadpool - QCOMPARE(Utils::mappedReduced(QList({1, 2, 3}), [](int &val) { return 2*val; }, 10, - [](int &state, int val) { state += val; }, - Utils::MapReduceOption::Unordered, &pool), - 22); - } -} - -void tst_MapReduce::mapReduceRvalueContainer() -{ - { - QFuture future = Utils::mapReduce(QList({1, 2, 3, 4, 5}), - []() { return 0; }, - [](int value) { return value; }, - [](QFutureInterface &, int &state, int value) { state += value; }, - [](QFutureInterface &fi, int &state) { fi.reportResult(state); }); - // here, lifetime of the QList temporary ends - QCOMPARE(future.results(), QList({15})); - } -} - -void tst_MapReduce::map() -{ - QCOMPARE(Utils::map(QList({2, 5, 1}), [](int x) { return x*2.5; }).results(), - QList({5., 12.5, 2.5})); - { - // void result - QList results; - QMutex mutex; - Utils::map( - // container - QList({2, 5, 1}), - // map - [&mutex, &results](int x) { QMutexLocker l(&mutex); results.append(x); } - ).waitForFinished(); - // Utils::map is "ordered" by default, but that means that result reporting is ordered, - // the map function is still called out-of-order - Utils::sort(results); - QCOMPARE(results, QList({1, 2, 5})); - } - { - // inplace editing - QList container({2, 5, 1}); - Utils::map(std::ref(container), [](int &x) { x *= 2; }).waitForFinished(); - QCOMPARE(container, QList({4, 10, 2})); - - Utils::map(container.begin(), container.end(), [](int &x) { x *= 2; }, - Utils::MapReduceOption::Unordered, - nullptr, QThread::InheritPriority, 3).waitForFinished(); - QCOMPARE(container, QList({8, 20, 4})); - } - - // blocking map = mapped - { - const QSet sizes = Utils::mapped( - QStringList({QLatin1String("foo"), QLatin1String("bar"), QLatin1String("blah")}), - [](const QString &s) { return s.size(); }); - QList vals = sizes.values(); - Utils::sort(vals); - QCOMPARE(vals, QList({3, 4})); - } - { - const QStringList list({QLatin1String("foo"), QLatin1String("bar"), QLatin1String("blah")}); - const QSet sizes = Utils::mapped(list.cbegin(), - list.cend(), - [](const QString &s) { - return s.size(); - }); - QList vals = sizes.values(); - Utils::sort(vals); - QCOMPARE(vals, QList({3, 4})); - } -} - -void tst_MapReduce::orderedMapReduce() -{ - QCOMPARE(Utils::mapReduce(QList({1, 2, 3, 4}), - []() { return 0; }, - [](int i) { return i*2; }, - [](int &state, int val) { state += val; return state; }, - [](int &) { }, - Utils::MapReduceOption::Ordered).results(), - QList({2, 6, 12, 20})); -} - -#ifdef SUPPORTS_MOVE - -class MoveOnlyType -{ -public: - MoveOnlyType() noexcept {} // <- with GCC 5 the defaulted one is noexcept(false) - MoveOnlyType(const MoveOnlyType &) = delete; - MoveOnlyType(MoveOnlyType &&) = default; - MoveOnlyType &operator=(const MoveOnlyType &) = delete; - MoveOnlyType &operator=(MoveOnlyType &&) = default; -}; - -class MoveOnlyState : public MoveOnlyType -{ -public: - int count = 0; -}; - -class MoveOnlyInit : public MoveOnlyType -{ -public: - MoveOnlyState operator()(QFutureInterface &) const { return MoveOnlyState(); } -}; - -class MoveOnlyMap : public MoveOnlyType -{ -public: - int operator()(const MoveOnlyType &) const { return 1; } -}; - -class MoveOnlyReduce : public MoveOnlyType -{ -public: - void operator()(QFutureInterface &, MoveOnlyState &state, int) { ++state.count; } -}; - -class MoveOnlyList : public std::vector -{ -public: - MoveOnlyList() { emplace_back(MoveOnlyType()); emplace_back(MoveOnlyType()); } - MoveOnlyList(const MoveOnlyList &) = delete; - MoveOnlyList(MoveOnlyList &&) = default; - MoveOnlyList &operator=(const MoveOnlyList &) = delete; - MoveOnlyList &operator=(MoveOnlyList &&) = default; -}; - -void tst_MapReduce::moveOnlyType() -{ - QCOMPARE(Utils::mapReduce(MoveOnlyList(), - MoveOnlyInit(), - MoveOnlyMap(), - MoveOnlyReduce(), - [](QFutureInterface &fi, MoveOnlyState &state) { fi.reportResult(state.count); } - ).results(), - QList({2})); -} - -#endif - -QTEST_GUILESS_MAIN(tst_MapReduce) - -#include "tst_mapreduce.moc" diff --git a/tests/auto/runextensions/CMakeLists.txt b/tests/auto/runextensions/CMakeLists.txt deleted file mode 100644 index 73455f75185..00000000000 --- a/tests/auto/runextensions/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_qtc_test(tst_runextensions - DEPENDS Utils - SOURCES tst_runextensions.cpp -) diff --git a/tests/auto/runextensions/runextensions.qbs b/tests/auto/runextensions/runextensions.qbs deleted file mode 100644 index 26e6bf5d84a..00000000000 --- a/tests/auto/runextensions/runextensions.qbs +++ /dev/null @@ -1,10 +0,0 @@ -import qbs - -QtcAutotest { - name: "Run extensions autotest" - Depends { name: "Utils" } - - files: [ - "tst_runextensions.cpp", - ] -} diff --git a/tests/auto/runextensions/tst_runextensions.cpp b/tests/auto/runextensions/tst_runextensions.cpp deleted file mode 100644 index 4ffee270025..00000000000 --- a/tests/auto/runextensions/tst_runextensions.cpp +++ /dev/null @@ -1,540 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include - -#include - -#if !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2015 -#define SUPPORTS_MOVE -#endif - -class tst_RunExtensions : public QObject -{ - Q_OBJECT - -private slots: - void runAsync(); - void runInThreadPool(); -#ifdef SUPPORTS_MOVE - void moveOnlyType(); -#endif - void threadPriority(); - void runAsyncNoFutureInterface(); - void crefFunction(); -}; - -void report3(QFutureInterface &fi) -{ - fi.reportResults({0, 2, 1}); -} - -void reportN(QFutureInterface &fi, int n) -{ - fi.reportResults(QVector(n, 0)); -} - -void reportString1(QFutureInterface &fi, const QString &s) -{ - fi.reportResult(s); -} - -void reportString2(QFutureInterface &fi, QString s) -{ - fi.reportResult(s); -} - -class Callable { -public: - void operator()(QFutureInterface &fi, int n) const - { - fi.reportResults(QVector(n, 0)); - } -}; - -class MyObject { -public: - static void staticMember0(QFutureInterface &fi) - { - fi.reportResults({0, 2, 1}); - } - - static void staticMember1(QFutureInterface &fi, int n) - { - fi.reportResults(QVector(n, 0)); - } - - void member0(QFutureInterface &fi) const - { - fi.reportResults({0, 2, 1}); - } - - void member1(QFutureInterface &fi, int n) const - { - fi.reportResults(QVector(n, 0)); - } - - void memberString1(QFutureInterface &fi, const QString &s) const - { - fi.reportResult(s); - } - - void memberString2(QFutureInterface &fi, QString s) const - { - fi.reportResult(s); - } - - void nonConstMember(QFutureInterface &fi) - { - fi.reportResults({0, 2, 1}); - } -}; - -void voidFunction(bool *value) // can be useful to get QFuture for watching when it is finished -{ - *value = true; -} - -int one() -{ - return 1; -} - -int identity(int input) -{ - return input; -} - -QString stringIdentity1(const QString &s) -{ - return s; -} - -QString stringIdentity2(QString s) -{ - return s; -} - -class CallableWithoutQFutureInterface { -public: - void operator()(bool *value) const - { - *value = true; - } -}; - -class MyObjectWithoutQFutureInterface { -public: - static void staticMember0(bool *value) - { - *value = true; - } - - static double staticMember1(int n) - { - return n; - } - - void member0(bool *value) const - { - *value = true; - } - - double member1(int n) const - { - return n; - } - - QString memberString1(const QString &s) const - { - return s; - } - - QString memberString2(QString s) const - { - return s; - } - - double nonConstMember(int n) - { - return n; - } -}; - -void tst_RunExtensions::runAsync() -{ - // free function pointer - QCOMPARE(Utils::runAsync(&report3).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(report3).results(), - QList({0, 2, 1})); - - QCOMPARE(Utils::runAsync(reportN, 4).results(), - QList({0, 0, 0, 0})); - QCOMPARE(Utils::runAsync(reportN, 2).results(), - QList({0, 0})); - - QString s = QLatin1String("string"); - const QString &crs = QLatin1String("cr string"); - const QString cs = QLatin1String("c string"); - - QCOMPARE(Utils::runAsync(reportString1, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(reportString1, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(reportString1, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(reportString1, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - - QCOMPARE(Utils::runAsync(reportString2, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(reportString2, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(reportString2, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(reportString2, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - - // lambda - QCOMPARE(Utils::runAsync([](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }, 3).results(), - QList({0, 0, 0})); - - // std::function - const std::function&,int)> fun = [](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }; - QCOMPARE(Utils::runAsync(fun, 2).results(), - QList({0, 0})); - - // operator() - QCOMPARE(Utils::runAsync(Callable(), 3).results(), - QList({0, 0, 0})); - const Callable c{}; - QCOMPARE(Utils::runAsync(c, 2).results(), - QList({0, 0})); - - // static member functions - QCOMPARE(Utils::runAsync(&MyObject::staticMember0).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(&MyObject::staticMember1, 2).results(), - QList({0, 0})); - - // member functions - const MyObject obj{}; - QCOMPARE(Utils::runAsync(&MyObject::member0, &obj).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(&MyObject::member1, &obj, 4).results(), - QList({0, 0, 0, 0})); - QCOMPARE(Utils::runAsync(&MyObject::memberString1, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(&MyObject::memberString1, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(&MyObject::memberString1, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(&MyObject::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(Utils::runAsync(&MyObject::memberString2, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(&MyObject::memberString2, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(&MyObject::memberString2, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(&MyObject::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - MyObject nonConstObj{}; - QCOMPARE(Utils::runAsync(&MyObject::nonConstMember, &nonConstObj).results(), - QList({0, 2, 1})); -} - -void tst_RunExtensions::runInThreadPool() -{ - QScopedPointer pool(new QThreadPool); - // free function pointer - QCOMPARE(Utils::runAsync(pool.data(), &report3).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(pool.data(), report3).results(), - QList({0, 2, 1})); - - QCOMPARE(Utils::runAsync(pool.data(), reportN, 4).results(), - QList({0, 0, 0, 0})); - QCOMPARE(Utils::runAsync(pool.data(), reportN, 2).results(), - QList({0, 0})); - - QString s = QLatin1String("string"); - const QString &crs = QLatin1String("cr string"); - const QString cs = QLatin1String("c string"); - - QCOMPARE(Utils::runAsync(pool.data(), reportString1, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(pool.data(), reportString1, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(pool.data(), reportString1, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(pool.data(), reportString1, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - - QCOMPARE(Utils::runAsync(pool.data(), reportString2, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(pool.data(), reportString2, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(pool.data(), reportString2, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(pool.data(), reportString2, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - - // lambda - QCOMPARE(Utils::runAsync(pool.data(), [](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }, 3).results(), - QList({0, 0, 0})); - - // std::function - const std::function&,int)> fun = [](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }; - QCOMPARE(Utils::runAsync(pool.data(), fun, 2).results(), - QList({0, 0})); - - // operator() - QCOMPARE(Utils::runAsync(pool.data(), Callable(), 3).results(), - QList({0, 0, 0})); - const Callable c{}; - QCOMPARE(Utils::runAsync(pool.data(), c, 2).results(), - QList({0, 0})); - - // static member functions - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::staticMember0).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::staticMember1, 2).results(), - QList({0, 0})); - - // member functions - const MyObject obj{}; - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::member0, &obj).results(), - QList({0, 2, 1})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::member1, &obj, 4).results(), - QList({0, 0, 0, 0})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString1, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString1, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString1, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString2, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString2, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString2, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(pool.data(), &MyObject::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); -} - -#ifdef SUPPORTS_MOVE - -class MoveOnlyType -{ -public: - MoveOnlyType() = default; - MoveOnlyType(const MoveOnlyType &) = delete; - MoveOnlyType(MoveOnlyType &&) = default; - MoveOnlyType &operator=(const MoveOnlyType &) = delete; - MoveOnlyType &operator=(MoveOnlyType &&) = default; -}; - -class MoveOnlyCallable : public MoveOnlyType -{ -public: - void operator()(QFutureInterface &fi, const MoveOnlyType &) - { - fi.reportResult(1); - } -}; - -void tst_RunExtensions::moveOnlyType() -{ - QCOMPARE(Utils::runAsync(MoveOnlyCallable(), MoveOnlyType()).results(), - QList({1})); -} - -#endif - -void tst_RunExtensions::threadPriority() -{ - QScopedPointer pool(new QThreadPool); - // with pool - QCOMPARE(Utils::runAsync(pool.data(), QThread::LowestPriority, &report3).results(), - QList({0, 2, 1})); - - // without pool - QCOMPARE(Utils::runAsync(QThread::LowestPriority, report3).results(), - QList({0, 2, 1})); -} - -void tst_RunExtensions::runAsyncNoFutureInterface() -{ - // free function pointer - bool value = false; - Utils::runAsync(voidFunction, &value).waitForFinished(); - QCOMPARE(value, true); - - QCOMPARE(Utils::runAsync(one).results(), - QList({1})); - QCOMPARE(Utils::runAsync(identity, 5).results(), - QList({5})); - - QString s = QLatin1String("string"); - const QString &crs = QLatin1String("cr string"); - const QString cs = QLatin1String("c string"); - - QCOMPARE(Utils::runAsync(stringIdentity1, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(stringIdentity1, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(stringIdentity1, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(stringIdentity1, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(Utils::runAsync(stringIdentity2, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(stringIdentity2, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(stringIdentity2, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(stringIdentity2, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - - // lambda - QCOMPARE(Utils::runAsync([](int n) -> double { - return n + 1; - }, 3).results(), - QList({4})); - - // std::function - const std::function fun = [](int n) { - return n + 1; - }; - QCOMPARE(Utils::runAsync(fun, 2).results(), - QList({3})); - - // operator() - value = false; - Utils::runAsync(CallableWithoutQFutureInterface(), &value).waitForFinished(); - QCOMPARE(value, true); - value = false; - const CallableWithoutQFutureInterface c{}; - Utils::runAsync(c, &value).waitForFinished(); - QCOMPARE(value, true); - - // static member functions - value = false; - Utils::runAsync(&MyObjectWithoutQFutureInterface::staticMember0, &value).waitForFinished(); - QCOMPARE(value, true); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::staticMember1, 2).results(), - QList({2})); - - // member functions - const MyObjectWithoutQFutureInterface obj{}; - value = false; - Utils::runAsync(&MyObjectWithoutQFutureInterface::member0, &obj, &value).waitForFinished(); - QCOMPARE(value, true); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::member1, &obj, 4).results(), - QList({4})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString1, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString1, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString1, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString1, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString2, &obj, s).results(), - QList({s})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString2, &obj, crs).results(), - QList({crs})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString2, &obj, cs).results(), - QList({cs})); - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::memberString2, &obj, QString(QLatin1String("rvalue"))).results(), - QList({QString(QLatin1String("rvalue"))})); - MyObjectWithoutQFutureInterface nonConstObj{}; - QCOMPARE(Utils::runAsync(&MyObjectWithoutQFutureInterface::nonConstMember, &nonConstObj, 4).results(), - QList({4})); -} - -void tst_RunExtensions::crefFunction() -{ - // free function pointer with future interface - auto fun = &report3; - QCOMPARE(Utils::runAsync(std::cref(fun)).results(), - QList({0, 2, 1})); - - // lambda with future interface - auto lambda = [](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }; - QCOMPARE(Utils::runAsync(std::cref(lambda), 3).results(), - QList({0, 0, 0})); - - // std::function with future interface - const std::function&,int)> funObj = [](QFutureInterface &fi, int n) { - fi.reportResults(QVector(n, 0)); - }; - QCOMPARE(Utils::runAsync(std::cref(funObj), 2).results(), - QList({0, 0})); - - // callable with future interface - const Callable c{}; - QCOMPARE(Utils::runAsync(std::cref(c), 2).results(), - QList({0, 0})); - - // member functions with future interface - auto member = &MyObject::member0; - const MyObject obj{}; - QCOMPARE(Utils::runAsync(std::cref(member), &obj).results(), - QList({0, 2, 1})); - - // free function pointer without future interface - bool value = false; - auto voidFun = &voidFunction; - Utils::runAsync(std::cref(voidFun), &value).waitForFinished(); - QCOMPARE(value, true); - - auto oneFun = &one; - QCOMPARE(Utils::runAsync(std::cref(oneFun)).results(), - QList({1})); - - // lambda without future interface - auto lambda2 = [](int n) -> double { - return n + 1; - }; - QCOMPARE(Utils::runAsync(std::cref(lambda2), 3).results(), - QList({4})); - - // std::function - const std::function funObj2 = [](int n) { - return n + 1; - }; - QCOMPARE(Utils::runAsync(std::cref(funObj2), 2).results(), - QList({3})); - - // callable without future interface - const CallableWithoutQFutureInterface c2{}; - Utils::runAsync(std::cref(c2), &value).waitForFinished(); - QCOMPARE(value, true); - - // member functions without future interface - const MyObjectWithoutQFutureInterface obj2{}; - auto member2 = &MyObjectWithoutQFutureInterface::member0; - value = false; - Utils::runAsync(std::cref(member2), &obj2, &value).waitForFinished(); - QCOMPARE(value, true); -} - -QTEST_GUILESS_MAIN(tst_RunExtensions) - -#include "tst_runextensions.moc"