1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- // Copyright (c) 2022 Klemens D. Morgenstern
- //
- // 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 BOOST_COBALT_CONCEPTS_HPP
- #define BOOST_COBALT_CONCEPTS_HPP
- #include <coroutine>
- #include <concepts>
- #include <utility>
- #include <boost/asio/error.hpp>
- #include <boost/asio/is_executor.hpp>
- #include <boost/asio/execution/executor.hpp>
- #include <boost/system/system_error.hpp>
- #include <boost/throw_exception.hpp>
- namespace boost::cobalt
- {
- // tag::outline[]
- template<typename Awaitable, typename Promise = void>
- concept awaitable_type = requires (Awaitable aw, std::coroutine_handle<Promise> h)
- {
- {aw.await_ready()} -> std::convertible_to<bool>;
- {aw.await_suspend(h)};
- {aw.await_resume()};
- };
- template<typename Awaitable, typename Promise = void>
- concept awaitable =
- awaitable_type<Awaitable, Promise>
- || requires (Awaitable && aw) { {std::forward<Awaitable>(aw).operator co_await()} -> awaitable_type<Promise>;}
- || requires (Awaitable && aw) { {operator co_await(std::forward<Awaitable>(aw))} -> awaitable_type<Promise>;};
- //end::outline[]
- struct promise_throw_if_cancelled_base;
- template<typename Promise = void>
- struct enable_awaitables
- {
- template<awaitable<Promise> Aw>
- Aw && await_transform(Aw && aw,
- const boost::source_location & loc = BOOST_CURRENT_LOCATION)
- {
- if constexpr (std::derived_from<Promise, promise_throw_if_cancelled_base>)
- {
- auto p = static_cast<Promise*>(this);
- // a promise inheriting promise_throw_if_cancelled_base needs to also have a .cancelled() function
- if (!!p->cancelled() && p->throw_if_cancelled())
- {
- constexpr boost::source_location here{BOOST_CURRENT_LOCATION};
- boost::throw_exception(system::system_error(
- {asio::error::operation_aborted, &here},
- "throw_if_cancelled"), loc);
- }
- }
- return static_cast<Aw&&>(aw);
- }
- };
- template <typename T>
- concept with_get_executor = requires (T& t)
- {
- {t.get_executor()} -> asio::execution::executor;
- };
- }
- #endif //BOOST_COBALT_CONCEPTS_HPP
|