5 // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_USE_AWAITABLE_HPP
12 #define BOOST_ASIO_USE_AWAITABLE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
22 #include <boost/asio/awaitable.hpp>
23 #include <boost/asio/detail/handler_tracking.hpp>
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)
31 #include <boost/asio/detail/push_options.hpp>
36 /// A @ref completion_token that represents the currently executing coroutine.
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:
42 * @code awaitable<void> my_coroutine()
44 * std::size_t n = co_await my_socket.async_read_some(buffer, use_awaitable);
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
53 template <typename Executor = any_io_executor>
54 struct use_awaitable_t
56 /// Default constructor.
57 BOOST_ASIO_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)
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)
73 # endif // defined(BOOST_ASIO_HAS_SOURCE_LOCATION)
74 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
78 /// Constructor used to specify file name, line, and function name.
79 BOOST_ASIO_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),
84 function_name_(function_name)
85 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
87 #if !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
91 #endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
94 /// Adapts an executor to add the @c use_awaitable_t completion token as the
96 template <typename InnerExecutor>
97 struct executor_with_default : InnerExecutor
99 /// Specify @c use_awaitable_t as the default completion token type.
100 typedef use_awaitable_t default_completion_token_type;
102 /// Construct the adapted executor from the inner executor type.
103 template <typename InnerExecutor1>
104 executor_with_default(const InnerExecutor1& ex,
107 !is_same<InnerExecutor1, executor_with_default>::value,
108 is_convertible<InnerExecutor1, InnerExecutor>,
111 >::type = 0) BOOST_ASIO_NOEXCEPT
117 /// Type alias to adapt an I/O object to use @c use_awaitable_t as its
118 /// default completion token type.
119 #if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES) \
120 || defined(GENERATING_DOCUMENTATION)
121 template <typename T>
122 using as_default_on_t = typename T::template rebind_executor<
123 executor_with_default<typename T::executor_type> >::other;
124 #endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
125 // || defined(GENERATING_DOCUMENTATION)
127 /// Function helper to adapt an I/O object to use @c use_awaitable_t as its
128 /// default completion token type.
129 template <typename T>
130 static typename decay<T>::type::template rebind_executor<
131 executor_with_default<typename decay<T>::type::executor_type>
133 as_default_on(BOOST_ASIO_MOVE_ARG(T) object)
135 return typename decay<T>::type::template rebind_executor<
136 executor_with_default<typename decay<T>::type::executor_type>
137 >::other(BOOST_ASIO_MOVE_CAST(T)(object));
140 #if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
141 const char* file_name_;
143 const char* function_name_;
144 #endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
147 /// A @ref completion_token object that represents the currently executing
150 * See the documentation for boost::asio::use_awaitable_t for a usage example.
152 #if defined(GENERATING_DOCUMENTATION)
153 constexpr use_awaitable_t<> use_awaitable;
154 #elif defined(BOOST_ASIO_HAS_CONSTEXPR)
155 constexpr use_awaitable_t<> use_awaitable(0, 0, 0);
156 #elif defined(BOOST_ASIO_MSVC)
157 __declspec(selectany) use_awaitable_t<> use_awaitable(0, 0, 0);
163 #include <boost/asio/detail/pop_options.hpp>
165 #include <boost/asio/impl/use_awaitable.hpp>
167 #endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
169 #endif // BOOST_ASIO_USE_AWAITABLE_HPP