1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QTBASE_QTTASKBUILDER_H
5#define QTBASE_QTTASKBUILDER_H
6
7#if !defined(QT_NO_CONCURRENT) || defined(Q_QDOC)
8
9#include <QtConcurrent/qtconcurrentstoredfunctioncall.h>
10
11QT_BEGIN_NAMESPACE
12
13#ifdef Q_QDOC
14
15namespace QtConcurrent {
16
17enum class FutureResult { Ignore };
18
19using InvokeResultType = int;
20
21template <class Task, class ...Args>
22class QTaskBuilder
23{
24public:
25 [[nodiscard]]
26 QFuture<InvokeResultType> spawn();
27
28 void spawn(FutureResult);
29
30 template <class ...ExtraArgs>
31 [[nodiscard]]
32 QTaskBuilder<Task, ExtraArgs...> withArguments(ExtraArgs &&...args);
33
34 [[nodiscard]]
35 QTaskBuilder<Task, Args...> &onThreadPool(QThreadPool &newThreadPool);
36
37 [[nodiscard]]
38 QTaskBuilder<Task, Args...> &withPriority(int newPriority);
39};
40
41} // namespace QtConcurrent
42
43#else
44
45namespace QtConcurrent {
46
47enum class FutureResult { Ignore };
48
49template <class Task, class ...Args>
50class QTaskBuilder
51{
52public:
53 [[nodiscard]]
54 auto spawn()
55 {
56 return TaskResolver<std::decay_t<Task>, std::decay_t<Args>...>::run(
57 std::move(taskWithArgs), startParameters);
58 }
59
60 // We don't want to run with promise when we don't return a QFuture
61 void spawn(FutureResult)
62 {
63 (new StoredFunctionCall<Task, Args...>(std::move(taskWithArgs)))
64 ->start(startParameters);
65 }
66
67 template <class ...ExtraArgs>
68 [[nodiscard]]
69 constexpr auto withArguments(ExtraArgs &&...args)
70 {
71 static_assert(std::tuple_size_v<TaskWithArgs> == 1,
72 "This function cannot be invoked if "
73 "arguments have already been passed.");
74
75 static_assert(sizeof...(ExtraArgs) >= 1,
76 "One or more arguments must be passed.");
77
78 // We have to re-create a builder, because the type has changed
79 return QTaskBuilder<Task, ExtraArgs...>(
80 startParameters,
81 std::get<0>(std::move(taskWithArgs)),
82 std::forward<ExtraArgs>(args)...
83 );
84 }
85
86 [[nodiscard]]
87 constexpr auto &onThreadPool(QThreadPool &newThreadPool)
88 {
89 startParameters.threadPool = &newThreadPool;
90 return *this;
91 }
92
93 [[nodiscard]]
94 constexpr auto &withPriority(int newPriority)
95 {
96 startParameters.priority = newPriority;
97 return *this;
98 }
99
100protected: // Methods
101 constexpr explicit QTaskBuilder(Task &&task, Args &&...arguments)
102 : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
103 {}
104
105 constexpr QTaskBuilder(
106 const TaskStartParameters &parameters, Task &&task, Args &&...arguments)
107 : taskWithArgs{std::forward<Task>(task), std::forward<Args>(arguments)...}
108 , startParameters{parameters}
109 {}
110
111private: // Methods
112 // Required for creating a builder from "task" function
113 template <class T>
114 friend constexpr auto task(T &&t);
115
116 // Required for creating a new builder from "withArguments" function
117 template <class T, class ...A>
118 friend class QTaskBuilder;
119
120private: // Data
121 using TaskWithArgs = DecayedTuple<Task, Args...>;
122
123 TaskWithArgs taskWithArgs;
124 TaskStartParameters startParameters;
125};
126
127} // namespace QtConcurrent
128
129#endif // Q_QDOC
130
131QT_END_NAMESPACE
132
133#endif // !defined(QT_NO_CONCURRENT)
134
135#endif //QTBASE_QTTASKBUILDER_H
136

source code of qtbase/src/concurrent/qtaskbuilder.h