Iros
 
Loading...
Searching...
No Matches
as_awaitable.h
Go to the documentation of this file.
1#pragma once
2
9#include "di/meta/core.h"
10
11namespace di::execution {
12namespace as_awaitable_ns {
13 template<typename Send, typename Promise>
14 struct AwaitableReceiver<Send, Promise>::Type {
15 using is_receiver = void;
16
19
22
23 private:
24 template<typename... Args>
25 requires(concepts::ConstructibleFrom<Result, Args...>)
26 friend void tag_invoke(SetValue, Type&& self, Args&&... args) {
27 self.result_pointer->emplace(util::forward<Args>(args)...);
28 self.continuation.resume();
29 }
30
31 friend void tag_invoke(SetError, Type&& self, Error error) {
32 static_cast<CoroutineHandle<>>(self.continuation.promise().unhandled_error(util::move(error))).resume();
33 }
34
35 friend void tag_invoke(SetStopped, Type&& self) {
36 static_cast<CoroutineHandle<>>(self.continuation.promise().unhandled_stopped()).resume();
37 }
38
39 constexpr friend auto tag_invoke(types::Tag<get_env> tag, Type const& self) -> decltype(auto) {
40 return tag(self.continuation.promise());
41 }
42 };
43
44 template<typename Send, typename Promise>
46 struct Type {
47 private:
51
52 public:
53 explicit Type(Send&& sender, Promise& promise)
54 : m_state(connect(
55 util::forward<Send>(sender),
56 Receiver { util::addressof(m_result), CoroutineHandle<Promise>::from_promise(promise) })) {}
57
58 auto await_ready() const noexcept -> bool { return false; }
59 void await_suspend(CoroutineHandle<>) noexcept { start(m_state); }
60 auto await_resume() -> Value {
61 if constexpr (!concepts::LanguageVoid<Value>) {
62 return util::move(m_result).value();
63 }
64 }
65
66 private:
67 Optional<Result> m_result {};
69 };
70 };
71
72 template<typename Send, typename Promise>
74
75 struct DummyPromise {
76 auto get_return_object() noexcept -> DummyPromise;
77 auto initial_suspend() noexcept -> SuspendAlways;
78 auto final_suspend() noexcept -> SuspendAlways;
79 void unhandled_exception() noexcept;
80 void return_void() noexcept;
81
82 auto unhandled_stopped() noexcept -> std::coroutine_handle<>;
83 auto unhandled_error(vocab::Error) noexcept -> std::coroutine_handle<>;
84 };
85
86 struct Function {
87 template<typename T, typename Promise>
88 constexpr auto operator()(T&& value, Promise& promise) const -> decltype(auto) {
91 "Customizations of di::as_awaitable() must return an Awaitable.");
92 return function::tag_invoke(*this, util::forward<T>(value), promise);
93 } else if constexpr (concepts::IsAwaitable<T, DummyPromise>) {
94 return util::forward<T>(value);
95 } else if constexpr (concepts::AwaitableSender<T, Promise>) {
96 return SenderAwaitable<T, Promise> { util::forward<T>(value), promise };
97 }
98 }
99 };
100}
101
103}
104
105namespace di {
107}
Definition optional_forward_declaration.h:5
Definition awaitable_sender.h:16
Definition operations.h:11
Definition is_awaitable.h:36
Definition core.h:128
Definition tag_invoke.h:33
Definition awaitable_sender.h:7
meta::Type< SenderAwaitableT< Send, Promise > > SenderAwaitable
Definition as_awaitable.h:73
Definition bulk.h:30
constexpr auto start
Definition start.h:20
constexpr auto connect
Definition connect.h:42
constexpr as_awaitable_ns::Function as_awaitable
Definition as_awaitable.h:102
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
detail::ConditionalHelper< value, T, U >::Type Conditional
Definition core.h:88
T::Type Type
Definition core.h:26
decltype(execution::connect(util::declval< Send >(), util::declval< Rec >())) ConnectResult
Definition connect_result.h:7
ValueTypesOf< Send, Env, detail::SingleSenderValueTypeHelper, detail::SingleSenderValueTypeHelper > SingleSenderValueType
Definition single_sender_value_type.h:22
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
Definition lazy.h:165
StatusCode< Erased< long > > Error
Definition error.h:8
Definition zstring_parser.h:9
std::coroutine_handle< Promise > CoroutineHandle
Definition coroutine.h:164
std::suspend_always SuspendAlways
Definition coroutine.h:169
Definition enable_generate_structed_bindings.h:46
Definition set_error.h:6
Definition set_stopped.h:6
Definition set_value.h:6
meta::Conditional< concepts::LanguageVoid< Value >, Void, Value > Result
Definition as_awaitable.h:18
friend void tag_invoke(SetError, Type &&self, Error error)
Definition as_awaitable.h:31
friend void tag_invoke(SetValue, Type &&self, Args &&... args)
Definition as_awaitable.h:26
constexpr friend auto tag_invoke(types::Tag< get_env > tag, Type const &self) -> decltype(auto)
Definition as_awaitable.h:39
friend void tag_invoke(SetStopped, Type &&self)
Definition as_awaitable.h:35
CoroutineHandle< Promise > continuation
Definition as_awaitable.h:21
Optional< Result > * result_pointer
Definition as_awaitable.h:20
meta::SingleSenderValueType< Send, meta::EnvOf< Promise > > Value
Definition as_awaitable.h:17
auto unhandled_stopped() noexcept -> std::coroutine_handle<>
auto initial_suspend() noexcept -> SuspendAlways
auto final_suspend() noexcept -> SuspendAlways
auto get_return_object() noexcept -> DummyPromise
auto unhandled_error(vocab::Error) noexcept -> std::coroutine_handle<>
Definition as_awaitable.h:86
constexpr auto operator()(T &&value, Promise &promise) const -> decltype(auto)
Definition as_awaitable.h:88
auto await_resume() -> Value
Definition as_awaitable.h:60
void await_suspend(CoroutineHandle<>) noexcept
Definition as_awaitable.h:59
auto await_ready() const noexcept -> bool
Definition as_awaitable.h:58
Type(Send &&sender, Promise &promise)
Definition as_awaitable.h:53
Definition void.h:6