Geant4 Cross Reference |
1 // 1 2 // MIT License 3 // Copyright (c) 2020 Jonathan R. Madsen 4 // Permission is hereby granted, free of charg 5 // of this software and associated documentati 6 // in the Software without restriction, includ 7 // to use, copy, modify, merge, publish, distr 8 // copies of the Software, and to permit perso 9 // furnished to do so, subject to the followin 10 // The above copyright notice and this permiss 11 // all copies or substantial portions of the S 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPR 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILIT 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARIS 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALI 18 // 19 // 20 // ------------------------------------------- 21 // Tasking class header file 22 // 23 // Class Description: 24 // 25 // This file defines the task types for TaskMa 26 // 27 // ------------------------------------------- 28 // Author: Jonathan Madsen (Feb 13th 2018) 29 // ------------------------------------------- 30 31 #pragma once 32 33 #include "PTL/VTask.hh" 34 #include "PTL/detail/CxxBackports.hh" 35 36 #include <cstdint> 37 #include <future> 38 #include <tuple> 39 #include <utility> 40 41 namespace PTL 42 { 43 //============================================ 44 45 /// \brief The task class is supplied to threa 46 template <typename RetT> 47 class TaskFuture : public VTask 48 { 49 public: 50 using promise_type = std::promise<RetT>; 51 using future_type = std::future<RetT>; 52 using result_type = RetT; 53 54 public: 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&) = 65 66 TaskFuture(TaskFuture&&) noexcept = defaul 67 TaskFuture& operator=(TaskFuture&&) noexce 68 69 public: 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 threa 79 template <typename RetT, typename... Args> 80 class PackagedTask : public TaskFuture<RetT> 81 { 82 public: 83 using this_type = PackagedTask<Re 84 using promise_type = std::promise<Re 85 using future_type = std::future<Ret 86 using packaged_task_type = std::packaged_t 87 using result_type = RetT; 88 using tuple_type = std::tuple<Args 89 90 public: 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 _de 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 109 PackagedTask& operator=(const PackagedTask 110 111 PackagedTask(PackagedTask&&) noexcept = de 112 PackagedTask& operator=(PackagedTask&&) no 113 114 public: 115 // execution operator 116 void operator()() final { PTL::appl 117 future_type get_future() final { return m_ 118 void wait() final { return m_ptask. 119 RetT get() final { return m_ptask.g 120 121 private: 122 packaged_task_type m_ptask; 123 tuple_type m_args; 124 }; 125 126 //============================================ 127 128 /// \brief The task class is supplied to threa 129 template <typename RetT, typename... Args> 130 class Task : public TaskFuture<RetT> 131 { 132 public: 133 using this_type = Task<RetT, Args 134 using promise_type = std::promise<Re 135 using future_type = std::future<Ret 136 using packaged_task_type = std::packaged_t 137 using result_type = RetT; 138 using tuple_type = std::tuple<Args 139 140 public: 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, Fun 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 163 public: 164 // execution operator 165 void operator()() final 166 { 167 if(m_ptask.valid()) 168 PTL::apply(std::move(m_ptask), std 169 } 170 future_type get_future() final { return m_ 171 void wait() final { return m_ptask. 172 RetT get() final { return m_ptask.g 173 174 private: 175 packaged_task_type m_ptask{}; 176 tuple_type m_args{}; 177 }; 178 179 //============================================ 180 181 /// \brief The task class is supplied to threa 182 template <typename RetT> 183 class Task<RetT, void> : public TaskFuture<Ret 184 { 185 public: 186 using this_type = Task<RetT>; 187 using promise_type = std::promise<Re 188 using future_type = std::future<Ret 189 using packaged_task_type = std::packaged_t 190 using result_type = RetT; 191 192 public: 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, Fun 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 213 public: 214 // execution operator 215 virtual void operator()() final { m 216 virtual future_type get_future() final { r 217 virtual void wait() final { return 218 virtual RetT get() final { return m 219 220 private: 221 packaged_task_type m_ptask{}; 222 }; 223 224 //============================================ 225 226 /// \brief The task class is supplied to threa 227 template <> 228 class Task<void, void> : public TaskFuture<voi 229 { 230 public: 231 using RetT = void; 232 using this_type = Task<void, void 233 using promise_type = std::promise<Re 234 using future_type = std::future<Ret 235 using packaged_task_type = std::packaged_t 236 using result_type = RetT; 237 238 public: 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, Fun 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 259 public: 260 // execution operator 261 void operator()() final { m_ptask() 262 future_type get_future() final { return m_ 263 void wait() final { return m_ptask. 264 RetT get() final { return m_ptask.g 265 266 private: 267 packaged_task_type m_ptask{}; 268 }; 269 270 //============================================ 271 272 } // namespace PTL 273