diff --git a/include/condy/op_states.hpp b/include/condy/op_states.hpp index 2688679..c8cc8dd 100644 --- a/include/condy/op_states.hpp +++ b/include/condy/op_states.hpp @@ -357,18 +357,18 @@ template struct ReceiverRangedAnyWrapper { }; template -using WhenAllRangeOperationState = +using RangedWhenAllOperationState = RangedParallelAllOperationState, Sender>; template -using WhenAnyRangeOperationState = +using RangedWhenAnyOperationState = RangedParallelAnyOperationState, Sender>; template class RangedLinkOperationState - : public WhenAllRangeOperationState { + : public RangedWhenAllOperationState { public: - using Base = WhenAllRangeOperationState; + using Base = RangedWhenAllOperationState; using Base::Base; void start(unsigned int flags) noexcept { diff --git a/include/condy/sender_operations.hpp b/include/condy/sender_operations.hpp index 32f157f..2a516e2 100644 --- a/include/condy/sender_operations.hpp +++ b/include/condy/sender_operations.hpp @@ -8,6 +8,7 @@ #include "condy/concepts.hpp" #include "condy/senders.hpp" #include +#include namespace condy { @@ -204,6 +205,9 @@ template auto when_any(Senders &&...senders) { * @param range The range of operations to compose. */ template auto when_any(Range &&range) { + if (std::ranges::empty(range)) { + throw std::invalid_argument("when_any requires at least one sender"); + } return parallel(std::forward(range)); } diff --git a/include/condy/senders.hpp b/include/condy/senders.hpp index c1d4b28..9215726 100644 --- a/include/condy/senders.hpp +++ b/include/condy/senders.hpp @@ -8,7 +8,6 @@ #include "condy/concepts.hpp" #include "condy/op_states.hpp" #include -#include #include #include #include @@ -17,71 +16,44 @@ namespace condy { -template -class [[nodiscard]] OpSender { -public: - using ReturnType = std::invoke_result_t; - - OpSender(PrepFunc func, CQEHandler cqe_handler) - : prep_func_(std::move(func)), cqe_handler_(std::move(cqe_handler)) {} - - template auto connect(Receiver receiver) noexcept { - return detail::OpSenderOperationState< - OpFinishHandle, PrepFunc>( - std::move(prep_func_), std::move(cqe_handler_), - std::move(receiver)); - } - -private: - PrepFunc prep_func_; - CQEHandler cqe_handler_; -}; - template -class [[nodiscard]] MultiShotOpSender { + template class FinishHandle, typename... Args> +class [[nodiscard]] OpSenderBase { public: using ReturnType = std::invoke_result_t; - MultiShotOpSender(PrepFunc func, CQEHandler cqe_handler, - MultiShotFunc multi_shot_func) + OpSenderBase(PrepFunc func, CQEHandler cqe_handler, Args... args) : prep_func_(std::move(func)), cqe_handler_(std::move(cqe_handler)), - multi_shot_func_(std::move(multi_shot_func)) {} + args_(std::make_tuple(std::move(args)...)) {} template auto connect(Receiver receiver) noexcept { - return detail::OpSenderOperationState< - MultiShotOpFinishHandle, - PrepFunc>(std::move(prep_func_), std::move(cqe_handler_), - std::move(receiver), std::move(multi_shot_func_)); + return std::apply( + [&](auto &&...args) { + return detail::OpSenderOperationState< + FinishHandle, PrepFunc>( + std::move(prep_func_), std::move(cqe_handler_), + std::move(receiver), std::forward(args)...); + }, + std::move(args_)); } private: PrepFunc prep_func_; CQEHandler cqe_handler_; - MultiShotFunc multi_shot_func_; + std::tuple args_; }; -template -class [[nodiscard]] ZeroCopyOpSender { -public: - using ReturnType = std::invoke_result_t; - - ZeroCopyOpSender(PrepFunc func, CQEHandler cqe_handler, FreeFunc free_func) - : prep_func_(std::move(func)), cqe_handler_(std::move(cqe_handler)), - free_func_(std::move(free_func)) {} +template +using OpSender = OpSenderBase; - template auto connect(Receiver receiver) noexcept { - return detail::OpSenderOperationState< - ZeroCopyOpFinishHandle, PrepFunc>( - std::move(prep_func_), std::move(cqe_handler_), std::move(receiver), - std::move(free_func_)); - } +template +using MultiShotOpSender = + OpSenderBase; -private: - PrepFunc prep_func_; - CQEHandler cqe_handler_; - FreeFunc free_func_; -}; +template +using ZeroCopyOpSender = + OpSenderBase; template class [[nodiscard]] FlaggedOpSender { @@ -99,104 +71,71 @@ class [[nodiscard]] FlaggedOpSender { Sender sender_; }; -template class [[nodiscard]] ParallelAllSender { -public: - using ReturnType = std::pair, - std::tuple>; - - ParallelAllSender(Senders... senders) : senders_(std::move(senders)...) {} +namespace detail { - template auto connect(Receiver receiver) noexcept { - return detail::ParallelAllOperationState( - std::move(senders_), std::move(receiver)); - } - -private: - std::tuple senders_; +template