// 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_SYNC_WAIT_H_ #define MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_SYNC_WAIT_H_ #include #include "run_loop.h" #include "utility.h" namespace mmdeploy { namespace __sync_wait { template struct _State { std::optional> data_; }; template struct _Receiver { struct type; }; template using receiver_t = typename _Receiver>::type; template struct _Receiver::type { _State* state_; RunLoop* loop_; template friend void tag_invoke(set_value_t, type&& receiver, As&&... as) noexcept { receiver.state_->data_.emplace((As &&) as...); receiver.loop_->_Finish(); } }; struct sync_wait_t { template && _tag_invocable_with_completion_scheduler, int> = 0> auto operator()(Sender&& sender) const -> tag_invoke_result_t, Sender> { auto scheduler = GetCompletionScheduler(sender); return tag_invoke(sync_wait_t{}, std::move(scheduler), (Sender &&) sender); } template && !_tag_invocable_with_completion_scheduler && tag_invocable, int> = 0> auto operator()(Sender&& sender) const -> tag_invoke_result_t { return tag_invoke(sync_wait_t{}, (Sender &&) sender); } template && !_tag_invocable_with_completion_scheduler && !tag_invocable, int> = 0> completion_signatures_of_t operator()(Sender&& sender) const { _State> state; RunLoop loop; // connect to internal receiver auto op_state = Connect((Sender &&) sender, receiver_t{&state, &loop}); Start(op_state); loop._Run(); // extract the returned values return std::move(*state.data_); } }; } // namespace __sync_wait using __sync_wait::sync_wait_t; inline constexpr sync_wait_t SyncWait{}; } // namespace mmdeploy #endif // MMDEPLOY_CSRC_EXPERIMENTAL_EXECUTION_SYNC_WAIT_H_