// 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_SCHEDULE_FROM_H_ #define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_SCHEDULE_FROM_H_ #include #include "utility.h" namespace mmdeploy { namespace __schedule_from { template struct _Operation1 { struct type; }; template using operation1_t = typename _Operation1::type; template struct _Receiver1 { struct type; }; template using receiver1_t = typename _Receiver1::type; template struct _Receiver2 { struct type; }; template using receiver2_t = typename _Receiver2::type; template struct _Receiver2::type { operation1_t* op_state_; friend void tag_invoke(set_value_t, type&& self) noexcept { std::apply( [&](auto&&... vals) { SetValue(std::move(self.op_state_->receiver_), std::move(vals)...); // }, std::move(*self.op_state_->data_)); } }; template struct _Receiver1::type { using _receiver2_t = receiver2_t; operation1_t* op_state_; template friend void tag_invoke(set_value_t, type&& self, As&&... as) noexcept { self.op_state_->data_.emplace((As &&) as...); auto sender = Schedule(self.op_state_->scheduler_); auto& op_state2 = self.op_state_->op_state2_.emplace( __conv{[&] { return Connect(std::move(sender), _receiver2_t{self.op_state_}); }}); Start(op_state2); } }; template struct _Operation1::type { using _receiver1_t = receiver1_t; using _receiver2_t = receiver2_t; Scheduler scheduler_; Receiver receiver_; std::optional>> data_; connect_result_t op_state1_; std::optional, _receiver2_t>> op_state2_; template type(Scheduler sched, CvrefSender&& sender, Receiver2&& receiver) : scheduler_(sched), receiver_((Receiver2 &&) receiver), op_state1_(Connect((CvrefSender &&) sender, _receiver1_t{this})) {} type(const type&) = delete; type(_Operation1&&) noexcept = delete; type& operator=(const type&) = delete; type& operator=(type&&) noexcept = delete; friend void tag_invoke(start_t, type& op_state) noexcept { Start(op_state.op_state1_); } }; 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 = 0> friend auto tag_invoke(connect_t, Self&& self, Receiver&& receiver) -> operation1_t, remove_cvref_t> { return {self.scheduler_, ((Self &&) self).sender_, (Receiver &&) receiver}; } friend Scheduler tag_invoke(get_completion_scheduler_t, const type& self) noexcept { return self.scheduler_; } }; struct schedule_from_t { template && tag_invocable, int> = 0> auto operator()(Scheduler&& scheduler, Sender&& sender) const -> tag_invoke_result_t { return tag_invoke(schedule_from_t{}, (Scheduler &&) scheduler, (Sender &&) sender); } template && !tag_invocable, int> = 0> sender_t operator()(Scheduler&& scheduler, Sender&& sender) const { return {(Scheduler &&) scheduler, (Sender &&) sender}; } }; } // namespace __schedule_from using __schedule_from::schedule_from_t; inline constexpr schedule_from_t ScheduleFrom{}; } // namespace mmdeploy #endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_SCHEDULE_FROM_H_