20template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
21 template <
typename...>
class FinishHandle,
typename... Args>
22class [[nodiscard]] OpSenderBase {
24 using CondySender = void;
25 using ReturnType = std::invoke_result_t<CQEHandler &, io_uring_cqe *>;
27 OpSenderBase(PrepFunc func, CQEHandler cqe_handler, Args... args)
28 : prep_func_(std::move(func)), cqe_handler_(std::move(cqe_handler)),
29 args_(std::make_tuple(std::move(args)...)) {}
31 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
34 return OpSenderOperationState<
35 FinishHandle<CQEHandler, Args..., Receiver>, PrepFunc>(
36 std::move(prep_func_), std::move(cqe_handler_),
37 std::move(receiver), std::forward<decltype(args)>(args)...);
44 CQEHandler cqe_handler_;
45 std::tuple<Args...> args_;
48template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler>
49using OpSender = OpSenderBase<PrepFunc, CQEHandler, OpFinishHandle>;
51template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
52 typename MultiShotFunc>
53using MultiShotOpSender =
54 OpSenderBase<PrepFunc, CQEHandler, MultiShotOpFinishHandle, MultiShotFunc>;
56template <PrepFuncLike PrepFunc, CQEHandlerLike CQEHandler,
typename FreeFunc>
57using ZeroCopyOpSender =
58 OpSenderBase<PrepFunc, CQEHandler, ZeroCopyOpFinishHandle, FreeFunc>;
60template <
unsigned int Flags,
typename Sender>
61class [[nodiscard]] FlaggedOpSender {
63 using CondySender = void;
64 using ReturnType =
typename Sender::ReturnType;
66 FlaggedOpSender(Sender sender) : sender_(std::move(sender)) {}
68 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
69 return FlaggedOpState<Flags, Sender, Receiver>(std::move(sender_),
77template <
template <
typename,
unsigned int,
typename...>
class OperationState,
79struct link_sender_helper {
80 template <
typename Receiver,
typename... Senders>
81 using apply = OperationState<Receiver, Flags, Senders...>;
84template <
typename Return,
template <
typename...>
class OperationState,
86class [[nodiscard]] ParallelSenderBase {
88 using CondySender = void;
89 using ReturnType = Return;
91 ParallelSenderBase(Senders... senders) : senders_(std::move(senders)...) {}
93 template <
typename PrevReturn,
typename S,
typename... Ss>
95 ParallelSenderBase<PrevReturn, OperationState, Ss...> &&other, S sender)
96 : senders_(std::tuple_cat(std::move(other.senders_),
97 std::make_tuple(std::move(sender)))) {}
99 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
100 return OperationState<Receiver, Senders...>(std::move(senders_),
101 std::move(receiver));
105 std::tuple<Senders...> senders_;
107 template <
typename,
template <
typename...>
class,
typename...>
108 friend class ParallelSenderBase;
111template <
typename... Senders>
112using ParallelAllSender =
113 ParallelSenderBase<std::pair<std::array<size_t,
sizeof...(Senders)>,
114 std::tuple<typename Senders::ReturnType...>>,
115 ParallelAllOperationState, Senders...>;
117template <
typename... Senders>
118using ParallelAnySender =
119 ParallelSenderBase<std::pair<std::array<size_t,
sizeof...(Senders)>,
120 std::tuple<typename Senders::ReturnType...>>,
121 ParallelAnyOperationState, Senders...>;
123template <
typename... Senders>
125 ParallelSenderBase<std::tuple<
typename Senders::ReturnType...>,
126 WhenAllOperationState, Senders...>;
128template <
typename... Senders>
130 ParallelSenderBase<std::variant<
typename Senders::ReturnType...>,
131 WhenAnyOperationState, Senders...>;
133template <
unsigned int Flags,
typename... Senders>
134using LinkSenderBase = ParallelSenderBase<
135 std::tuple<
typename Senders::ReturnType...>,
136 link_sender_helper<LinkOperationState, Flags>::template apply, Senders...>;
138template <
typename... Senders>
139using LinkSender = LinkSenderBase<IOSQE_IO_LINK, Senders...>;
141template <
typename... Senders>
142using HardLinkSender = LinkSenderBase<IOSQE_IO_HARDLINK, Senders...>;
144template <
typename Return,
template <
typename...>
class OperationState,
146class [[nodiscard]] RangedParallelSenderBase {
148 using CondySender = void;
149 using ReturnType = Return;
151 RangedParallelSenderBase(std::vector<Sender> senders)
152 : senders_(std::move(senders)) {}
154 template <
typename Receiver>
auto connect_impl(Receiver receiver)
noexcept {
155 return OperationState<Receiver, Sender>(std::move(senders_),
156 std::move(receiver));
160 std::vector<Sender> senders_;
163template <
typename Sender>
164using RangedParallelAllSender = RangedParallelSenderBase<
165 std::pair<std::vector<size_t>, std::vector<typename Sender::ReturnType>>,
166 RangedParallelAllOperationState, Sender>;
168template <
typename Sender>
169using RangedParallelAnySender = RangedParallelSenderBase<
170 std::pair<std::vector<size_t>, std::vector<typename Sender::ReturnType>>,
171 RangedParallelAnyOperationState, Sender>;
173template <
typename Sender>
174using RangedWhenAllSender =
175 RangedParallelSenderBase<std::vector<typename Sender::ReturnType>,
176 RangedWhenAllOperationState, Sender>;
178template <
typename Sender>
179using RangedWhenAnySender =
180 RangedParallelSenderBase<std::pair<size_t, typename Sender::ReturnType>,
181 RangedWhenAnyOperationState, Sender>;
183template <
unsigned int Flags,
typename Sender>
184using RangedLinkSenderBase = RangedParallelSenderBase<
185 std::vector<typename Sender::ReturnType>,
186 link_sender_helper<RangedLinkOperationState, Flags>::template apply,
189template <
typename Sender>
190using RangedLinkSender = RangedLinkSenderBase<IOSQE_IO_LINK, Sender>;
192template <
typename Sender>
193using RangedHardLinkSender = RangedLinkSenderBase<IOSQE_IO_HARDLINK, Sender>;
The main namespace for the Condy library.
Operation state implementations for various operations.