Fenix @develop
 
Loading...
Searching...
No Matches
subtask.hpp
1#ifndef FENIX_TASKS_SUBTASK_HPP
2#define FENIX_TASKS_SUBTASK_HPP
3
4#include <coroutine>
5#include <exception>
6#include <memory>
7
8namespace fenix::tasks {
9
10template <typename T>
11concept Subtaskable = requires(T t) {
12 { t.done() } -> std::same_as<bool>;
13 t.resume();
14 t.wait();
15 t.result();
16};
17
19 public:
20 virtual ~SubtaskBase() = default;
21
22 virtual bool done() const = 0;
23 virtual void resume() const = 0;
24 virtual void wait() const = 0;
25};
26
27namespace impl {
28template <Subtaskable T>
30 using U = std::remove_reference_t<T>;
31 SubtaskHolder(T&& t) : task(std::make_shared<U>(std::move(t))) {}
32 U* operator->() { return task.get(); }
33 std::shared_ptr<U> task;
34};
35template <Subtaskable T>
36struct SubtaskHolder<T&> {
37 SubtaskHolder(T& t) : task(t) {};
38 T* operator->() { return &task; }
39 T& task;
40};
41} // namespace impl
42
43template <Subtaskable T>
44class Subtask : public SubtaskBase {
45 public:
47
48 Subtask(T&& t) : task(std::forward<T>(t)) {};
49 ~Subtask() = default;
50
51 HolderT& operator->() const { return task; }
52
53 bool done() const override { return task->done(); }
54 void resume() const override { task->resume(); }
55 void wait() const override {
56 task->wait();
57 assert(task->done());
58 }
59 auto result() const {
60 assert(task->done());
61 return task->result();
62 }
63
64 mutable HolderT task;
65};
66
67} // namespace fenix::tasks
68
69#endif //FENIX_TASKS_SUBTASK_HPP
Definition subtask.hpp:18
Definition subtask.hpp:44
Definition subtask.hpp:11
Definition subtask.hpp:29