19template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
20 template <
typename...>
class FinishHandle,
typename... Args>
21class [[nodiscard]] OpSenderBase {
23 using CondySender = void;
24 using ReturnType = std::invoke_result_t<CQEHandler &, io_uring_cqe *>;
26 OpSenderBase(PrepFunc func, CQEHandler cqe_handler, Args... args)
27 : prep_func_(std::move(func)), cqe_handler_(std::move(cqe_handler)),
28 args_(std::make_tuple(std::move(args)...)) {}
30 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
33 return detail::OpSenderOperationState<
34 FinishHandle<CQEHandler, Args..., Receiver>, PrepFunc>(
35 std::move(prep_func_), std::move(cqe_handler_),
36 std::move(receiver), std::forward<decltype(args)>(args)...);
43 CQEHandler cqe_handler_;
44 std::tuple<Args...> args_;
47template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler>
48using OpSender = OpSenderBase<PrepFunc, CQEHandler, OpFinishHandle>;
50template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
51 typename MultiShotFunc>
52using MultiShotOpSender =
53 OpSenderBase<PrepFunc, CQEHandler, MultiShotOpFinishHandle, MultiShotFunc>;
55template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
typename FreeFunc>
56using ZeroCopyOpSender =
57 OpSenderBase<PrepFunc, CQEHandler, ZeroCopyOpFinishHandle, FreeFunc>;
59template <
unsigned int Flags,
typename Sender>
60class [[nodiscard]] FlaggedOpSender {
62 using CondySender = void;
63 using ReturnType =
typename Sender::ReturnType;
65 FlaggedOpSender(Sender sender) : sender_(std::move(sender)) {}
67 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
68 return detail::FlaggedOpState<Flags, Sender, Receiver>(
69 std::move(sender_), std::move(receiver));
78template <
template <
typename,
unsigned int,
typename...>
class OperationState,
80struct link_sender_helper {
81 template <
typename Receiver,
typename... Senders>
82 using apply = OperationState<Receiver, Flags, Senders...>;
87template <
typename Return,
template <
typename...>
class OperationState,
89class [[nodiscard]] ParallelSenderBase {
91 using CondySender = void;
92 using ReturnType = Return;
94 ParallelSenderBase(Senders... senders) : senders_(std::move(senders)...) {}
96 template <
typename PrevReturn,
typename S,
typename... Ss>
98 ParallelSenderBase<PrevReturn, OperationState, Ss...> &&other, S sender)
99 : senders_(std::tuple_cat(std::move(other.senders_),
100 std::make_tuple(std::move(sender)))) {}
102 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
103 return OperationState<Receiver, Senders...>(std::move(senders_),
104 std::move(receiver));
108 std::tuple<Senders...> senders_;
110 template <
typename,
template <
typename...>
class,
typename...>
111 friend class ParallelSenderBase;
114template <
typename... Senders>
115using ParallelAllSender =
116 ParallelSenderBase<std::pair<std::array<size_t,
sizeof...(Senders)>,
117 std::tuple<typename Senders::ReturnType...>>,
118 detail::ParallelAllOperationState, Senders...>;
120template <
typename... Senders>
121using ParallelAnySender =
122 ParallelSenderBase<std::pair<std::array<size_t,
sizeof...(Senders)>,
123 std::tuple<typename Senders::ReturnType...>>,
124 detail::ParallelAnyOperationState, Senders...>;
126template <
typename... Senders>
128 ParallelSenderBase<std::tuple<
typename Senders::ReturnType...>,
129 detail::WhenAllOperationState, Senders...>;
131template <
typename... Senders>
133 ParallelSenderBase<std::variant<
typename Senders::ReturnType...>,
134 detail::WhenAnyOperationState, Senders...>;
136template <
unsigned int Flags,
typename... Senders>
137using LinkSenderBase =
138 ParallelSenderBase<std::tuple<
typename Senders::ReturnType...>,
139 detail::link_sender_helper<detail::LinkOperationState,
140 Flags>::template apply,
143template <
typename... Senders>
144using LinkSender = LinkSenderBase<IOSQE_IO_LINK, Senders...>;
146template <
typename... Senders>
147using HardLinkSender = LinkSenderBase<IOSQE_IO_HARDLINK, Senders...>;
149template <
typename Return,
template <
typename...>
class OperationState,
151class [[nodiscard]] RangedParallelSenderBase {
153 using CondySender = void;
154 using ReturnType = Return;
156 RangedParallelSenderBase(std::vector<Sender> senders)
157 : senders_(std::move(senders)) {}
159 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
160 return OperationState<Receiver, Sender>(std::move(senders_),
161 std::move(receiver));
165 std::vector<Sender> senders_;
168template <
typename Sender>
169using RangedParallelAllSender = RangedParallelSenderBase<
170 std::pair<std::vector<size_t>, std::vector<typename Sender::ReturnType>>,
171 detail::RangedParallelAllOperationState, Sender>;
173template <
typename Sender>
174using RangedParallelAnySender = RangedParallelSenderBase<
175 std::pair<std::vector<size_t>, std::vector<typename Sender::ReturnType>>,
176 detail::RangedParallelAnyOperationState, Sender>;
178template <
typename Sender>
179using RangedWhenAllSender =
180 RangedParallelSenderBase<std::vector<typename Sender::ReturnType>,
181 detail::RangedWhenAllOperationState, Sender>;
183template <
typename Sender>
184using RangedWhenAnySender =
185 RangedParallelSenderBase<std::pair<size_t, typename Sender::ReturnType>,
186 detail::RangedWhenAnyOperationState, Sender>;
188template <
unsigned int Flags,
typename Sender>
189using RangedLinkSenderBase = RangedParallelSenderBase<
190 std::vector<typename Sender::ReturnType>,
191 detail::link_sender_helper<detail::RangedLinkOperationState,
192 Flags>::template apply,
195template <
typename Sender>
196using RangedLinkSender = RangedLinkSenderBase<IOSQE_IO_LINK, Sender>;
198template <
typename Sender>
199using RangedHardLinkSender = RangedLinkSenderBase<IOSQE_IO_HARDLINK, Sender>;
The main namespace for the Condy library.
Operation state implementations for various operations.