// // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_COBALT_DETAIL_WAIT_GROUP_HPP #define BOOST_COBALT_DETAIL_WAIT_GROUP_HPP #include #include #include #include namespace boost::cobalt::detail { struct race_wrapper { using impl_type = decltype(race(std::declval> &>())); std::list> &waitables_; race_wrapper(std::list> &waitables) : waitables_(waitables) { } struct awaitable_type { bool await_ready() { if (waitables_.empty()) return true; else return impl_->await_ready(); } template auto await_suspend(std::coroutine_handle h) { return impl_->await_suspend(h); } void await_resume() { if (waitables_.empty()) return; auto idx = impl_->await_resume(); if (idx != std::numeric_limits::max()) waitables_.erase(std::next(waitables_.begin(), idx)); } awaitable_type(std::list> &waitables) : waitables_(waitables) { if (!waitables_.empty()) impl_.emplace(waitables_, random_); } private: std::optional impl_; std::list> &waitables_; std::default_random_engine &random_{detail::prng()}; }; awaitable_type operator co_await() && { return awaitable_type(waitables_); } }; struct gather_wrapper { using impl_type = decltype(gather(std::declval> &>())); std::list> &waitables_; gather_wrapper(std::list> &waitables) : waitables_(waitables) { } struct awaitable_type { bool await_ready() { if (waitables_.empty()) return true; else return impl_->await_ready(); } template auto await_suspend(std::coroutine_handle h) { return impl_->await_suspend(h); } void await_resume() { if (waitables_.empty()) return; BOOST_ASSERT(impl_); impl_->await_resume(); waitables_.clear(); } awaitable_type(std::list> &waitables) : waitables_(waitables) { if (!waitables_.empty()) impl_.emplace(waitables_); } private: std::list> &waitables_; std::optional impl_; }; awaitable_type operator co_await() { return awaitable_type(waitables_); } }; } #endif //BOOST_COBALT_DETAIL_WAIT_GROUP_HPP