34 constexpr
static bool IsVoid =
false;
38 template<
typename U = R>
41 std::lock_guard guard {
self };
42 self.Ret_.emplace (std::forward<U> (val));
55 std::lock_guard guard {
self };
62 template<
typename Promise>
65 using Handle_t = std::coroutine_handle<Promise>;
74 :
Subtask_ { std::exchange (other.Subtask_, {}) }
85 Subtask_.promise ().Continuation_.exchange ({});
90 const auto& promise =
Subtask_.promise ();
91 std::lock_guard guard { promise };
92 return CheckTaskFinishedUnlocked (promise);
98 std::lock_guard guard { promise };
99 if (CheckTaskFinishedUnlocked (promise))
102 if (promise.Continuation_.exchange (handle))
103 qFatal () <<
"subtask has already been awaited on";
109 const auto& promise =
Subtask_.promise ();
110 std::lock_guard guard { promise };
111 if (promise.Exception_)
114 std::rethrow_exception (promise.Exception_);
120 if constexpr (!Promise::IsVoid)
121 return *promise.Ret_;
124 bool CheckTaskFinishedUnlocked (
const Promise& promise)
const 126 if (promise.Exception_)
129 if constexpr (Promise::IsVoid)
130 return promise.Done_;
132 return static_cast<bool> (promise.Ret_);
153 template<
typename R,
template<
typename>
typename... Extensions>
159 using Handle_t = std::coroutine_handle<promise_type>;
163 , Extensions<promise_type>...
167 if constexpr (
requires { this->DoLock (); })
173 if constexpr (
requires { this->DoUnlock (); })
177 auto GetAddress () {
return Handle_t::from_promise (*this).address (); }
181 return Task { Handle_t::from_promise (*
this) };
190 static_cast<void> (
this);
191 using Base = Extensions<promise_type>;
192 if constexpr (
requires (Base t) { t.FinalSuspend (); })
193 Base::FinalSuspend ();
205 this->
Refs_.fetch_add (1);
210 if (this->
Refs_.fetch_sub (1) == 1)
211 Handle_t::from_promise (*this).destroy ();
217 template<
typename RR>
220 template<
template<
typename>
typename F>
223 explicit Task (
const std::coroutine_handle<promise_type>& handle)
227 handle.promise ().IncRef ();
233 Handle_.promise ().DecRef ();
237 : Handle_ { other.Handle_ }
240 Handle_.promise ().IncRef ();
246 *
this = std::move (task);
269 template<
typename R,
template<
typename>
typename... Extensions>
void return_value(this auto &&self, U &&val)
std::atomic< std::coroutine_handle<> > Continuation_
decltype(auto) await_resume() const noexcept
void swap(FDGuard &g1, FDGuard &g2)
Task(const std::coroutine_handle< promise_type > &handle)
Task & operator=(const Task &other)
std::coroutine_handle< Promise > Handle_t
auto final_suspend() noexcept
bool await_suspend(std::coroutine_handle<> handle)
Task(Task &&other) noexcept
TaskAwaiter(Handle_t subtask)
void unhandled_exception()
TaskAwaiter & operator=(const TaskAwaiter &)=delete
bool await_suspend(std::coroutine_handle< Promise > handle) noexcept
requires(Tup1Size==Tup2Size) const expr auto ZipWith(Tup1 &&tup1
bool await_ready() const noexcept
TaskAwaiter(TaskAwaiter &&other) noexcept
static constexpr bool IsVoid
auto Tup2 &&tup2 noexcept
bool await_ready() const noexcept
std::atomic< size_t > Refs_
std::exception_ptr Exception_
typename Task< R, Extensions... >::promise_type Promise
void return_void(this auto &&self) noexcept
std::suspend_never initial_suspend() const noexcept