summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/impl/use_awaitable.hpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/impl/use_awaitable.hpp')
-rw-r--r--3rdparty/asio/include/asio/impl/use_awaitable.hpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/3rdparty/asio/include/asio/impl/use_awaitable.hpp b/3rdparty/asio/include/asio/impl/use_awaitable.hpp
new file mode 100644
index 00000000000..2f5449f5428
--- /dev/null
+++ b/3rdparty/asio/include/asio/impl/use_awaitable.hpp
@@ -0,0 +1,291 @@
+//
+// impl/use_awaitable.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_IMPL_USE_AWAITABLE_HPP
+#define ASIO_IMPL_USE_AWAITABLE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/async_result.hpp"
+#include "asio/cancellation_signal.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+template <typename Executor, typename T>
+class awaitable_handler_base
+ : public awaitable_thread<Executor>
+{
+public:
+ typedef void result_type;
+ typedef awaitable<T, Executor> awaitable_type;
+
+ // Construct from the entry point of a new thread of execution.
+ awaitable_handler_base(awaitable<awaitable_thread_entry_point, Executor> a,
+ const Executor& ex, cancellation_slot pcs, cancellation_state cs)
+ : awaitable_thread<Executor>(std::move(a), ex, pcs, cs)
+ {
+ }
+
+ // Transfer ownership from another awaitable_thread.
+ explicit awaitable_handler_base(awaitable_thread<Executor>* h)
+ : awaitable_thread<Executor>(std::move(*h))
+ {
+ }
+
+protected:
+ awaitable_frame<T, Executor>* frame() noexcept
+ {
+ return static_cast<awaitable_frame<T, Executor>*>(
+ this->entry_point()->top_of_stack_);
+ }
+};
+
+template <typename, typename...>
+class awaitable_handler;
+
+template <typename Executor>
+class awaitable_handler<Executor>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()()
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_void();
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor>
+class awaitable_handler<Executor, asio::error_code>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()(const asio::error_code& ec)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_void();
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor>
+class awaitable_handler<Executor, std::exception_ptr>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()(std::exception_ptr ex)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_void();
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, asio::error_code, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(const asio::error_code& ec, Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, std::exception_ptr, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(std::exception_ptr ex, Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler<Executor, asio::error_code, Ts...>
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(const asio::error_code& ec, Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler<Executor, std::exception_ptr, Ts...>
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(std::exception_ptr ex, Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->clear_cancellation_slot();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+#if defined(_MSC_VER)
+template <typename T>
+T dummy_return()
+{
+ return std::move(*static_cast<T*>(nullptr));
+}
+
+template <>
+inline void dummy_return()
+{
+}
+#endif // defined(_MSC_VER)
+
+template <typename Executor, typename R, typename... Args>
+class async_result<use_awaitable_t<Executor>, R(Args...)>
+{
+public:
+ typedef typename detail::awaitable_handler<
+ Executor, typename decay<Args>::type...> handler_type;
+ typedef typename handler_type::awaitable_type return_type;
+
+ template <typename Initiation, typename... InitArgs>
+ static return_type initiate(Initiation initiation,
+ use_awaitable_t<Executor> u, InitArgs... args)
+ {
+ (void)u;
+
+ co_await [&](auto* frame)
+ {
+ ASIO_HANDLER_LOCATION((u.file_name_, u.line_, u.function_name_));
+ handler_type handler(frame->detach_thread());
+ std::move(initiation)(std::move(handler), std::move(args)...);
+ return static_cast<handler_type*>(nullptr);
+ };
+
+ for (;;) {} // Never reached.
+#if defined(_MSC_VER)
+ co_return dummy_return<typename return_type::value_type>();
+#endif // defined(_MSC_VER)
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_IMPL_USE_AWAITABLE_HPP