File indexing completed on 2025-07-14 08:27:12
0001
0002
0003
0004
0005
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
0018 template<typename Yield, typename Push = void>
0019 struct [[nodiscard]] generator
0020
0021 : detail::generator_base<Yield, Push>
0022
0023 {
0024
0025
0026 generator(generator &&lhs) noexcept = default;
0027 generator& operator=(generator &&) noexcept;
0028
0029
0030 explicit operator bool() const;
0031
0032
0033 void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
0034
0035
0036 bool ready() const;
0037
0038
0039 Yield get();
0040
0041
0042 ~generator();
0043
0044
0045 using promise_type = detail::generator_promise<Yield, Push>;
0046
0047 generator(const generator &) = delete;
0048 generator& operator=(const generator &) = delete;
0049
0050 constexpr generator(noop<Yield> n) : receiver_(std::move(n)){}
0051
0052 private:
0053 template<typename, typename>
0054 friend struct detail::generator_base;
0055 template<typename, typename>
0056 friend struct detail::generator_promise;
0057
0058 generator(detail::generator_promise<Yield, Push> * generator) : receiver_(generator->receiver, generator->signal)
0059 {
0060 }
0061 detail::generator_receiver<Yield, Push> receiver_;
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 };
0080
0081
0082
0083
0084 template<typename Yield, typename Push >
0085 inline generator<Yield, Push>::operator bool() const
0086 {
0087 return !receiver_.done || receiver_.result || receiver_.exception;
0088 }
0089
0090 template<typename Yield, typename Push >
0091 inline void generator<Yield, Push>::cancel(asio::cancellation_type ct)
0092 {
0093 if (!receiver_.done && *receiver_.reference == &receiver_)
0094 receiver_.cancel_signal->emit(ct);
0095 }
0096
0097 template<typename Yield, typename Push >
0098 inline bool generator<Yield, Push>::ready() const { return receiver_.result || receiver_.exception; }
0099
0100 template<typename Yield, typename Push >
0101 inline Yield generator<Yield, Push>::get()
0102 {
0103 BOOST_ASSERT(ready());
0104 receiver_.rethrow_if();
0105 return receiver_.get_result();
0106 }
0107
0108 template<typename Yield, typename Push >
0109 inline generator<Yield, Push>::~generator() { cancel(); }
0110
0111 template<typename Yield, typename Push >
0112 inline
0113 generator<Yield, Push>& generator<Yield, Push>::operator=(generator && lhs) noexcept
0114 {
0115 cancel();
0116 receiver_ = std::move(lhs.receiver_);
0117 return *this;
0118 }
0119
0120 }
0121
0122 #endif