File indexing completed on 2025-01-30 09:33:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_AWAITABLE_HPP
0012 #define BOOST_ASIO_AWAITABLE_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019
0020 #if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
0021
0022 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0023 # include <coroutine>
0024 #else
0025 # include <experimental/coroutine>
0026 #endif
0027
0028 #include <utility>
0029 #include <boost/asio/any_io_executor.hpp>
0030
0031 #include <boost/asio/detail/push_options.hpp>
0032
0033 namespace boost {
0034 namespace asio {
0035 namespace detail {
0036
0037 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0038 using std::coroutine_handle;
0039 using std::suspend_always;
0040 #else
0041 using std::experimental::coroutine_handle;
0042 using std::experimental::suspend_always;
0043 #endif
0044
0045 template <typename> class awaitable_thread;
0046 template <typename, typename> class awaitable_frame;
0047
0048 }
0049
0050
0051 template <typename T, typename Executor = any_io_executor>
0052 class BOOST_ASIO_NODISCARD awaitable
0053 {
0054 public:
0055
0056 typedef T value_type;
0057
0058
0059 typedef Executor executor_type;
0060
0061
0062 constexpr awaitable() noexcept
0063 : frame_(nullptr)
0064 {
0065 }
0066
0067
0068 awaitable(awaitable&& other) noexcept
0069 : frame_(std::exchange(other.frame_, nullptr))
0070 {
0071 }
0072
0073
0074 ~awaitable()
0075 {
0076 if (frame_)
0077 frame_->destroy();
0078 }
0079
0080
0081 awaitable& operator=(awaitable&& other) noexcept
0082 {
0083 if (this != &other)
0084 frame_ = std::exchange(other.frame_, nullptr);
0085 return *this;
0086 }
0087
0088
0089 bool valid() const noexcept
0090 {
0091 return !!frame_;
0092 }
0093
0094 #if !defined(GENERATING_DOCUMENTATION)
0095
0096
0097 bool await_ready() const noexcept
0098 {
0099 return false;
0100 }
0101
0102
0103 template <class U>
0104 void await_suspend(
0105 detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
0106 {
0107 frame_->push_frame(&h.promise());
0108 }
0109
0110
0111 T await_resume()
0112 {
0113 return awaitable(static_cast<awaitable&&>(*this)).frame_->get();
0114 }
0115
0116 #endif
0117
0118 private:
0119 template <typename> friend class detail::awaitable_thread;
0120 template <typename, typename> friend class detail::awaitable_frame;
0121
0122
0123 awaitable(const awaitable&) = delete;
0124 awaitable& operator=(const awaitable&) = delete;
0125
0126
0127 explicit awaitable(detail::awaitable_frame<T, Executor>* a)
0128 : frame_(a)
0129 {
0130 }
0131
0132 detail::awaitable_frame<T, Executor>* frame_;
0133 };
0134
0135 }
0136 }
0137
0138 #include <boost/asio/detail/pop_options.hpp>
0139
0140 #include <boost/asio/impl/awaitable.hpp>
0141
0142 #endif
0143
0144 #endif