YACLib
C++ library for concurrent tasks execution
Loading...
Searching...
No Matches
task.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <yaclib/fwd.hpp>
11
12namespace yaclib {
13namespace detail {
14
15void Start(BaseCore* head, IExecutor& e) noexcept;
16void Start(BaseCore* head) noexcept;
17
18} // namespace detail
19
20/**
21 * Provides a mechanism to schedule the some async operations
22 * TODO(MBkkt) add description
23 */
24template <typename V, typename E>
25class Task final {
27
28 public:
29 static_assert(Check<V>(), "V should be valid");
30 static_assert(Check<E>(), "E should be valid");
31 static_assert(!std::is_same_v<V, E>, "Task cannot be instantiated with same V and E, because it's ambiguous");
32
33 Task(const Task&) = delete;
34 Task& operator=(const Task&) = delete;
35
36 Task(Task&& other) noexcept = default;
37 Task& operator=(Task&& other) noexcept = default;
38
41 if (Valid()) {
42 std::move(*this).Cancel();
43 }
44 }
45
47 return _core != nullptr;
48 }
49
50 /**
51 * Check that \ref Result that corresponds to this \ref Task is computed
52 *
53 * \return false if the \ref Result of this \ref Task is not computed yet, otherwise true
54 */
57 return !_core->Empty();
58 }
59
60 /**
61 * Do nothing, just for compatibility with FutureOn
62 * TODO(MBkkt) think about force On/Detach/ToFuture:
63 * It's able to set passed executor to previous nullptr/all/head/etc or replace
64 */
65 Task<V, E> On(std::nullptr_t) && noexcept {
66 return {std::move(this->_core)};
67 }
68
69 template <typename Func>
70 /*Task*/ auto Then(IExecutor& e, Func&& f) && {
72 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Call | CoreType::Lazy;
73 return detail::SetCallback<CoreT, false>(_core, &e, std::forward<Func>(f));
74 }
75 template <typename Func>
76 /*Task*/ auto ThenInline(Func&& f) && {
78 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Lazy;
79 return detail::SetCallback<CoreT, false>(_core, nullptr, std::forward<Func>(f));
80 }
81 template <typename Func>
82 /*Task*/ auto Then(Func&& f) && {
84 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Call | CoreType::Lazy;
85 return detail::SetCallback<CoreT, false>(_core, nullptr, std::forward<Func>(f));
86 }
87
88 void Cancel() && noexcept {
89 std::move(*this).Detach(MakeInline(StopTag{}));
90 }
91
92 void Detach() && noexcept {
94 auto* core = _core.Release();
95 core->StoreCallback(detail::MakeDrop());
96 detail::Start(core);
97 }
98 void Detach(IExecutor& e) && noexcept {
100 auto* core = _core.Release();
101 core->StoreCallback(detail::MakeDrop());
102 detail::Start(core, e);
103 }
104
105 Future<V, E> ToFuture() && noexcept {
107 detail::Start(_core.Get());
108 return {std::move(_core)};
109 }
112 detail::Start(_core.Get(), e);
113 return {std::move(_core)};
114 }
115
116 Result<V, E> Get() && noexcept {
117 // TODO(MBkkt) make it better: we can remove concurrent atomic changes from here
118 return std::move(*this).ToFuture().Get();
119 }
120
121 void Touch() & = delete;
122 void Touch() const&& = delete;
123
126 return _core->Get();
127 }
128 Result<V, E> Touch() && noexcept {
130 auto core = std::exchange(_core, nullptr);
131 return std::move(core->Get());
132 }
133
134 /**
135 * Method that get internal Core state
136 *
137 * \return internal Core state ptr
138 */
140 return _core;
141 }
142 Task(detail::UniqueCorePtr<V, E> core) noexcept : _core{std::move(core)} {
143 }
144
145 private:
146 detail::UniqueCorePtr<V, E> _core;
147};
148
149extern template class Task<>;
150
151} // namespace yaclib
Provides a mechanism to access the result of async operations.
Definition future.hpp:244
Provides a mechanism to access the result of async operations.
Definition future.hpp:210
A intrusive pointer to objects with an embedded reference count.
Encapsulated return value from caller.
Definition result.hpp:90
Provides a mechanism to schedule the some async operations TODO(MBkkt) add description.
Definition task.hpp:25
Task & operator=(const Task &)=delete
Result< V, E > Touch() &&noexcept
Definition task.hpp:128
auto ThenInline(Func &&f) &&
Definition task.hpp:76
bool Ready() const &noexcept
Check that Result that corresponds to this Task is computed.
Definition task.hpp:55
void Touch() const &&=delete
detail::UniqueCorePtr< V, E > & GetCore() noexcept
Method that get internal Core state.
Definition task.hpp:139
void Cancel() &&noexcept
Definition task.hpp:88
auto Then(Func &&f) &&
Definition task.hpp:82
Task< V, E > On(std::nullptr_t) &&noexcept
Do nothing, just for compatibility with FutureOn TODO(MBkkt) think about force On/Detach/ToFuture: It...
Definition task.hpp:65
Task() noexcept=default
void Detach() &&noexcept
Definition task.hpp:92
Task(detail::UniqueCorePtr< V, E > core) noexcept
Definition task.hpp:142
Task(Task &&other) noexcept=default
void Detach(IExecutor &e) &&noexcept
Definition task.hpp:98
bool Valid() const &noexcept
Definition task.hpp:46
Future< V, E > ToFuture() &&noexcept
Definition task.hpp:105
Result< V, E > Get() &&noexcept
Definition task.hpp:116
auto Then(IExecutor &e, Func &&f) &&
Definition task.hpp:70
Task(const Task &)=delete
FutureOn< V, E > ToFuture(IExecutor &e) &&noexcept
Definition task.hpp:110
Task & operator=(Task &&other) noexcept=default
void Touch() &=delete
#define YACLIB_ASSERT(cond)
Definition log.hpp:85
InlineCore & MakeDrop() noexcept
Definition drop_core.cpp:27
void Start(BaseCore *head, IExecutor &e) noexcept
Definition task_impl.cpp:6
IExecutor & MakeInline() noexcept
Get Inline executor singleton object.
Definition inline.cpp:34
Contract< V, E > MakeContract()
Creates related future and promise.
Definition contract.hpp:25