Condy v1.9
C++ Asynchronous System Call Layer for Linux
Loading...
Searching...
No Matches
sender_operations.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "condy/concepts.hpp"
9#include "condy/senders.hpp"
10#include <stdexcept>
11
12namespace condy {
13
14template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler>
15auto build_op_sender(PrepFunc &&prep_func, CQEHandler &&cqe_handler) {
16 return OpSender<std::decay_t<PrepFunc>, std::decay_t<CQEHandler>>(
17 std::forward<PrepFunc>(prep_func),
18 std::forward<CQEHandler>(cqe_handler));
19}
20
21template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
22 typename MultiShotFunc>
23auto build_multishot_op_sender(PrepFunc &&func, CQEHandler &&cqe_handler,
24 MultiShotFunc &&multishot_func) {
25 return MultiShotOpSender<std::decay_t<PrepFunc>, std::decay_t<CQEHandler>,
26 std::decay_t<MultiShotFunc>>(
27 std::forward<PrepFunc>(func), std::forward<CQEHandler>(cqe_handler),
28 std::forward<MultiShotFunc>(multishot_func));
29}
30
31template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler, typename FreeFunc>
32auto build_zero_copy_op_sender(PrepFunc &&func, CQEHandler &&cqe_handler,
33 FreeFunc &&free_func) {
34 return ZeroCopyOpSender<std::decay_t<PrepFunc>, std::decay_t<CQEHandler>,
35 std::decay_t<FreeFunc>>(
36 std::forward<PrepFunc>(func), std::forward<CQEHandler>(cqe_handler),
37 std::forward<FreeFunc>(free_func));
38}
39
45template <unsigned int Flags, typename Sender> auto flag(Sender &&sender) {
46 return FlaggedOpSender<Flags, std::decay_t<Sender>>(
47 std::forward<Sender>(sender));
48}
49
54template <typename Sender> auto drain(Sender &&sender) {
55 return flag<IOSQE_IO_DRAIN>(std::forward<Sender>(sender));
56}
57
62template <typename Sender> auto always_async(Sender &&sender) {
63 return flag<IOSQE_ASYNC>(std::forward<Sender>(sender));
64}
65
72template <template <typename... Senders> typename SenderType,
73 typename... Senders>
74auto parallel(Senders &&...senders) {
75 return SenderType<std::decay_t<Senders>...>(
76 std::forward<Senders>(senders)...);
77}
78
85template <template <typename Sender> typename RangedSenderType,
86 std::ranges::range Range>
87auto parallel(Range &&range) {
88 using SenderType = typename std::remove_cvref_t<Range>::value_type;
89 auto begin = std::make_move_iterator(std::begin(range));
90 auto end = std::make_move_iterator(std::end(range));
91 std::vector<SenderType> senders(begin, end);
92 return RangedSenderType<SenderType>(std::move(senders));
93}
94
100template <typename... Senders> auto when_all(Senders &&...senders) {
101 return parallel<WhenAllSender>(std::forward<Senders>(senders)...);
102}
103
109template <std::ranges::range Range> auto when_all(Range &&range) {
110 return parallel<RangedWhenAllSender>(std::forward<Range>(range));
111}
112
118template <typename... Senders> auto when_any(Senders &&...senders) {
119 static_assert(sizeof...(Senders) > 0,
120 "when_any requires at least one sender");
121 return parallel<WhenAnySender>(std::forward<Senders>(senders)...);
122}
123
129template <std::ranges::range Range> auto when_any(Range &&range) {
130 if (std::ranges::empty(range)) {
131 throw std::invalid_argument("when_any requires at least one sender");
132 }
133 return parallel<RangedWhenAnySender>(std::forward<Range>(range));
134}
135
141template <typename... Senders> auto link(Senders &&...senders) {
142 return parallel<LinkSender>(std::forward<Senders>(senders)...);
143}
144
150template <std::ranges::range Range> auto link(Range &&range) {
151 return parallel<RangedLinkSender>(std::forward<Range>(range));
152}
153
159template <typename... Senders> auto hard_link(Senders &&...senders) {
160 return parallel<HardLinkSender>(std::forward<Senders>(senders)...);
161}
162
168template <std::ranges::range Range> auto hard_link(Range &&range) {
169 return parallel<RangedHardLinkSender>(std::forward<Range>(range));
170}
171
175namespace operators {
176
180template <typename Sender1, typename Sender2>
181auto operator&&(Sender1 s1, Sender2 s2) {
182 return when_all(std::move(s1), std::move(s2));
183}
184
188template <typename S, typename... Ss>
189auto operator&&(WhenAllSender<Ss...> aws, S sender) {
190 return WhenAllSender<Ss..., std::decay_t<S>>(std::move(aws),
191 std::move(sender));
192}
193
197template <typename Sender1, typename Sender2>
198auto operator||(Sender1 s1, Sender2 s2) {
199 return when_any(std::move(s1), std::move(s2));
200}
201
205template <typename S, typename... Ss>
206auto operator||(WhenAnySender<Ss...> aws, S sender) {
207 return WhenAnySender<Ss..., std::decay_t<S>>(std::move(aws),
208 std::move(sender));
209}
210
214template <typename Sender1, typename Sender2>
215auto operator>>(Sender1 s1, Sender2 s2) {
216 return link(std::move(s1), std::move(s2));
217}
218
222template <typename S, typename... Ss>
223auto operator>>(LinkSender<Ss...> aws, S sender) {
224 return LinkSender<Ss..., std::decay_t<S>>(std::move(aws),
225 std::move(sender));
226}
227
228} // namespace operators
229
230} // namespace condy
Operators for composing operations.
auto operator&&(Sender1 s1, Sender2 s2)
Operator overloads version of condy::when_all.
auto operator>>(Sender1 s1, Sender2 s2)
Operator overloads version of condy::link.
auto operator||(Sender1 s1, Sender2 s2)
Operator overloads version of condy::when_any.
The main namespace for the Condy library.
Definition condy.hpp:38
auto drain(Sender &&sender)
Mark an operation as drain operation.
auto link(Senders &&...senders)
Compose multiple operations into a single operation that executes them in sequence.
auto parallel(Senders &&...senders)
Compose multiple operations into a single sender that executes them in parallel.
auto hard_link(Senders &&...senders)
Compose multiple operations into a single operation that executes them in sequence and continues even...
auto when_any(Senders &&...senders)
Compose multiple operations into a single operation that completes when any of them complete.
auto when_all(Senders &&...senders)
Compose multiple operations into a single operation that completes when all of them complete.
auto flag(Sender &&sender)
Decorates an operation with specific io_uring sqe flags.
auto always_async(Sender &&sender)
Mark an operation to always execute asynchronously.
Sender types for composing asynchronous operations.