Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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