1//
2// awaitable.hpp
3// ~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_AWAITABLE_HPP
12#define BOOST_ASIO_AWAITABLE_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
21
22#if defined(BOOST_ASIO_HAS_STD_COROUTINE)
23# include <coroutine>
24#else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
25# include <experimental/coroutine>
26#endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
27
28#include <utility>
29#include <boost/asio/any_io_executor.hpp>
30
31#include <boost/asio/detail/push_options.hpp>
32
33namespace boost {
34namespace asio {
35namespace detail {
36
37#if defined(BOOST_ASIO_HAS_STD_COROUTINE)
38using std::coroutine_handle;
39using std::suspend_always;
40#else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
41using std::experimental::coroutine_handle;
42using std::experimental::suspend_always;
43#endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
44
45template <typename> class awaitable_thread;
46template <typename, typename> class awaitable_frame;
47
48} // namespace detail
49
50/// The return type of a coroutine or asynchronous operation.
51template <typename T, typename Executor = any_io_executor>
52class BOOST_ASIO_NODISCARD awaitable
53{
54public:
55 /// The type of the awaited value.
56 typedef T value_type;
57
58 /// The executor type that will be used for the coroutine.
59 typedef Executor executor_type;
60
61 /// Default constructor.
62 constexpr awaitable() noexcept
63 : frame_(nullptr)
64 {
65 }
66
67 /// Move constructor.
68 awaitable(awaitable&& other) noexcept
69 : frame_(std::exchange(other.frame_, nullptr))
70 {
71 }
72
73 /// Destructor
74 ~awaitable()
75 {
76 if (frame_)
77 frame_->destroy();
78 }
79
80 /// Move assignment.
81 awaitable& operator=(awaitable&& other) noexcept
82 {
83 if (this != &other)
84 frame_ = std::exchange(other.frame_, nullptr);
85 return *this;
86 }
87
88 /// Checks if the awaitable refers to a future result.
89 bool valid() const noexcept
90 {
91 return !!frame_;
92 }
93
94#if !defined(GENERATING_DOCUMENTATION)
95
96 // Support for co_await keyword.
97 bool await_ready() const noexcept
98 {
99 return false;
100 }
101
102 // Support for co_await keyword.
103 template <class U>
104 void await_suspend(
105 detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
106 {
107 frame_->push_frame(&h.promise());
108 }
109
110 // Support for co_await keyword.
111 T await_resume()
112 {
113 return awaitable(static_cast<awaitable&&>(*this)).frame_->get();
114 }
115
116#endif // !defined(GENERATING_DOCUMENTATION)
117
118private:
119 template <typename> friend class detail::awaitable_thread;
120 template <typename, typename> friend class detail::awaitable_frame;
121
122 // Not copy constructible or copy assignable.
123 awaitable(const awaitable&) = delete;
124 awaitable& operator=(const awaitable&) = delete;
125
126 // Construct the awaitable from a coroutine's frame object.
127 explicit awaitable(detail::awaitable_frame<T, Executor>* a)
128 : frame_(a)
129 {
130 }
131
132 detail::awaitable_frame<T, Executor>* frame_;
133};
134
135} // namespace asio
136} // namespace boost
137
138#include <boost/asio/detail/pop_options.hpp>
139
140#include <boost/asio/impl/awaitable.hpp>
141
142#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
143
144#endif // BOOST_ASIO_AWAITABLE_HPP
145

source code of boost/libs/asio/include/boost/asio/awaitable.hpp