Revision control

++ // Copyright (C) 2020 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
++ // Qt-Security score:significant reason:default
++
++ #ifndef QTBASE_QTTASKBUILDER_H
++ #define QTBASE_QTTASKBUILDER_H
++
++ #if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
++
++ #include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
++
++ QT_BEGIN_NAMESPACE
++
++ #ifdef Q_QDOC
++
++ namespace QtConcurrent {
++
++ enum class FutureResult { Ignore };
++
++ using InvokeResultType = int;
++
++ template <class Task, class ...Args>
++ class QTaskBuilder
++ {
++ public:
++ [[nodiscard]]
++ QFuture<InvokeResultType> spawn();
++
++ void spawn(FutureResult);
++
++ template <class ...ExtraArgs>
++ [[nodiscard]]
++ QTaskBuilder<Task, ExtraArgs...> withArguments(ExtraArgs &&...args);
++
++ [[nodiscard]]
++ QTaskBuilder<Task, Args...> &onThreadPool(QThreadPool &newThreadPool);
++
++ [[nodiscard]]
++ QTaskBuilder<Task, Args...> &withPriority(int newPriority);
++ };
++
++ } // namespace QtConcurrent
++
++ #else
++
++ namespace QtConcurrent {
++
++ enum class FutureResult { Ignore };
++
++ template <class Task, class ...Args>
++ class QTaskBuilder
++ {
++ public:
++ [[nodiscard]]
++ auto spawn()
++ {
++ return TaskResolver<std::decay_t<Task>, std::decay_t<Args>...>::run(
++ std::move(taskWithArgs), startParameters);
++ }
++
++ // We don't want to run with promise when we don't return a QFuture
++ void spawn(FutureResult)
++ {
++ (new StoredFunctionCall<Task, Args...>(std::move(taskWithArgs)))
++ ->start(startParameters);
++ }
++
++ template <class ...ExtraArgs>
++ [[nodiscard]]
++ constexpr auto withArguments(ExtraArgs &&...args)
++ {
++ static_assert(std::tuple_size_v<TaskWithArgs> == 1,
++ "This function cannot be invoked if "
++ "arguments have already been passed.");
++
++ static_assert(sizeof...(ExtraArgs) >= 1,
++ "One or more arguments must be passed.");
++
++ // We have to re-create a builder, because the type has changed
++ return QTaskBuilder<Task, ExtraArgs...>(
++ startParameters,
++ std::get<0>(std::move(taskWithArgs)),
++ std::forward<ExtraArgs>(args)...
++ );
++ }
++
++ [[nodiscard]]
++ constexpr auto &onThreadPool(QThreadPool &newThreadPool)
++ {
++ startParameters.threadPool = &newThreadPool;
++ return *this;
++ }
++
++ [[nodiscard]]
++ constexpr auto &withPriority(int newPriority)
++ {
++ startParameters.priority = newPriority;
++ return *this;
++ }
++
++ protected: // Methods
++ constexpr explicit QTaskBuilder(Task &&task, Args &&...arguments)
++ : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
++ {}
++
++ constexpr QTaskBuilder(
++ const TaskStartParameters &parameters, Task &&task, Args &&...arguments)
++ : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
++ , startParameters{parameters}
++ {}
++
++ private: // Methods
++ // Required for creating a builder from "task" function
++ template <class T>
++ friend constexpr auto task(T &&t);
++
++ // Required for creating a new builder from "withArguments" function
++ template <class T, class ...A>
++ friend class QTaskBuilder;
++
++ private: // Data
++ using TaskWithArgs = DecayedTuple<Task, Args...>;
++
++ TaskWithArgs taskWithArgs;
++ TaskStartParameters startParameters;
++ };
++
++ } // namespace QtConcurrent
++
++ #endif // Q_QDOC
++
++ QT_END_NAMESPACE
++
++ #endif // !defined(QT_NO_CONCURRENT)
++
++ #endif //QTBASE_QTTASKBUILDER_H