Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:34:31

0001 //
0002 // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 //BOOST_COBALT_DETAIL_WAIT_GROUP_HPP