Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:04:17

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_GENERATOR_HPP
0009 #define BOOST_COBALT_GENERATOR_HPP
0010 
0011 #include <boost/cobalt/detail/generator.hpp>
0012 
0013 
0014 namespace boost::cobalt
0015 {
0016 
0017 // tag::outline[]
0018 template<typename Yield, typename Push = void>
0019 struct [[nodiscard]] generator
0020 // end::outline[]
0021      : detail::generator_base<Yield, Push>
0022 // tag::outline[]
0023 {
0024   // Movable
0025 
0026   generator(generator &&lhs) noexcept = default;
0027   generator& operator=(generator &&) noexcept = default;
0028 
0029   // True until it co_returns & is co_awaited after <1>
0030   explicit operator bool() const;
0031 
0032   // Cancel the generator. <3>
0033   void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
0034 
0035   // Check if a value is available
0036   bool ready() const;
0037 
0038   // Get the returned value. If !ready() this function has undefined behaviour.
0039   Yield get();
0040 
0041   // Cancel & detach the generator.
0042   ~generator();
0043 
0044   // end::outline[]
0045   using promise_type = detail::generator_promise<Yield, Push>;
0046 
0047   generator(const generator &) = delete;
0048   generator& operator=(const generator &) = delete;
0049 
0050 
0051  private:
0052   template<typename, typename>
0053   friend struct detail::generator_base;
0054   template<typename, typename>
0055   friend struct detail::generator_promise;
0056 
0057   generator(detail::generator_promise<Yield, Push> * generator) : receiver_(generator->receiver, generator->signal)
0058   {
0059   }
0060   detail::generator_receiver<Yield, Push> receiver_;
0061 
0062   /* tag::outline[]
0063   // an awaitable that results in value of `Yield`.
0064   using __generator_awaitable__ = __unspecified__;
0065 
0066   // Present when `Push` != `void`
0067   __generator_awaitable__ operator()(      Push && push);
0068   __generator_awaitable__ operator()(const Push &  push);
0069 
0070   // Present when `Push` == `void`, i.e. can `co_await` the generator directly.
0071   __generator_awaitable__ operator co_await (); // <2>
0072    end::outline[]
0073    */
0074 
0075 
0076 // tag::outline[]
0077 
0078 };
0079 // end::outline[]
0080 
0081 
0082 
0083 template<typename Yield, typename Push >
0084 inline generator<Yield, Push>::operator bool() const
0085 {
0086   return !receiver_.done || receiver_.result || receiver_.exception;
0087 }
0088 
0089 template<typename Yield, typename Push >
0090 inline void generator<Yield, Push>::cancel(asio::cancellation_type ct)
0091 {
0092   if (!receiver_.done && receiver_.reference == &receiver_)
0093     receiver_.cancel_signal.emit(ct);
0094 }
0095 
0096 template<typename Yield, typename Push >
0097 inline bool generator<Yield, Push>::ready() const  { return receiver_.result || receiver_.exception; }
0098 
0099 template<typename Yield, typename Push >
0100 inline Yield generator<Yield, Push>::get()
0101 {
0102   BOOST_ASSERT(ready());
0103   receiver_.rethrow_if();
0104   return receiver_.get_result();
0105 }
0106 
0107 template<typename Yield, typename Push >
0108 inline generator<Yield, Push>::~generator() { cancel(); }
0109 
0110 
0111 }
0112 
0113 #endif //BOOST_COBALT_GENERATOR_HPP