File indexing completed on 2025-01-30 09:34:31
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_COBALT_DETAIL_WAIT_GROUP_HPP
0009 #define BOOST_COBALT_DETAIL_WAIT_GROUP_HPP
0010
0011 #include <boost/cobalt/promise.hpp>
0012 #include <boost/cobalt/race.hpp>
0013 #include <boost/cobalt/gather.hpp>
0014
0015 #include <list>
0016
0017
0018 namespace boost::cobalt::detail
0019 {
0020
0021 struct race_wrapper
0022 {
0023 using impl_type = decltype(race(std::declval<std::list<promise<void>> &>()));
0024 std::list<promise<void>> &waitables_;
0025
0026 race_wrapper(std::list<promise<void>> &waitables) : waitables_(waitables)
0027 {
0028 }
0029
0030 struct awaitable_type
0031 {
0032
0033 bool await_ready()
0034 {
0035 if (waitables_.empty())
0036 return true;
0037 else
0038 return impl_->await_ready();
0039 }
0040
0041 template<typename Promise>
0042 auto await_suspend(std::coroutine_handle<Promise> h)
0043 {
0044 return impl_->await_suspend(h);
0045 }
0046
0047 void await_resume()
0048 {
0049 if (waitables_.empty())
0050 return;
0051 auto idx = impl_->await_resume();
0052 if (idx != std::numeric_limits<std::size_t>::max())
0053 waitables_.erase(std::next(waitables_.begin(), idx));
0054 }
0055
0056 awaitable_type(std::list<promise<void>> &waitables) : waitables_(waitables)
0057 {
0058 if (!waitables_.empty())
0059 impl_.emplace(waitables_, random_);
0060 }
0061
0062 private:
0063 std::optional<impl_type::awaitable> impl_;
0064 std::list<promise<void>> &waitables_;
0065 std::default_random_engine &random_{detail::prng()};
0066
0067 };
0068 awaitable_type operator co_await() &&
0069 {
0070 return awaitable_type(waitables_);
0071 }
0072 };
0073
0074 struct gather_wrapper
0075 {
0076 using impl_type = decltype(gather(std::declval<std::list<promise<void>> &>()));
0077 std::list<promise<void>> &waitables_;
0078
0079 gather_wrapper(std::list<promise<void>> &waitables) : waitables_(waitables)
0080 {
0081 }
0082
0083 struct awaitable_type
0084 {
0085 bool await_ready()
0086 {
0087 if (waitables_.empty())
0088 return true;
0089 else
0090 return impl_->await_ready();
0091 }
0092
0093 template<typename Promise>
0094 auto await_suspend(std::coroutine_handle<Promise> h)
0095 {
0096 return impl_->await_suspend(h);
0097 }
0098
0099 void await_resume()
0100 {
0101 if (waitables_.empty())
0102 return;
0103 BOOST_ASSERT(impl_);
0104 impl_->await_resume();
0105 waitables_.clear();
0106 }
0107
0108 awaitable_type(std::list<promise<void>> &waitables) : waitables_(waitables)
0109 {
0110 if (!waitables_.empty())
0111 impl_.emplace(waitables_);
0112 }
0113 private:
0114 std::list<promise<void>> &waitables_;
0115 std::optional<decltype(gather(waitables_).operator co_await())> impl_;
0116 };
0117
0118 awaitable_type operator co_await()
0119 {
0120 return awaitable_type(waitables_);
0121 }
0122
0123 };
0124
0125 }
0126
0127 #endif