// 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_ON_H_ #define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ON_H_ #include #include "utility.h" namespace mmdeploy { namespace __on { template struct _Operation { struct type; }; template using operation_t = typename _Operation::type; template struct _ReceiverRef { struct type; }; template using receiver_ref_t = typename _ReceiverRef::type; template struct _ReceiverRef::type { operation_t* op_state_; template friend void tag_invoke(set_value_t, type&& self, Args&&... args) noexcept { SetValue((Receiver &&) self.op_state_->receiver_, ((Args &&) args)...); } }; template struct _Receiver { struct type; }; template using receiver_t = typename _Receiver::type; template struct _Receiver::type { operation_t* op_state_; using _receiver_ref_t = receiver_ref_t; friend void tag_invoke(set_value_t, type&& self) noexcept { auto op_state = self.op_state_; Start(op_state->data_.template emplace<1>( Connect((Sender &&) op_state->sender_, _receiver_ref_t{op_state}))); } }; template struct _Operation::type { using _receiver_t = receiver_t; using _receiver_ref_t = receiver_ref_t; template type(Scheduler scheduler, Sender2&& sender, Receiver2&& receiver) : data_(std::in_place_index<0>, Connect(Schedule(scheduler), _receiver_t{this})), scheduler_(scheduler), sender_((Sender2 &&) sender), receiver_((Receiver2 &&) receiver) {} friend void tag_invoke(start_t, type& self) { Start(std::get<0>(self.data_)); } std::variant, _receiver_t>, connect_result_t> data_; Scheduler scheduler_; Sender sender_; Receiver receiver_; }; template struct _Sender { struct type; }; template using sender_t = typename _Sender, remove_cvref_t>::type; template struct _Sender::type { using value_types = completion_signatures_of_t; Scheduler scheduler_; Sender sender_; template using _operation_t = operation_t>; template = 0> friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver) -> _operation_t { return {((Self &&) self).scheduler_, ((Self &&) self).sender_, (Receiver &&) receiver}; } }; struct on_t { template && tag_invocable, int> = 0> auto operator()(Scheduler&& scheduler, Sender&& sender) const -> tag_invoke_result_t { return tag_invoke(on_t{}, (Scheduler &&) scheduler, (Sender &&) sender); } template < typename Scheduler, typename Sender, std::enable_if_t<_is_sender && !tag_invocable, int> = 0> sender_t operator()(Scheduler&& scheduler, Sender&& sender) const { return {(Scheduler &&) scheduler, (Sender &&) sender}; } }; } // namespace __on using __on::on_t; inline constexpr on_t On{}; } // namespace mmdeploy #endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_ON_H_