Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:26

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_PROMISE_HPP
0009 #define BOOST_COBALT_PROMISE_HPP
0010 
0011 #include <boost/cobalt/detail/promise.hpp>
0012 
0013 namespace boost::cobalt
0014 {
0015 
0016 // tag::outline[]
0017 template<typename Return>
0018 struct [[nodiscard]] promise
0019 {
0020     promise(promise &&lhs) noexcept;
0021     promise& operator=(promise && lhs) noexcept;
0022 
0023     // enable `co_await`. <1>
0024     auto operator co_await ();
0025 
0026     // Ignore the return value, i.e. detach it. <2>
0027     void operator +() &&;
0028 
0029     // Cancel the promise.
0030     void cancel(asio::cancellation_type ct = asio::cancellation_type::all);
0031 
0032     // Check if the result is ready
0033     bool ready() const;
0034     // Check if the promise can be awaited.
0035     explicit operator bool () const; // <3>
0036 
0037     // Detach or attach
0038     bool attached() const;
0039     void detach();
0040     void attach();
0041     // end::outline[]
0042 
0043     /* tag::outline[]
0044     // Create an already completed promimse
0045 
0046     static promise
0047 
0048     // Get the return value. If !ready() this function has undefined behaviour.
0049     Return get();
0050     end::outline[] */
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     //tag::outline[]
0082 };
0083 // end::outline[]
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 // Ignore the returns value
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 //BOOST_COBALT_PROMISE_HPP