// Copyright (c) OpenMMLab. All rights reserved. #ifndef MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_WHEN_ALL_VALUE_H_ #define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_WHEN_ALL_VALUE_H_ #include "core/value.h" #include "execution/schedulers/registry.h" namespace mmdeploy { namespace __when_all_value { template struct _Operation { struct type; }; template using operation_t = typename _Operation::type; template struct _Receiver { struct type; }; template using receiver_t = typename _Receiver::type; template struct _Receiver::type { size_t index_; operation_t* op_state_; friend void tag_invoke(set_value_t, type&& self, Value value) noexcept { self.op_state_->values_[self.index_] = std::move(value); if (0 == --self.op_state_->count_) { SetValue(std::move(self.op_state_->rcvr_), std::move(self.op_state_->values_)); } } }; template struct _Operation::type { std::vector ConnectChildren(std::vector> senders) { std::vector op_states; op_states.reserve(senders.size()); for (size_t i = 0; i < senders.size(); ++i) op_states.push_back(Connect(std::move(senders[i]), receiver_t{i, this})); return op_states; } type(std::vector> senders, Receiver receiver) : child_op_states_{ConnectChildren(std::move(senders))}, rcvr_((Receiver &&) receiver), count_(child_op_states_.size()), values_(child_op_states_.size()) {} std::vector child_op_states_; Receiver rcvr_; std::atomic count_; std::vector values_; friend void tag_invoke(start_t, type& op_state) { for (auto& op : op_state.child_op_states_) { Start(op); } } }; struct sender_t { using value_types = std::tuple>; std::vector> senders_; template > friend operation_t> tag_invoke(connect_t, Self&& self, Receiver&& receiver) { return {((Self &&) self).senders_, (Receiver &&) receiver}; } }; } // namespace __when_all_value namespace _type_erased { inline __when_all_value::sender_t tag_invoke(when_all_t, std::vector> senders) { return {std::move(senders)}; } } // namespace _type_erased } // namespace mmdeploy #endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_WHEN_ALL_VALUE_H_