// Copyright (c) OpenMMLab. All rights reserved. // Modified from // https://github.com/brycelelbach/wg21_p2300_std_execution/blob/main/include/execution.hpp #ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_BULK_H_ #define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_BULK_H_ #include "closure.h" #include "concepts.h" #include "core/logger.h" #include "utility.h" namespace mmdeploy { namespace __bulk { template struct _Operation { struct type; }; template using Operation = typename _Operation>::type; template struct _Receiver { struct type; }; template using receiver_t = typename _Receiver::type; template struct _Receiver::type { Receiver receiver_; Shape shape_; Func func_; template friend void tag_invoke(set_value_t, type&& self, As&&... as) noexcept { MMDEPLOY_WARN("fallback Bulk implementation"); for (Shape i = 0; i < self.shape_; ++i) { self.func_(i, as...); } SetValue(std::move(self.receiver_), (As &&) as...); } }; template struct _Operation::type { connect_result_t> op_state2_; friend void tag_invoke(start_t, type& self) { Start(self.op_state2_); } }; template struct _Sender { struct type; }; template using sender_t = typename _Sender, remove_cvref_t, Func>::type; template struct _Sender::type { using value_types = completion_signatures_of_t; template using _receiver_t = receiver_t; Sender sender_; Shape shape_; Func func_; template = 0> friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver) -> Operation<_copy_cvref_t, Shape, Func, Receiver> { return {Connect(((Self &&) self).sender_, _receiver_t{(Receiver &&) receiver, ((Self &&) self).shape_, ((Self &&) self).func_})}; } }; using std::enable_if_t; struct bulk_t { template && _tag_invocable_with_completion_scheduler, int> = 0> auto operator()(Sender&& sender, Shape&& shape, Func func) const { auto scheduler = GetCompletionScheduler(sender); return tag_invoke(bulk_t{}, std::move(scheduler), (Sender &&) sender, (Shape &&) shape, (Func &&) func); } template < typename Sender, typename Shape, typename Func, enable_if_t<_is_sender && !_tag_invocable_with_completion_scheduler && tag_invocable, int> = 0> auto operator()(Sender&& sender, Shape&& shape, Func func) const { return tag_invoke(bulk_t{}, (Sender &&) sender, (Shape &&) shape, (Func &&) func); } template < typename Sender, typename Shape, typename Func, enable_if_t<_is_sender && !_tag_invocable_with_completion_scheduler && !tag_invocable, int> = 0> auto operator()(Sender&& sender, Shape&& shape, Func func) const -> sender_t { return {(Sender &&) sender, (Shape &&) shape, std::move(func)}; } template _BinderBack operator()(Shape shape, Func fun) const { return {{}, {}, {shape, std::move(fun)}}; } }; } // namespace __bulk using __bulk::bulk_t; inline constexpr bulk_t Bulk{}; } // namespace mmdeploy #endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_BULK_H_