| 1 | // |
|---|---|
| 2 | // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) |
| 3 | // |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | // |
| 7 | |
| 8 | #ifndef BOOST_COBALT_DETAIL_DETACHED_HPP |
| 9 | #define BOOST_COBALT_DETAIL_DETACHED_HPP |
| 10 | |
| 11 | #include <boost/cobalt/detail/exception.hpp> |
| 12 | #include <boost/cobalt/detail/forward_cancellation.hpp> |
| 13 | #include <boost/cobalt/detail/wrapper.hpp> |
| 14 | #include <boost/cobalt/detail/this_thread.hpp> |
| 15 | |
| 16 | #include <boost/asio/cancellation_signal.hpp> |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | #include <boost/core/exchange.hpp> |
| 22 | |
| 23 | #include <coroutine> |
| 24 | #include <optional> |
| 25 | #include <utility> |
| 26 | #include <boost/asio/bind_allocator.hpp> |
| 27 | |
| 28 | namespace boost::cobalt |
| 29 | { |
| 30 | |
| 31 | struct detached; |
| 32 | |
| 33 | namespace detail |
| 34 | { |
| 35 | |
| 36 | struct detached_promise |
| 37 | : promise_memory_resource_base, |
| 38 | promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>, |
| 39 | promise_throw_if_cancelled_base, |
| 40 | enable_awaitables<detached_promise>, |
| 41 | enable_await_allocator<detached_promise>, |
| 42 | enable_await_executor<detached_promise> |
| 43 | { |
| 44 | using promise_cancellation_base<asio::cancellation_slot, asio::enable_total_cancellation>::await_transform; |
| 45 | using promise_throw_if_cancelled_base::await_transform; |
| 46 | using enable_awaitables<detached_promise>::await_transform; |
| 47 | using enable_await_allocator<detached_promise>::await_transform; |
| 48 | using enable_await_executor<detached_promise>::await_transform; |
| 49 | |
| 50 | [[nodiscard]] detached get_return_object(); |
| 51 | |
| 52 | std::suspend_never await_transform( |
| 53 | cobalt::this_coro::reset_cancellation_source_t<asio::cancellation_slot> reset) noexcept |
| 54 | { |
| 55 | this->reset_cancellation_source(source: reset.source); |
| 56 | return {}; |
| 57 | } |
| 58 | |
| 59 | using executor_type = executor; |
| 60 | executor_type exec; |
| 61 | const executor_type & get_executor() const {return exec;} |
| 62 | |
| 63 | template<typename ... Args> |
| 64 | detached_promise(Args & ...args) |
| 65 | : |
| 66 | #if !defined(BOOST_COBALT_NO_PMR) |
| 67 | promise_memory_resource_base(detail::get_memory_resource_from_args(args...)), |
| 68 | #endif |
| 69 | exec{detail::get_executor_from_args(args...)} |
| 70 | { |
| 71 | } |
| 72 | |
| 73 | std::suspend_never initial_suspend() {return {};} |
| 74 | std::suspend_never final_suspend() noexcept {return {};} |
| 75 | |
| 76 | void return_void() {} |
| 77 | void unhandled_exception() |
| 78 | { |
| 79 | throw ; |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | } |
| 84 | |
| 85 | } |
| 86 | |
| 87 | #endif //BOOST_COBALT_DETAIL_DETACHED_HPP |
| 88 |
