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