1//
2// use_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_USE_AWAITABLE_HPP
12#define BOOST_ASIO_USE_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#include <boost/asio/awaitable.hpp>
23#include <boost/asio/detail/handler_tracking.hpp>
24
25#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
26# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
27# include <boost/asio/detail/source_location.hpp>
28# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
29#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
30
31#include <boost/asio/detail/push_options.hpp>
32
33namespace boost {
34namespace asio {
35
36/// A @ref completion_token that represents the currently executing coroutine.
37/**
38 * The @c use_awaitable_t class, with its value @c use_awaitable, is used to
39 * represent the currently executing coroutine. This completion token may be
40 * passed as a handler to an asynchronous operation. For example:
41 *
42 * @code awaitable<void> my_coroutine()
43 * {
44 * std::size_t n = co_await my_socket.async_read_some(buffer, use_awaitable);
45 * ...
46 * } @endcode
47 *
48 * When used with co_await, the initiating function (@c async_read_some in the
49 * above example) suspends the current coroutine. The coroutine is resumed when
50 * the asynchronous operation completes, and the result of the operation is
51 * returned.
52 */
53template <typename Executor = any_io_executor>
54struct use_awaitable_t
55{
56 /// Default constructor.
57 constexpr use_awaitable_t(
58#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
59# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
60 detail::source_location location = detail::source_location::current()
61# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
62#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
63 )
64#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
65# if defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
66 : file_name_(location.file_name()),
67 line_(location.line()),
68 function_name_(location.function_name())
69# else // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
70 : file_name_(0),
71 line_(0),
72 function_name_(0)
73# endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
74#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
75 {
76 }
77
78 /// Constructor used to specify file name, line, and function name.
79 constexpr use_awaitable_t(const char* file_name,
80 int line, const char* function_name)
81#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
82 : file_name_(file_name),
83 line_(line),
84 function_name_(function_name)
85#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
86 {
87#if !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
88 (void)file_name;
89 (void)line;
90 (void)function_name;
91#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
92 }
93
94 /// Adapts an executor to add the @c use_awaitable_t completion token as the
95 /// default.
96 template <typename InnerExecutor>
97 struct executor_with_default : InnerExecutor
98 {
99 /// Specify @c use_awaitable_t as the default completion token type.
100 typedef use_awaitable_t default_completion_token_type;
101
102 /// Construct the adapted executor from the inner executor type.
103 template <typename InnerExecutor1>
104 executor_with_default(const InnerExecutor1& ex,
105 constraint_t<
106 conditional_t<
107 !is_same<InnerExecutor1, executor_with_default>::value,
108 is_convertible<InnerExecutor1, InnerExecutor>,
109 false_type
110 >::value
111 > = 0) noexcept
112 : InnerExecutor(ex)
113 {
114 }
115 };
116
117 /// Type alias to adapt an I/O object to use @c use_awaitable_t as its
118 /// default completion token type.
119 template <typename T>
120 using as_default_on_t = typename T::template rebind_executor<
121 executor_with_default<typename T::executor_type>>::other;
122
123 /// Function helper to adapt an I/O object to use @c use_awaitable_t as its
124 /// default completion token type.
125 template <typename T>
126 static typename decay_t<T>::template rebind_executor<
127 executor_with_default<typename decay_t<T>::executor_type>
128 >::other
129 as_default_on(T&& object)
130 {
131 return typename decay_t<T>::template rebind_executor<
132 executor_with_default<typename decay_t<T>::executor_type>
133 >::other(static_cast<T&&>(object));
134 }
135
136#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
137 const char* file_name_;
138 int line_;
139 const char* function_name_;
140#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
141};
142
143/// A @ref completion_token object that represents the currently executing
144/// coroutine.
145/**
146 * See the documentation for boost::asio::use_awaitable_t for a usage example.
147 */
148#if defined(GENERATING_DOCUMENTATION)
149constexpr use_awaitable_t<> use_awaitable;
150#else
151constexpr use_awaitable_t<> use_awaitable(0, 0, 0);
152#endif
153
154} // namespace asio
155} // namespace boost
156
157#include <boost/asio/detail/pop_options.hpp>
158
159#include <boost/asio/impl/use_awaitable.hpp>
160
161#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
162
163#endif // BOOST_ASIO_USE_AWAITABLE_HPP
164

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