File indexing completed on 2025-01-30 10:07:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #pragma once
0032
0033 #include "PTL/Globals.hh"
0034 #include "PTL/VTask.hh"
0035
0036 #include <cstdint>
0037 #include <future>
0038 #include <tuple>
0039 #include <utility>
0040
0041 namespace PTL
0042 {
0043
0044
0045
0046 template <typename RetT>
0047 class TaskFuture : public VTask
0048 {
0049 public:
0050 using promise_type = std::promise<RetT>;
0051 using future_type = std::future<RetT>;
0052 using result_type = RetT;
0053
0054 public:
0055
0056 template <typename... Args>
0057 TaskFuture(Args&&... args)
0058 : VTask{ std::forward<Args>(args)... }
0059 {}
0060
0061 ~TaskFuture() override = default;
0062
0063 TaskFuture(const TaskFuture&) = delete;
0064 TaskFuture& operator=(const TaskFuture&) = delete;
0065
0066 TaskFuture(TaskFuture&&) noexcept = default;
0067 TaskFuture& operator=(TaskFuture&&) noexcept = default;
0068
0069 public:
0070
0071 virtual future_type get_future() = 0;
0072 virtual void wait() = 0;
0073 virtual RetT get() = 0;
0074 };
0075
0076
0077
0078
0079 template <typename RetT, typename... Args>
0080 class PackagedTask : public TaskFuture<RetT>
0081 {
0082 public:
0083 using this_type = PackagedTask<RetT, Args...>;
0084 using promise_type = std::promise<RetT>;
0085 using future_type = std::future<RetT>;
0086 using packaged_task_type = std::packaged_task<RetT(Args...)>;
0087 using result_type = RetT;
0088 using tuple_type = std::tuple<Args...>;
0089
0090 public:
0091
0092 template <typename FuncT>
0093 PackagedTask(FuncT func, Args... args)
0094 : TaskFuture<RetT>{ true, 0 }
0095 , m_ptask{ std::move(func) }
0096 , m_args{ args... }
0097 {}
0098
0099 template <typename FuncT>
0100 PackagedTask(bool _is_native, intmax_t _depth, FuncT func, Args... args)
0101 : TaskFuture<RetT>{ _is_native, _depth }
0102 , m_ptask{ std::move(func) }
0103 , m_args{ args... }
0104 {}
0105
0106 ~PackagedTask() override = default;
0107
0108 PackagedTask(const PackagedTask&) = delete;
0109 PackagedTask& operator=(const PackagedTask&) = delete;
0110
0111 PackagedTask(PackagedTask&&) noexcept = default;
0112 PackagedTask& operator=(PackagedTask&&) noexcept = default;
0113
0114 public:
0115
0116 void operator()() final { mpl::apply(std::move(m_ptask), std::move(m_args)); }
0117 future_type get_future() final { return m_ptask.get_future(); }
0118 void wait() final { return m_ptask.get_future().wait(); }
0119 RetT get() final { return m_ptask.get_future().get(); }
0120
0121 private:
0122 packaged_task_type m_ptask;
0123 tuple_type m_args;
0124 };
0125
0126
0127
0128
0129 template <typename RetT, typename... Args>
0130 class Task : public TaskFuture<RetT>
0131 {
0132 public:
0133 using this_type = Task<RetT, Args...>;
0134 using promise_type = std::promise<RetT>;
0135 using future_type = std::future<RetT>;
0136 using packaged_task_type = std::packaged_task<RetT(Args...)>;
0137 using result_type = RetT;
0138 using tuple_type = std::tuple<Args...>;
0139
0140 public:
0141 template <typename FuncT>
0142 Task(FuncT func, Args... args)
0143 : TaskFuture<RetT>{}
0144 , m_ptask{ std::move(func) }
0145 , m_args{ args... }
0146 {}
0147
0148 template <typename FuncT>
0149 Task(bool _is_native, intmax_t _depth, FuncT func, Args... args)
0150 : TaskFuture<RetT>{ _is_native, _depth }
0151 , m_ptask{ std::move(func) }
0152 , m_args{ args... }
0153 {}
0154
0155 ~Task() override = default;
0156
0157 Task(const Task&) = delete;
0158 Task& operator=(const Task&) = delete;
0159
0160 Task(Task&&) noexcept = default;
0161 Task& operator=(Task&&) noexcept = default;
0162
0163 public:
0164
0165 void operator()() final
0166 {
0167 if(m_ptask.valid())
0168 mpl::apply(std::move(m_ptask), std::move(m_args));
0169 }
0170 future_type get_future() final { return m_ptask.get_future(); }
0171 void wait() final { return m_ptask.get_future().wait(); }
0172 RetT get() final { return m_ptask.get_future().get(); }
0173
0174 private:
0175 packaged_task_type m_ptask{};
0176 tuple_type m_args{};
0177 };
0178
0179
0180
0181
0182 template <typename RetT>
0183 class Task<RetT, void> : public TaskFuture<RetT>
0184 {
0185 public:
0186 using this_type = Task<RetT>;
0187 using promise_type = std::promise<RetT>;
0188 using future_type = std::future<RetT>;
0189 using packaged_task_type = std::packaged_task<RetT()>;
0190 using result_type = RetT;
0191
0192 public:
0193 template <typename FuncT>
0194 Task(FuncT func)
0195 : TaskFuture<RetT>()
0196 , m_ptask{ std::move(func) }
0197 {}
0198
0199 template <typename FuncT>
0200 Task(bool _is_native, intmax_t _depth, FuncT func)
0201 : TaskFuture<RetT>{ _is_native, _depth }
0202 , m_ptask{ std::move(func) }
0203 {}
0204
0205 virtual ~Task() = default;
0206
0207 Task(const Task&) = delete;
0208 Task& operator=(const Task&) = delete;
0209
0210 Task(Task&&) noexcept = default;
0211 Task& operator=(Task&&) noexcept = default;
0212
0213 public:
0214
0215 virtual void operator()() final { m_ptask(); }
0216 virtual future_type get_future() final { return m_ptask.get_future(); }
0217 virtual void wait() final { return m_ptask.get_future().wait(); }
0218 virtual RetT get() final { return m_ptask.get_future().get(); }
0219
0220 private:
0221 packaged_task_type m_ptask{};
0222 };
0223
0224
0225
0226
0227 template <>
0228 class Task<void, void> : public TaskFuture<void>
0229 {
0230 public:
0231 using RetT = void;
0232 using this_type = Task<void, void>;
0233 using promise_type = std::promise<RetT>;
0234 using future_type = std::future<RetT>;
0235 using packaged_task_type = std::packaged_task<RetT()>;
0236 using result_type = RetT;
0237
0238 public:
0239 template <typename FuncT>
0240 explicit Task(FuncT func)
0241 : TaskFuture<RetT>{}
0242 , m_ptask{ std::move(func) }
0243 {}
0244
0245 template <typename FuncT>
0246 Task(bool _is_native, intmax_t _depth, FuncT func)
0247 : TaskFuture<RetT>{ _is_native, _depth }
0248 , m_ptask{ std::move(func) }
0249 {}
0250
0251 ~Task() override = default;
0252
0253 Task(const Task&) = delete;
0254 Task& operator=(const Task&) = delete;
0255
0256 Task(Task&&) = default;
0257 Task& operator=(Task&&) = default;
0258
0259 public:
0260
0261 void operator()() final { m_ptask(); }
0262 future_type get_future() final { return m_ptask.get_future(); }
0263 void wait() final { return m_ptask.get_future().wait(); }
0264 RetT get() final { return m_ptask.get_future().get(); }
0265
0266 private:
0267 packaged_task_type m_ptask{};
0268 };
0269
0270
0271
0272 }