Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:26

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_COBALT_CONCEPTS_HPP
0006 #define BOOST_COBALT_CONCEPTS_HPP
0007 
0008 #include <coroutine>
0009 #include <concepts>
0010 #include <utility>
0011 
0012 #include <boost/asio/error.hpp>
0013 #include <boost/asio/is_executor.hpp>
0014 #include <boost/asio/execution/executor.hpp>
0015 #include <boost/system/system_error.hpp>
0016 #include <boost/throw_exception.hpp>
0017 
0018 namespace boost::cobalt
0019 {
0020 
0021 // tag::outline[]
0022 template<typename Awaitable, typename Promise = void>
0023 concept awaitable_type = requires (Awaitable aw, std::coroutine_handle<Promise> h)
0024 {
0025     {aw.await_ready()} -> std::convertible_to<bool>;
0026     {aw.await_suspend(h)};
0027     {aw.await_resume()};
0028 };
0029 
0030 template<typename Awaitable, typename Promise = void>
0031 concept awaitable =
0032         awaitable_type<Awaitable, Promise>
0033     || requires (Awaitable && aw) { {std::forward<Awaitable>(aw).operator co_await()} -> awaitable_type<Promise>;}
0034     || requires (Awaitable && aw) { {operator co_await(std::forward<Awaitable>(aw))} -> awaitable_type<Promise>;};
0035 //end::outline[]
0036 
0037 struct promise_throw_if_cancelled_base;
0038 template<typename Promise = void>
0039 struct enable_awaitables
0040 {
0041     template<awaitable<Promise> Aw>
0042     Aw && await_transform(Aw && aw,
0043                           const boost::source_location & loc = BOOST_CURRENT_LOCATION)
0044     {
0045         if constexpr (std::derived_from<Promise, promise_throw_if_cancelled_base>)
0046         {
0047           auto p = static_cast<Promise*>(this);
0048           // a promise inheriting promise_throw_if_cancelled_base needs to also have a .cancelled() function
0049           if (!!p->cancelled() && p->throw_if_cancelled())
0050           {
0051             constexpr boost::source_location here{BOOST_CURRENT_LOCATION};
0052             boost::throw_exception(system::system_error(
0053                 {asio::error::operation_aborted, &here},
0054                 "throw_if_cancelled"), loc);
0055           }
0056 
0057         }
0058         return static_cast<Aw&&>(aw);
0059     }
0060 };
0061 
0062 template <typename T>
0063 concept with_get_executor = requires (T& t)
0064 {
0065   {t.get_executor()} -> asio::execution::executor;
0066 };
0067 
0068 
0069 }
0070 
0071 #endif //BOOST_COBALT_CONCEPTS_HPP