From a1347eb6d6718785efa91a42f1b18506e722ab35 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 1 May 2026 19:02:27 +0800 Subject: [PATCH 1/7] simplify parallel sender --- include/condy/senders.hpp | 88 +++++++++++++-------------------------- 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/include/condy/senders.hpp b/include/condy/senders.hpp index c1d4b28..ce76ee1 100644 --- a/include/condy/senders.hpp +++ b/include/condy/senders.hpp @@ -99,81 +99,53 @@ class [[nodiscard]] FlaggedOpSender { Sender sender_; }; -template class [[nodiscard]] ParallelAllSender { +template class OperationState, + typename... Senders> +class [[nodiscard]] ParallelSender { public: - using ReturnType = std::pair, - std::tuple>; + using ReturnType = Return; - ParallelAllSender(Senders... senders) : senders_(std::move(senders)...) {} + ParallelSender(Senders... senders) : senders_(std::move(senders)...) {} - template auto connect(Receiver receiver) noexcept { - return detail::ParallelAllOperationState( - std::move(senders_), std::move(receiver)); - } - -private: - std::tuple senders_; -}; - -template class [[nodiscard]] ParallelAnySender { -public: - using ReturnType = std::pair, - std::tuple>; - - ParallelAnySender(Senders... senders) : senders_(std::move(senders)...) {} - - template auto connect(Receiver receiver) noexcept { - return detail::ParallelAnyOperationState( - std::move(senders_), std::move(receiver)); - } - -private: - std::tuple senders_; -}; - -template class [[nodiscard]] WhenAllSender { -public: - using ReturnType = std::tuple; - - WhenAllSender(Senders... senders) : senders_(std::move(senders)...) {} - - template - WhenAllSender(WhenAllSender other, S sender) + template + ParallelSender(ParallelSender &&other, + S sender) : senders_(std::tuple_cat(std::move(other.senders_), std::make_tuple(std::move(sender)))) {} template auto connect(Receiver receiver) noexcept { - return detail::WhenAllOperationState( - std::move(senders_), std::move(receiver)); + return OperationState(std::move(senders_), + std::move(receiver)); } private: std::tuple senders_; - template friend class WhenAllSender; + template class, typename...> + friend class ParallelSender; }; -template class [[nodiscard]] WhenAnySender { -public: - using ReturnType = std::variant; - - WhenAnySender(Senders... senders) : senders_(std::move(senders)...) {} - - template - WhenAnySender(WhenAnySender other, S sender) - : senders_(std::tuple_cat(std::move(other.senders_), - std::make_tuple(std::move(sender)))) {} +template +using ParallelAllSender = + ParallelSender, + std::tuple>, + detail::ParallelAllOperationState, Senders...>; - template auto connect(Receiver receiver) noexcept { - return detail::WhenAnyOperationState( - std::move(senders_), std::move(receiver)); - } +template +using ParallelAnySender = + ParallelSender, + std::tuple>, + detail::ParallelAnyOperationState, Senders...>; -private: - std::tuple senders_; +template +using WhenAllSender = + ParallelSender, + detail::WhenAllOperationState, Senders...>; - template friend class WhenAnySender; -}; +template +using WhenAnySender = + ParallelSender, + detail::WhenAnyOperationState, Senders...>; template class [[nodiscard]] LinkSenderBase { From e357fa3975afcc0eb0731563be89d7d94c1a4de7 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 1 May 2026 19:08:57 +0800 Subject: [PATCH 2/7] simplify link sender --- include/condy/senders.hpp | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/include/condy/senders.hpp b/include/condy/senders.hpp index ce76ee1..961c996 100644 --- a/include/condy/senders.hpp +++ b/include/condy/senders.hpp @@ -147,28 +147,20 @@ using WhenAnySender = ParallelSender, detail::WhenAnyOperationState, Senders...>; -template -class [[nodiscard]] LinkSenderBase { -public: - using ReturnType = std::tuple; - - LinkSenderBase(Senders... senders) : senders_(std::move(senders)...) {} - - template - LinkSenderBase(LinkSenderBase other, S sender) - : senders_(std::tuple_cat(std::move(other.senders_), - std::make_tuple(std::move(sender)))) {} +namespace detail { - template auto connect(Receiver receiver) noexcept { - return detail::LinkOperationState( - std::move(senders_), std::move(receiver)); - } +template struct link_sender_helper { + template + using apply = LinkOperationState; +}; -private: - std::tuple senders_; +} // namespace detail - template friend class LinkSenderBase; -}; +template +using LinkSenderBase = + ParallelSender, + detail::link_sender_helper::template apply, + Senders...>; template using LinkSender = LinkSenderBase; From c044b7ff991c1a12c573e72a6370ef25649b61c5 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 1 May 2026 19:21:41 +0800 Subject: [PATCH 3/7] simplify ranged senders --- include/condy/sender_operations.hpp | 4 ++ include/condy/senders.hpp | 98 +++++++++-------------------- 2 files changed, 35 insertions(+), 67 deletions(-) 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 961c996..5f22191 100644 --- a/include/condy/senders.hpp +++ b/include/condy/senders.hpp @@ -168,93 +168,57 @@ using LinkSender = LinkSenderBase; template using HardLinkSender = LinkSenderBase; -template class [[nodiscard]] RangedParallelAllSender { +template class OperationState, + typename Sender> +class [[nodiscard]] RangedParallelSender { public: - using ReturnType = std::pair, - std::vector>; + using ReturnType = Return; - RangedParallelAllSender(std::vector senders) + RangedParallelSender(std::vector senders) : senders_(std::move(senders)) {} template auto connect(Receiver receiver) noexcept { - return detail::RangedParallelAllOperationState( - std::move(senders_), std::move(receiver)); + return OperationState(std::move(senders_), + std::move(receiver)); } private: std::vector senders_; }; -template class [[nodiscard]] RangedParallelAnySender { -public: - using ReturnType = std::pair, - std::vector>; - - RangedParallelAnySender(std::vector senders) - : senders_(std::move(senders)) {} - - template auto connect(Receiver receiver) noexcept { - return detail::RangedParallelAnyOperationState( - std::move(senders_), std::move(receiver)); - } +template +using RangedParallelAllSender = RangedParallelSender< + std::pair, std::vector>, + detail::RangedParallelAllOperationState, Sender>; -private: - std::vector senders_; -}; +template +using RangedParallelAnySender = RangedParallelSender< + std::pair, std::vector>, + detail::RangedParallelAnyOperationState, Sender>; -template class [[nodiscard]] RangedWhenAllSender { -public: - using ReturnType = std::vector; +template +using RangedWhenAllSender = + RangedParallelSender, + detail::WhenAllRangeOperationState, Sender>; - RangedWhenAllSender(std::vector senders) - : senders_(std::move(senders)) {} +template +using RangedWhenAnySender = + RangedParallelSender, + detail::WhenAnyRangeOperationState, Sender>; - template auto connect(Receiver receiver) noexcept { - return detail::WhenAllRangeOperationState( - std::move(senders_), std::move(receiver)); - } +namespace detail { -private: - std::vector senders_; +template struct ranged_link_sender_helper { + template + using apply = RangedLinkOperationState; }; -template class [[nodiscard]] RangedWhenAnySender { -public: - using ReturnType = std::pair; - - RangedWhenAnySender(std::vector senders) - : senders_(std::move(senders)) { - if (senders_.empty()) { - throw std::invalid_argument( - "when_any requires at least one sender"); - } - } - - template auto connect(Receiver receiver) noexcept { - return detail::WhenAnyRangeOperationState( - std::move(senders_), std::move(receiver)); - } - -private: - std::vector senders_; -}; +} // namespace detail template -class [[nodiscard]] RangedLinkSenderBase { -public: - using ReturnType = std::vector; - - RangedLinkSenderBase(std::vector senders) - : senders_(std::move(senders)) {} - - template auto connect(Receiver receiver) noexcept { - return detail::RangedLinkOperationState( - std::move(senders_), std::move(receiver)); - } - -private: - std::vector senders_; -}; +using RangedLinkSenderBase = RangedParallelSender< + std::vector, + detail::ranged_link_sender_helper::template apply, Sender>; template using RangedLinkSender = RangedLinkSenderBase; From 31cb291940de2c127b12d4ae270c0ce86c2c9656 Mon Sep 17 00:00:00 2001 From: wokron Date: Fri, 1 May 2026 19:24:26 +0800 Subject: [PATCH 4/7] simplify link_sender_helper --- include/condy/senders.hpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/include/condy/senders.hpp b/include/condy/senders.hpp index 5f22191..2eb96d1 100644 --- a/include/condy/senders.hpp +++ b/include/condy/senders.hpp @@ -99,6 +99,17 @@ class [[nodiscard]] FlaggedOpSender { Sender sender_; }; +namespace detail { + +template