File indexing completed on 2025-12-16 09:44:26
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_COBALT_PROMISE_HPP
0009 #define BOOST_COBALT_PROMISE_HPP
0010
0011 #include <boost/cobalt/detail/promise.hpp>
0012
0013 namespace boost::cobalt
0014 {
0015
0016
0017 template<typename Return>
0018 struct [[nodiscard]] promise
0019 {
0020 promise(promise &&lhs) noexcept;
0021 promise& operator=(promise && lhs) noexcept;
0022
0023
0024 auto operator co_await ();
0025
0026
0027 void operator +() &&;
0028
0029
0030 void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
0031
0032
0033 bool ready() const;
0034
0035 explicit operator bool () const;
0036
0037
0038 bool attached() const;
0039 void detach();
0040 void attach();
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 Return get(const boost::source_location & loc = BOOST_CURRENT_LOCATION)
0053 {
0054 BOOST_ASSERT(ready());
0055 return receiver_.get_result().value(loc);
0056 }
0057
0058 using promise_type = detail::cobalt_promise<Return>;
0059 promise(const promise &) = delete;
0060 promise& operator=(const promise &) = delete;
0061
0062 ~promise()
0063 {
0064 if (attached_)
0065 cancel();
0066 }
0067
0068 constexpr promise(noop<Return> n) : receiver_(std::move(n)), attached_(false) {}
0069 private:
0070 template<typename>
0071 friend struct detail::cobalt_promise;
0072
0073 promise(detail::cobalt_promise<Return> * promise) : receiver_(promise->receiver, promise->signal), attached_{true}
0074 {
0075 }
0076
0077 detail::promise_receiver<Return> receiver_;
0078 bool attached_;
0079
0080 friend struct detached;
0081
0082 };
0083
0084
0085 template<typename T>
0086 inline
0087 promise<T>::promise(promise &&lhs) noexcept
0088 : receiver_(std::move(lhs.receiver_)), attached_(std::exchange(lhs.attached_, false))
0089 {
0090 }
0091
0092 template<typename T>
0093 inline
0094 promise<T>& promise<T>::operator=(promise && lhs) noexcept
0095 {
0096 if (attached_)
0097 cancel();
0098 receiver_ = std::move(lhs.receiver_);
0099 attached_ = std::exchange(lhs.attached_, false);
0100 return *this;
0101 }
0102
0103 template<typename T>
0104 inline
0105 auto promise<T>::operator co_await () {return receiver_.get_awaitable();}
0106
0107
0108 template<typename T>
0109 inline
0110 void promise<T>::operator +() && {detach();}
0111
0112 template<typename T>
0113 inline
0114 void promise<T>::cancel(asio::cancellation_type ct)
0115 {
0116 if (!receiver_.done && *receiver_.reference == &receiver_)
0117 receiver_.cancel_signal->emit(ct);
0118 }
0119
0120 template<typename T>
0121 inline
0122 bool promise<T>::ready() const { return receiver_.done; }
0123
0124 template<typename T>
0125 inline
0126 promise<T>::operator bool () const
0127 {
0128 return !receiver_.done || !receiver_.result_taken;
0129 }
0130
0131 template<typename T>
0132 inline
0133 bool promise<T>::attached() const {return attached_;}
0134
0135 template<typename T>
0136 inline
0137 void promise<T>::detach() {attached_ = false;}
0138 template<typename T>
0139 inline
0140 void promise<T>::attach() {attached_ = true;}
0141
0142
0143 }
0144
0145 #endif