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 T>
25class Task final {
27
28 public:
29 static_assert(Check<V>(), "V should be valid");
30
31 using Result = typename T::template Result<V>;
32 static_assert(!std::is_same_v<V, typename T::Error>,
33 "V cannot be the same as the trait Error type, because callback dispatch would be ambiguous");
34
35 Task(const Task&) = delete;
36 Task& operator=(const Task&) = delete;
37
38 Task(Task&& other) noexcept = default;
39 Task& operator=(Task&& other) noexcept = default;
40
43 if (Valid()) {
44 std::move(*this).Cancel();
45 }
46 }
47
49 return _core != nullptr;
50 }
51
52 /**
53 * Check that \ref Result that corresponds to this \ref Task is computed
54 *
55 * \return false if the \ref Result of this \ref Task is not computed yet, otherwise true
56 */
59 return !_core->Empty();
60 }
61
62 /**
63 * Do nothing, just for compatibility with FutureOn
64 * TODO(MBkkt) think about force On/Detach/ToFuture:
65 * It's able to set passed executor to previous nullptr/all/head/etc or replace
66 */
67 Task<V, T> On(std::nullptr_t) && noexcept {
68 return {std::move(this->_core)};
69 }
70
71 template <typename Func>
72 /*Task*/ auto Then(IExecutor& e, Func&& f) && {
74 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Call | CoreType::Lazy;
75 return detail::SetCallback<CoreT, false>(_core, &e, std::forward<Func>(f));
76 }
77 template <typename Func>
78 /*Task*/ auto ThenInline(Func&& f) && {
80 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Lazy;
81 return detail::SetCallback<CoreT, false>(_core, nullptr, std::forward<Func>(f));
82 }
83 template <typename Func>
84 /*Task*/ auto Then(Func&& f) && {
86 static constexpr auto CoreT = CoreType::ToUnique | CoreType::Call | CoreType::Lazy;
87 return detail::SetCallback<CoreT, false>(_core, nullptr, std::forward<Func>(f));
88 }
89
90 void Cancel() && noexcept {
91 std::move(*this).Detach(MakeInline(StopTag{}));
92 }
93
94 void Detach() && noexcept {
96 auto* core = _core.Release();
97 core->StoreCallback(detail::MakeDrop());
98 detail::Start(core);
99 }
100 void Detach(IExecutor& e) && noexcept {
102 auto* core = _core.Release();
103 core->StoreCallback(detail::MakeDrop());
104 detail::Start(core, e);
105 }
106
107 Future<V, T> ToFuture() && noexcept {
109 detail::Start(_core.Get());
110 return {std::move(_core)};
111 }
114 detail::Start(_core.Get(), e);
115 return {std::move(_core)};
116 }
117
118 Result Get() && noexcept {
119 // TODO(MBkkt) make it better: we can remove concurrent atomic changes from here
120 return std::move(*this).ToFuture().Get();
121 }
122
123 void Touch() & = delete;
124 void Touch() const&& = delete;
125
128 return _core->Get();
129 }
130 Result Touch() && noexcept {
132 auto core = std::exchange(_core, nullptr);
133 return std::move(core->Get());
134 }
135
136 /**
137 * Method that get internal Core state
138 *
139 * \return internal Core state ptr
140 */
142 return _core;
143 }
144 Task(detail::UniqueCorePtr<V, T> core) noexcept : _core{std::move(core)} {
145 }
146
147 private:
148 detail::UniqueCorePtr<V, T> _core;
149};
150
151extern template class Task<>;
152
153} // namespace yaclib
Provides a mechanism to access the result of async operations.
Definition future.hpp:247
Provides a mechanism to access the result of async operations.
Definition future.hpp:213
A intrusive pointer to objects with an embedded reference count.
Provides a mechanism to schedule the some async operations TODO(MBkkt) add description.
Definition task.hpp:25
Task & operator=(const Task &)=delete
detail::UniqueCorePtr< V, T > & GetCore() noexcept
Method that get internal Core state.
Definition task.hpp:141
Future< V, T > ToFuture() &&noexcept
Definition task.hpp:107
auto Then(Func &&f) &&
Definition task.hpp:84
void Touch() &=delete
void Detach(IExecutor &e) &&noexcept
Definition task.hpp:100
Task & operator=(Task &&other) noexcept=default
Task() noexcept=default
auto Then(IExecutor &e, Func &&f) &&
Definition task.hpp:72
bool Ready() const &noexcept
Check that Result that corresponds to this Task is computed.
Definition task.hpp:57
void Touch() const &&=delete
Task(detail::UniqueCorePtr< V, T > core) noexcept
Definition task.hpp:144
Result Get() &&noexcept
Definition task.hpp:118
bool Valid() const &noexcept
Definition task.hpp:48
typename T::template Result< V > Result
Definition task.hpp:31
Task(Task &&other) noexcept=default
void Cancel() &&noexcept
Definition task.hpp:90
Task< V, T > On(std::nullptr_t) &&noexcept
Do nothing, just for compatibility with FutureOn TODO(MBkkt) think about force On/Detach/ToFuture: It...
Definition task.hpp:67
Task(const Task &)=delete
auto ThenInline(Func &&f) &&
Definition task.hpp:78
FutureOn< V, T > ToFuture(IExecutor &e) &&noexcept
Definition task.hpp:112
Result Touch() &&noexcept
Definition task.hpp:130
void Detach() &&noexcept
Definition task.hpp:94
#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
Contract< V, T > MakeContract()
Creates related future and promise.
Definition contract.hpp:25
IExecutor & MakeInline() noexcept
Get Inline executor singleton object.
Definition inline.cpp:34