Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
Task.hh
Go to the documentation of this file.
1//
2// MIT License
3// Copyright (c) 2020 Jonathan R. Madsen
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and
8// copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
12// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
13// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
16// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
17// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18//
19//
20// ---------------------------------------------------------------
21// Tasking class header file
22//
23// Class Description:
24//
25// This file defines the task types for TaskManager and ThreadPool
26//
27// ---------------------------------------------------------------
28// Author: Jonathan Madsen (Feb 13th 2018)
29// ---------------------------------------------------------------
30
31#pragma once
32
33#include "PTL/Globals.hh"
34#include "PTL/VTask.hh"
35
36#include <cstdint>
37#include <future>
38#include <tuple>
39#include <utility>
40
41namespace PTL
42{
43//======================================================================================//
44
45/// \brief The task class is supplied to thread_pool.
46template <typename RetT>
47class TaskFuture : public VTask
48{
49public:
50 using promise_type = std::promise<RetT>;
51 using future_type = std::future<RetT>;
52 using result_type = RetT;
53
54public:
55 // pass a free function pointer
56 template <typename... Args>
57 TaskFuture(Args&&... args)
58 : VTask{ std::forward<Args>(args)... }
59 {}
60
61 ~TaskFuture() override = default;
62
63 TaskFuture(const TaskFuture&) = delete;
64 TaskFuture& operator=(const TaskFuture&) = delete;
65
66 TaskFuture(TaskFuture&&) noexcept = default;
67 TaskFuture& operator=(TaskFuture&&) noexcept = default;
68
69public:
70 // execution operator
71 virtual future_type get_future() = 0;
72 virtual void wait() = 0;
73 virtual RetT get() = 0;
74};
75
76//======================================================================================//
77
78/// \brief The task class is supplied to thread_pool.
79template <typename RetT, typename... Args>
80class PackagedTask : public TaskFuture<RetT>
81{
82public:
83 using this_type = PackagedTask<RetT, Args...>;
84 using promise_type = std::promise<RetT>;
85 using future_type = std::future<RetT>;
86 using packaged_task_type = std::packaged_task<RetT(Args...)>;
87 using result_type = RetT;
88 using tuple_type = std::tuple<Args...>;
89
90public:
91 // pass a free function pointer
92 template <typename FuncT>
93 PackagedTask(FuncT func, Args... args)
94 : TaskFuture<RetT>{ true, 0 }
95 , m_ptask{ std::move(func) }
96 , m_args{ args... }
97 {}
98
99 template <typename FuncT>
100 PackagedTask(bool _is_native, intmax_t _depth, FuncT func, Args... args)
101 : TaskFuture<RetT>{ _is_native, _depth }
102 , m_ptask{ std::move(func) }
103 , m_args{ args... }
104 {}
105
106 ~PackagedTask() override = default;
107
108 PackagedTask(const PackagedTask&) = delete;
110
111 PackagedTask(PackagedTask&&) noexcept = default;
112 PackagedTask& operator=(PackagedTask&&) noexcept = default;
113
114public:
115 // execution operator
116 void operator()() final { mpl::apply(std::move(m_ptask), std::move(m_args)); }
117 future_type get_future() final { return m_ptask.get_future(); }
118 void wait() final { return m_ptask.get_future().wait(); }
119 RetT get() final { return m_ptask.get_future().get(); }
120
121private:
122 packaged_task_type m_ptask;
123 tuple_type m_args;
124};
125
126//======================================================================================//
127
128/// \brief The task class is supplied to thread_pool.
129template <typename RetT, typename... Args>
130class Task : public TaskFuture<RetT>
131{
132public:
133 using this_type = Task<RetT, Args...>;
134 using promise_type = std::promise<RetT>;
135 using future_type = std::future<RetT>;
136 using packaged_task_type = std::packaged_task<RetT(Args...)>;
137 using result_type = RetT;
138 using tuple_type = std::tuple<Args...>;
139
140public:
141 template <typename FuncT>
142 Task(FuncT func, Args... args)
143 : TaskFuture<RetT>{}
144 , m_ptask{ std::move(func) }
145 , m_args{ args... }
146 {}
147
148 template <typename FuncT>
149 Task(bool _is_native, intmax_t _depth, FuncT func, Args... args)
150 : TaskFuture<RetT>{ _is_native, _depth }
151 , m_ptask{ std::move(func) }
152 , m_args{ args... }
153 {}
154
155 ~Task() override = default;
156
157 Task(const Task&) = delete;
158 Task& operator=(const Task&) = delete;
159
160 Task(Task&&) noexcept = default;
161 Task& operator=(Task&&) noexcept = default;
162
163public:
164 // execution operator
165 void operator()() final
166 {
167 if(m_ptask.valid())
168 mpl::apply(std::move(m_ptask), std::move(m_args));
169 }
170 future_type get_future() final { return m_ptask.get_future(); }
171 void wait() final { return m_ptask.get_future().wait(); }
172 RetT get() final { return m_ptask.get_future().get(); }
173
174private:
175 packaged_task_type m_ptask{};
176 tuple_type m_args{};
177};
178
179//======================================================================================//
180
181/// \brief The task class is supplied to thread_pool.
182template <typename RetT>
183class Task<RetT, void> : public TaskFuture<RetT>
184{
185public:
187 using promise_type = std::promise<RetT>;
188 using future_type = std::future<RetT>;
189 using packaged_task_type = std::packaged_task<RetT()>;
190 using result_type = RetT;
191
192public:
193 template <typename FuncT>
194 Task(FuncT func)
195 : TaskFuture<RetT>()
196 , m_ptask{ std::move(func) }
197 {}
198
199 template <typename FuncT>
200 Task(bool _is_native, intmax_t _depth, FuncT func)
201 : TaskFuture<RetT>{ _is_native, _depth }
202 , m_ptask{ std::move(func) }
203 {}
204
205 virtual ~Task() = default;
206
207 Task(const Task&) = delete;
208 Task& operator=(const Task&) = delete;
209
210 Task(Task&&) noexcept = default;
211 Task& operator=(Task&&) noexcept = default;
212
213public:
214 // execution operator
215 virtual void operator()() final { m_ptask(); }
216 virtual future_type get_future() final { return m_ptask.get_future(); }
217 virtual void wait() final { return m_ptask.get_future().wait(); }
218 virtual RetT get() final { return m_ptask.get_future().get(); }
219
220private:
221 packaged_task_type m_ptask{};
222};
223
224//======================================================================================//
225
226/// \brief The task class is supplied to thread_pool.
227template <>
228class Task<void, void> : public TaskFuture<void>
229{
230public:
231 using RetT = void;
233 using promise_type = std::promise<RetT>;
234 using future_type = std::future<RetT>;
235 using packaged_task_type = std::packaged_task<RetT()>;
237
238public:
239 template <typename FuncT>
240 explicit Task(FuncT func)
241 : TaskFuture<RetT>{}
242 , m_ptask{ std::move(func) }
243 {}
244
245 template <typename FuncT>
246 Task(bool _is_native, intmax_t _depth, FuncT func)
247 : TaskFuture<RetT>{ _is_native, _depth }
248 , m_ptask{ std::move(func) }
249 {}
250
251 ~Task() override = default;
252
253 Task(const Task&) = delete;
254 Task& operator=(const Task&) = delete;
255
256 Task(Task&&) = default;
257 Task& operator=(Task&&) = default;
258
259public:
260 // execution operator
261 void operator()() final { m_ptask(); }
262 future_type get_future() final { return m_ptask.get_future(); }
263 void wait() final { return m_ptask.get_future().wait(); }
264 RetT get() final { return m_ptask.get_future().get(); }
265
266private:
267 packaged_task_type m_ptask{};
268};
269
270//======================================================================================//
271
272} // namespace PTL
The task class is supplied to thread_pool.
Definition Task.hh:81
PackagedTask(const PackagedTask &)=delete
void wait() final
Definition Task.hh:118
std::future< RetT > future_type
Definition Task.hh:85
std::tuple< Args... > tuple_type
Definition Task.hh:88
PackagedTask(bool _is_native, intmax_t _depth, FuncT func, Args... args)
Definition Task.hh:100
future_type get_future() final
Definition Task.hh:117
PackagedTask(FuncT func, Args... args)
Definition Task.hh:93
PackagedTask & operator=(const PackagedTask &)=delete
std::packaged_task< RetT(Args...)> packaged_task_type
Definition Task.hh:86
PackagedTask(PackagedTask &&) noexcept=default
RetT get() final
Definition Task.hh:119
std::promise< RetT > promise_type
Definition Task.hh:84
~PackagedTask() override=default
RetT result_type
Definition Task.hh:87
The task class is supplied to thread_pool.
Definition Task.hh:48
std::promise< RetT > promise_type
Definition Task.hh:50
TaskFuture(const TaskFuture &)=delete
TaskFuture & operator=(const TaskFuture &)=delete
RetT result_type
Definition Task.hh:52
std::future< RetT > future_type
Definition Task.hh:51
~TaskFuture() override=default
virtual RetT get()=0
TaskFuture(Args &&... args)
Definition Task.hh:57
TaskFuture(TaskFuture &&) noexcept=default
virtual future_type get_future()=0
virtual void wait()=0
std::future< RetT > future_type
Definition Task.hh:188
Task & operator=(const Task &)=delete
Task(bool _is_native, intmax_t _depth, FuncT func)
Definition Task.hh:200
Task(const Task &)=delete
virtual ~Task()=default
virtual RetT get() final
Definition Task.hh:218
std::promise< RetT > promise_type
Definition Task.hh:187
std::packaged_task< RetT()> packaged_task_type
Definition Task.hh:189
virtual future_type get_future() final
Definition Task.hh:216
Task(FuncT func)
Definition Task.hh:194
Task(Task &&) noexcept=default
virtual void wait() final
Definition Task.hh:217
The task class is supplied to thread_pool.
Definition Task.hh:229
Task & operator=(Task &&)=default
Task & operator=(const Task &)=delete
Task(Task &&)=default
std::packaged_task< RetT()> packaged_task_type
Definition Task.hh:235
void wait() final
Definition Task.hh:263
future_type get_future() final
Definition Task.hh:262
Task(FuncT func)
Definition Task.hh:240
void operator()() final
Definition Task.hh:261
Task(bool _is_native, intmax_t _depth, FuncT func)
Definition Task.hh:246
std::promise< RetT > promise_type
Definition Task.hh:233
~Task() override=default
std::future< RetT > future_type
Definition Task.hh:234
RetT get() final
Definition Task.hh:264
Task(const Task &)=delete
The task class is supplied to thread_pool.
Definition Task.hh:131
std::future< RetT > future_type
Definition Task.hh:135
Task & operator=(const Task &)=delete
Task(FuncT func, Args... args)
Definition Task.hh:142
future_type get_future() final
Definition Task.hh:170
void wait() final
Definition Task.hh:171
std::promise< RetT > promise_type
Definition Task.hh:134
std::tuple< Args... > tuple_type
Definition Task.hh:138
Task(bool _is_native, intmax_t _depth, FuncT func, Args... args)
Definition Task.hh:149
Task(const Task &)=delete
RetT result_type
Definition Task.hh:137
RetT get() final
Definition Task.hh:172
std::packaged_task< RetT(Args...)> packaged_task_type
Definition Task.hh:136
Task(Task &&) noexcept=default
~Task() override=default
VTask is the abstract class stored in thread_pool.
Definition VTask.hh:43