|
- //
- // awaitable.hpp
- // ~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2019 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_AWAITABLE_HPP
- #define ASIO_AWAITABLE_HPP
-
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
- #include "asio/detail/config.hpp"
-
- #if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
-
- #include <experimental/coroutine>
- #include "asio/executor.hpp"
-
- #include "asio/detail/push_options.hpp"
-
- namespace asio {
- namespace detail {
-
- using std::experimental::coroutine_handle;
- using std::experimental::suspend_always;
-
- template <typename> class awaitable_thread;
- template <typename, typename> class awaitable_frame;
-
- } // namespace detail
-
- /// The return type of a coroutine or asynchronous operation.
- template <typename T, typename Executor = executor>
- class awaitable
- {
- public:
- /// The type of the awaited value.
- typedef T value_type;
-
- /// The executor type that will be used for the coroutine.
- typedef Executor executor_type;
-
- /// Default constructor.
- constexpr awaitable() noexcept
- : frame_(nullptr)
- {
- }
-
- /// Move constructor.
- awaitable(awaitable&& other) noexcept
- : frame_(std::exchange(other.frame_, nullptr))
- {
- }
-
- /// Destructor
- ~awaitable()
- {
- if (frame_)
- frame_->destroy();
- }
-
- /// Checks if the awaitable refers to a future result.
- bool valid() const noexcept
- {
- return !!frame_;
- }
-
- #if !defined(GENERATING_DOCUMENTATION)
-
- // Support for co_await keyword.
- bool await_ready() const noexcept
- {
- return false;
- }
-
- // Support for co_await keyword.
- template <class U>
- void await_suspend(
- detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
- {
- frame_->push_frame(&h.promise());
- }
-
- // Support for co_await keyword.
- T await_resume()
- {
- return frame_->get();
- }
-
- #endif // !defined(GENERATING_DOCUMENTATION)
-
- private:
- template <typename> friend class detail::awaitable_thread;
- template <typename, typename> friend class detail::awaitable_frame;
-
- // Not copy constructible or copy assignable.
- awaitable(const awaitable&) = delete;
- awaitable& operator=(const awaitable&) = delete;
-
- // Construct the awaitable from a coroutine's frame object.
- explicit awaitable(detail::awaitable_frame<T, Executor>* a)
- : frame_(a)
- {
- }
-
- detail::awaitable_frame<T, Executor>* frame_;
- };
-
- } // namespace asio
-
- #include "asio/detail/pop_options.hpp"
-
- #include "asio/impl/awaitable.hpp"
-
- #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
-
- #endif // ASIO_AWAITABLE_HPP
|