Iros
 
Loading...
Searching...
No Matches
then.h
Go to the documentation of this file.
1#pragma once
2
19#include "di/function/invoke.h"
21#include "di/meta/algorithm.h"
22#include "di/meta/core.h"
23#include "di/meta/language.h"
24#include "di/meta/util.h"
25#include "di/meta/vocab.h"
27#include "di/util/addressof.h"
28
29namespace di::execution {
30namespace then_ns {
31 template<typename CPO, typename Completions>
33
34 template<typename CPO, typename Completions>
35 using ArgTypes =
37
38 template<typename CPO, typename Fun, typename Completions>
41
42 template<typename T>
43 struct ComplSigT : meta::TypeConstant<SetValue(T)> {};
44
45 template<>
46 struct ComplSigT<void> : meta::TypeConstant<SetValue()> {};
47
48 template<typename T>
50
51 template<typename T>
52 struct InvokeSigsT : meta::TypeConstant<meta::List<ComplSig<T>>> {};
53
54 template<concepts::Expected T>
55 struct InvokeSigsT<T>
56 : meta::TypeConstant<meta::List<ComplSig<meta::ExpectedValue<T>>, SetError(meta::ExpectedError<T>)>> {};
57
58 template<typename T>
60
61 template<typename CPO, typename Send, typename Env, typename Fun>
67
68 template<typename Fun, typename Rec>
69 struct DataT {
70 struct Type {
71#ifdef DI_CLANG
72 // NOTE: Clang for some reason crashes when using [[no_unique_address]] in debug mode here. In release mode,
73 // the program itself segfaults...
74 Fun function;
75 Rec receiver;
76#else
77 [[no_unique_address]] Fun function;
78 [[no_unique_address]] Rec receiver;
79#endif
80 };
81 };
82
83 template<typename Fun, typename Rec>
85
86 template<typename CPO, typename Fun, typename Rec>
87 struct ReceiverT {
88 struct Type {
89 using is_receiver = void;
90
92
93 template<concepts::SameAs<CPO> Tg, typename... Args>
94 requires(sizeof...(Args) < 2 && concepts::Invocable<Fun, Args...> &&
98 friend void tag_invoke(Tg, Type&& self, Args&&... args) {
99 using R = meta::InvokeResult<Fun, Args...>;
100
101 auto& data = *self.data;
102 auto result = function::invoke(util::move(data.function), util::forward<Args>(args)...);
103 if (!result) {
104 execution::set_error(util::move(data.receiver), util::move(result).error());
105 } else {
107 execution::set_value(util::move(data.receiver));
108 } else {
109 execution::set_value(util::move(data.receiver), util::move(result).value());
110 }
111 }
112 }
113
114 template<concepts::SameAs<CPO> Tg, typename... Args>
115 friend void tag_invoke(Tg, Type&& self, Args&&... args)
116 requires(concepts::Invocable<Fun, Args...> && !concepts::Expected<meta::InvokeResult<Fun, Args...>> &&
118 {
119 using R = meta::InvokeResult<Fun, Args...>;
120
121 if constexpr (concepts::LanguageVoid<R>) {
122 function::invoke(util::move(self.data->function), util::forward<Args>(args)...);
123 execution::set_value(util::move(self.data->receiver));
124 } else {
126 util::move(self.data->receiver),
127 function::invoke(util::move(self.data->function), util::forward<Args>(args)...));
128 }
129 }
130
131 template<concepts::OneOf<SetValue, SetError, SetStopped> Tg, typename... Args>
132 friend void tag_invoke(Tg const tag, Type&& self, Args&&... args)
133 requires(sizeof...(Args) < 2 && !concepts::SameAs<CPO, Tg> && concepts::Invocable<Tg, Rec, Args...>)
134 {
135 tag(util::move(self.data->receiver), util::forward<Args>(args)...);
136 }
137
138 friend auto tag_invoke(Tag<get_env>, Type const& self) { return make_env(get_env(self.data->receiver)); }
139 };
140 };
141
142 template<typename CPO, typename Fun, typename Rec>
144
145 template<typename CPO, typename Send, typename Fun, typename Rec>
148 private:
149 using Rc = Receiver<CPO, Fun, Rec>;
151
152 public:
153 explicit Type(Send&& sender, Fun&& function, Rec receiver)
154 : m_data(util::forward<Fun>(function), util::move(receiver))
155 , m_operation(connect(util::forward<Send>(sender), Rc(util::addressof(m_data)))) {}
156
157 private:
158 friend void tag_invoke(Tag<start>, Type& self) { start(self.m_operation); }
159
160 Data<Fun, Rec> m_data;
161 Op m_operation;
162 };
163 };
164
165 template<typename CPO, typename Send, typename Fun, typename Rec>
167
168 template<typename CPO, typename Send, typename Fun>
169 struct SenderT {
170 struct Type {
171 using is_sender = void;
172
173 [[no_unique_address]] Send sender;
174 [[no_unique_address]] Fun function;
175
176 template<concepts::RemoveCVRefSameAs<Type> Self, typename E>
180 return {};
181 }
182
183 template<concepts::RemoveCVRefSameAs<Type> Self, typename Rec>
186 friend auto tag_invoke(Tag<connect>, Self&& self, Rec receiver) {
188 di::forward_like<Self>(self.sender), di::forward_like<Self>(self.function), util::move(receiver));
189 }
190
191 friend auto tag_invoke(Tag<get_env>, Type const& self) { return make_env(get_env(self.sender)); }
192 };
193 };
194
195 template<typename CPO, typename Send, typename Fun>
197
199 template<concepts::Sender Send, concepts::MovableValue Fun>
200 auto operator()(Send&& sender, Fun&& function) const -> concepts::Sender auto {
201 if constexpr (requires {
203 util::forward<Send>(sender), util::forward<Fun>(function));
204 }) {
206 util::forward<Send>(sender), util::forward<Fun>(function));
207 } else if constexpr (requires {
208 function::tag_invoke(*this, util::forward<Send>(sender),
209 util::forward<Fun>(function));
210 }) {
211 return function::tag_invoke(*this, util::forward<Send>(sender), util::forward<Fun>(function));
212 } else {
213 return Sender<SetValue, Send, Fun> { util::forward<Send>(sender), util::forward<Fun>(function) };
214 }
215 }
216 };
217
219 template<concepts::Sender Send, concepts::MovableValue Fun>
220 auto operator()(Send&& sender, Fun&& function) const -> concepts::Sender auto {
221 if constexpr (requires {
223 util::forward<Send>(sender), util::forward<Fun>(function));
224 }) {
226 util::forward<Send>(sender), util::forward<Fun>(function));
227 } else if constexpr (requires {
228 function::tag_invoke(*this, util::forward<Send>(sender),
229 util::forward<Fun>(function));
230 }) {
231 return function::tag_invoke(*this, util::forward<Send>(sender), util::forward<Fun>(function));
232 } else {
233 return Sender<SetError, Send, Fun> { util::forward<Send>(sender), util::forward<Fun>(function) };
234 }
235 }
236 };
237
239 template<concepts::Sender Send, concepts::MovableValue Fun>
240 auto operator()(Send&& sender, Fun&& function) const -> concepts::Sender auto {
241 if constexpr (requires {
243 util::forward<Send>(sender), util::forward<Fun>(function));
244 }) {
246 util::forward<Send>(sender), util::forward<Fun>(function));
247 } else if constexpr (requires {
248 function::tag_invoke(*this, util::forward<Send>(sender),
249 util::forward<Fun>(function));
250 }) {
251 return function::tag_invoke(*this, util::forward<Send>(sender), util::forward<Fun>(function));
252 } else {
253 return Sender<SetStopped, Send, Fun> { util::forward<Send>(sender), util::forward<Fun>(function) };
254 }
255 }
256 };
257}
258
277
290
303}
Definition util.h:68
Definition vocab.h:30
Definition invoke.h:58
Definition core.h:128
Definition receiver_of.h:25
Definition core.h:114
Definition sender.h:11
Definition then.h:30
meta::Transform< meta::Filter< meta::AsList< Completions >, meta::IsFunctionTo< CPO > >, meta::Quote< meta::AsList > > ArgTypes
Definition then.h:35
meta::Type< ComplSigT< T > > ComplSig
Definition then.h:49
meta::Type< SenderT< CPO, meta::RemoveCVRef< Send >, meta::Decay< Fun > > > Sender
Definition then.h:196
meta::Filter< meta::AsList< Completions >, meta::Not< meta::IsFunctionTo< CPO > > > PassthroughSignatures
Definition then.h:32
meta::Type< ReceiverT< CPO, meta::Decay< Fun >, Rec > > Receiver
Definition then.h:143
meta::Type< OperationStateT< CPO, Send, Fun, Rec > > OperationState
Definition then.h:166
meta::AsTemplate< CompletionSignatures, meta::Concat< PassthroughSignatures< CPO, meta::CompletionSignaturesOf< Send, MakeEnv< Env > > >, meta::Join< meta::Transform< ResultTypes< CPO, Fun, meta::CompletionSignaturesOf< Send, MakeEnv< Env > > >, meta::Quote< InvokeSigs > > > > > Sigs
Definition then.h:62
meta::Transform< ArgTypes< CPO, Completions >, meta::Uncurry< meta::BindFront< meta::Quote< meta::InvokeResult >, Fun > > > ResultTypes
Definition then.h:39
meta::Type< DataT< meta::Decay< Fun >, Rec > > Data
Definition then.h:84
meta::Type< InvokeSigsT< T > > InvokeSigs
Definition then.h:59
Definition bulk.h:30
constexpr auto upon_stopped
A sender that maps the stop signal into a value.
Definition then.h:302
constexpr auto set_error
Definition set_error.h:14
constexpr auto start
Definition start.h:20
constexpr auto then
A sender that maps values into another value.
Definition then.h:276
constexpr auto make_env
Create an environment with overrides for queries.
Definition make_env.h:147
constexpr auto upon_error
A sender that maps an error into a value.
Definition then.h:289
constexpr auto get_completion_scheduler
Definition get_completion_scheduler.h:19
constexpr auto get_env
Definition get_env.h:27
constexpr auto connect
Definition connect.h:42
constexpr auto set_value
Definition set_value.h:14
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
constexpr auto curry_back
Definition curry_back.h:141
T::Type Type
Definition core.h:26
Type< detail::AsTemplateHelper< Template, T > > AsTemplate
Definition algorithm.h:60
Conditional< concepts::LanguageArray< RemoveReference< T > >, RemoveExtent< RemoveReference< T > > *, Conditional< concepts::LanguageFunction< RemoveReference< T > >, AddPointer< RemoveReference< T > >, RemoveCVRef< T > > > Decay
Definition language.h:574
Type< detail::LikeHelper< T, U > > Like
Definition language.h:468
Apply< Quote< Concat >, List > Join
Definition algorithm.h:89
Fold< List, meta::List<>, detail::FilterReducer< Pred > > Filter
Definition algorithm.h:152
decltype(function::detail::invoke_impl(util::declval< Ts >()...)) InvokeResult
Definition invoke.h:64
Type< detail::ConcatHelper< Lists... > > Concat
Definition algorithm.h:80
detail::TransformHelper< List, Function >::Type Transform
Definition algorithm.h:186
decltype(execution::get_env(util::declval< T >())) EnvOf
Definition env_of.h:8
decltype(execution::connect(util::declval< Send >(), util::declval< Rec >())) ConnectResult
Definition connect_result.h:7
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto forward_like(U &&value) -> decltype(auto)
Definition forward_like.h:8
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
Fun function
Definition then.h:77
Rec receiver
Definition then.h:78
Definition then.h:69
auto operator()(Send &&sender, Fun &&function) const -> concepts::Sender auto
Definition then.h:220
friend void tag_invoke(Tag< start >, Type &self)
Definition then.h:158
Type(Send &&sender, Fun &&function, Rec receiver)
Definition then.h:153
friend void tag_invoke(Tg const tag, Type &&self, Args &&... args)
Definition then.h:132
friend void tag_invoke(Tg, Type &&self, Args &&... args)
Definition then.h:115
friend void tag_invoke(Tg, Type &&self, Args &&... args)
Definition then.h:98
void is_receiver
Definition then.h:89
Data< Fun, Rec > * data
Definition then.h:91
friend auto tag_invoke(Tag< get_env >, Type const &self)
Definition then.h:138
Fun function
Definition then.h:174
void is_sender
Definition then.h:171
friend auto tag_invoke(Tag< connect >, Self &&self, Rec receiver)
Definition then.h:186
Send sender
Definition then.h:173
friend auto tag_invoke(Tag< get_completion_signatures >, Self &&, E &&) -> Sigs< CPO, meta::Like< Self, Send >, E, Fun >
Definition then.h:178
friend auto tag_invoke(Tag< get_env >, Type const &self)
Definition then.h:191
Definition then.h:169
auto operator()(Send &&sender, Fun &&function) const -> concepts::Sender auto
Definition then.h:240
auto operator()(Send &&sender, Fun &&function) const -> concepts::Sender auto
Definition then.h:200
Definition language.h:80
Definition function.h:128
Definition function.h:30
Definition core.h:18
Definition function.h:58
Definition completion_signuatures.h:7
Definition immovable.h:4