include/boost/capy/asio/executor_adapter.hpp

90.9% Lines (30/33) 64.6% List of functions (42/65)
executor_adapter.hpp
f(x) Functions (65)
Function Calls Lines Blocks
boost::capy::detail::asio_adapter_context_service<boost::asio::execution_context>::asio_adapter_context_service(boost::capy::execution_context&) :44 1x 100.0% 80.0% boost::capy::detail::asio_adapter_context_service<boost::asio::execution_context>::shutdown() :45 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0> const&) :121 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0> const&) :121 5x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter<1>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter<4>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0> const&) :121 2x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<5>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0> const&) :121 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<5>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::asio_executor_adapter<1>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::asio_executor_adapter<4>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4> const&) :121 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 0> const&) :121 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>&&) :139 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<4>(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>&&) :139 6x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter<0>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>&&) :139 8x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<1>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>&&) :139 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<4>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>&&) :139 6x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::asio_executor_adapter<5>(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>&&) :139 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<1>(boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 1>&&) :139 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 1>::asio_executor_adapter<std::pmr::polymorphic_allocator<void> >(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 1>, std::pmr::polymorphic_allocator<void> const&) :170 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::asio_executor_adapter<std::pmr::polymorphic_allocator<void> >(boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>, std::pmr::polymorphic_allocator<void> const&) :170 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 0>::asio_executor_adapter<std::pmr::polymorphic_allocator<void> >(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>, std::allocator<void> const&) :170 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 1>::asio_executor_adapter<std::pmr::polymorphic_allocator<void> >(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>, std::allocator<void> const&) :170 2x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::allocator<void>, 1>::asio_executor_adapter<std::pmr::polymorphic_allocator<void> >(boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 1>, std::allocator<void> const&) :170 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter(boost::capy::executor_ref) :188 6x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter(boost::capy::test_executor) :188 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 0>::asio_executor_adapter(boost::capy::thread_pool::executor_type) :188 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>::~asio_executor_adapter() :201 10x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 1>::~asio_executor_adapter() :201 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::~asio_executor_adapter() :201 17x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 0>::~asio_executor_adapter() :201 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 1>::~asio_executor_adapter() :201 2x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::~asio_executor_adapter() :201 16x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::~asio_executor_adapter() :201 6x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::~asio_executor_adapter() :201 9x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::~asio_executor_adapter() :201 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::allocator<void>, 1>::~asio_executor_adapter() :201 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 0>::~asio_executor_adapter() :201 3x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::pmr::polymorphic_allocator<void>, 1>::~asio_executor_adapter() :201 12x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::operator==(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0> const&) const :245 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::operator==(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1> const&) const :245 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::operator==(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4> const&) const :245 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::operator==(boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5> const&) const :245 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 1>::execute<boost::asio::detail::work_dispatcher<boost::asio::detail::empty_work_function, boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot>, boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>, void> >(boost::asio::detail::work_dispatcher<boost::asio::detail::empty_work_function, boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot>, boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 0>, void>&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::execute<boost::asio::detail::binder0<boost::asio::detail::binder2<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot, boost::system::error_code, unsigned long>, boost::system::error_code, unsigned long> > >(boost::asio::detail::binder0<boost::asio::detail::binder2<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot, boost::system::error_code, unsigned long>, boost::system::error_code, unsigned long> >&&) const :277 2x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::execute<boost::asio::detail::binder0<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot> > >(boost::asio::detail::binder0<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot> >&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::executor_ref, std::pmr::polymorphic_allocator<void>, 4>::execute<boost::asio::detail::binder2<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot, boost::system::error_code, unsigned long>, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2<boost::capy::detail::asio_coroutine_completion_handler<boost::asio::cancellation_slot, boost::system::error_code, unsigned long>, boost::system::error_code, unsigned long>&&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 0>::execute<boost::asio::detail::binder0<boost::capy::boost_asio_test::testExecutor()::{lambda()#2}> >(boost::asio::detail::binder0<boost::capy::boost_asio_test::testExecutor()::{lambda()#2}>&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 1>::execute<boost::asio::detail::binder0<boost::capy::boost_asio_test::testExecutor()::{lambda()#1}> >(boost::asio::detail::binder0<boost::capy::boost_asio_test::testExecutor()::{lambda()#1}>&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::allocator<void>, 1>::execute<boost::asio::detail::work_dispatcher<boost::asio::detail::empty_work_function, boost::asio::detail::append_handler<boost::asio::detail::promise_handler<void (std::__exception_ptr::exception_ptr), std::allocator<void> >, std::__exception_ptr::exception_ptr>, boost::asio::detail::promise_executor<void, boost::asio::execution::detail::blocking::possibly_t<0> >, void> >(boost::asio::detail::work_dispatcher<boost::asio::detail::empty_work_function, boost::asio::detail::append_handler<boost::asio::detail::promise_handler<void (std::__exception_ptr::exception_ptr), std::allocator<void> >, std::__exception_ptr::exception_ptr>, boost::asio::detail::promise_executor<void, boost::asio::execution::detail::blocking::possibly_t<0> >, void>&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::execute<boost::asio::detail::executor_function>(boost::asio::detail::executor_function&&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::execute<boost::asio::detail::executor_function_view&>(boost::asio::detail::executor_function_view&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::execute<boost::asio::detail::executor_function>(boost::asio::detail::executor_function&&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::execute<boost::asio::detail::executor_function_view&>(boost::asio::detail::executor_function_view&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::execute<boost::asio::detail::executor_function>(boost::asio::detail::executor_function&&) const :277 1x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::execute<boost::asio::detail::executor_function_view&>(boost::asio::detail::executor_function_view&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::execute<boost::asio::detail::executor_function>(boost::asio::detail::executor_function&&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::execute<boost::asio::detail::executor_function_view&>(boost::asio::detail::executor_function_view&) const :277 0 0.0% 0.0% void boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::allocator<void>, 1>::execute<boost::asio::detail::binder0<boost::asio::detail::append_handler<boost::asio::detail::read_op<boost::capy::async_read_stream<boost::capy::noexcept_stream<boost::capy::test::read_stream>, boost::capy::thread_pool::executor_type>, boost::asio::mutable_buffer, boost::asio::mutable_buffer const*, boost::asio::detail::transfer_all_t, boost::capy::boost_asio_test::testStreamToAsio()::{lambda(boost::system::error_code, unsigned long)#2}>, std::error_code, unsigned long> > >(boost::asio::detail::binder0<boost::asio::detail::append_handler<boost::asio::detail::read_op<boost::capy::async_read_stream<boost::capy::noexcept_stream<boost::capy::test::read_stream>, boost::capy::thread_pool::executor_type>, boost::asio::mutable_buffer, boost::asio::mutable_buffer const*, boost::asio::detail::transfer_all_t, boost::capy::boost_asio_test::testStreamToAsio()::{lambda(boost::system::error_code, unsigned long)#2}>, std::error_code, unsigned long> >&&) const :277 2x 100.0% 100.0% void boost::capy::asio_executor_adapter<boost::capy::thread_pool::executor_type, std::allocator<void>, 1>::execute<boost::asio::detail::binder0<boost::asio::detail::append_handler<boost::asio::detail::write_op<boost::capy::async_write_stream<boost::capy::noexcept_stream<boost::capy::test::write_stream>, boost::capy::thread_pool::executor_type>, boost::asio::const_buffer, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, boost::capy::boost_asio_test::testStreamToAsio()::{lambda(boost::system::error_code, unsigned long)#1}>, std::error_code, unsigned long> > >(boost::asio::detail::binder0<boost::asio::detail::append_handler<boost::asio::detail::write_op<boost::capy::async_write_stream<boost::capy::noexcept_stream<boost::capy::test::write_stream>, boost::capy::thread_pool::executor_type>, boost::asio::const_buffer, boost::asio::const_buffer const*, boost::asio::detail::transfer_all_t, boost::capy::boost_asio_test::testStreamToAsio()::{lambda(boost::system::error_code, unsigned long)#1}>, std::error_code, unsigned long> >&&) const :277 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 0>::context() const :298 1x 100.0% 100.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 1>::context() const :298 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 4>::context() const :298 0 0.0% 0.0% boost::capy::asio_executor_adapter<boost::capy::test_executor, std::pmr::polymorphic_allocator<void>, 5>::context() const :298 0 0.0% 0.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
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 // Official repository: https://github.com/cppalliance/capy
8 //
9
10 #ifndef BOOST_CAPY_ASIO_EXECUTOR_ADAPTER_HPP
11 #define BOOST_CAPY_ASIO_EXECUTOR_ADAPTER_HPP
12
13 #include <boost/capy/asio/detail/continuation.hpp>
14 #include <boost/capy/ex/any_executor.hpp>
15 #include <boost/capy/ex/execution_context.hpp>
16 #include <memory_resource>
17
18
19 namespace boost {
20 namespace capy {
21
22 /** @addtogroup asio
23 * @{
24 */
25
26 namespace detail
27 {
28
29 /** @brief Service that bridges capy's execution_context with Asio's.
30 * @internal
31 *
32 * This service inherits from both capy's service and the target Asio
33 * execution context, allowing capy executors wrapped in `asio_executor_adapter`
34 * to be queried for their Asio execution context.
35 *
36 * @tparam ExecutionContext The Asio execution_context type (boost::asio or standalone)
37 */
38 template<typename ExecutionContext>
39 struct asio_adapter_context_service
40 : execution_context::service,
41 // shutdown is protected
42 ExecutionContext
43 {
44 1x asio_adapter_context_service(boost::capy::execution_context &) {}
45 1x void shutdown() override {ExecutionContext::shutdown();}
46 };
47
48 }
49
50
51 /** @brief Adapts a capy executor to be usable with Asio.
52 *
53 * `asio_executor_adapter` wraps a capy executor and exposes it as an
54 * Asio-compatible executor. This allows capy coroutines and executors to
55 * interoperate seamlessly with Asio's async operations.
56 *
57 * The adapter tracks execution properties (blocking behavior and work tracking)
58 * as compile-time template parameters for zero-overhead property queries.
59 *
60 * @tparam Executor The underlying capy executor type (default: `capy::any_executor`)
61 * @tparam Allocator The allocator type for handler allocation
62 * (default: `std::pmr::polymorphic_allocator<void>`)
63 * @tparam Bits Compile-time bitfield encoding blocking and work-tracking properties
64 *
65 * @par Execution Properties
66 * The adapter supports the standard Asio execution properties:
67 * - `blocking`: `possibly` (default), `never`, or `always`
68 * - `outstanding_work`: `untracked` (default) or `tracked`
69 * - `allocator`: Custom allocator for handler allocation
70 * - `context`: Returns the associated capy execution_context
71 *
72 * @par Example
73 * @code
74 * // Wrap a capy executor for use with Asio
75 * capy::any_executor capy_exec = ...;
76 * asio_executor_adapter<> asio_exec(capy_exec);
77 *
78 * // Use with Asio operations
79 * asio::post(asio_exec, []{ std::cout << "Hello from capy!\n"; });
80 *
81 * // Require non-blocking execution
82 * auto never_blocking = asio::require(asio_exec,
83 * asio::execution::blocking.never);
84 * @endcode
85 *
86 * @see wrap_asio_executor For the reverse direction (Asio to capy)
87 */
88 template<typename Executor = capy::any_executor,
89 typename Allocator = std::pmr::polymorphic_allocator<void>,
90 int Bits = 0>
91 struct asio_executor_adapter
92 {
93 /// @name Blocking Property Constants
94 /// @{
95 constexpr static int blocking_possibly = 0b000; ///< May block the caller
96 constexpr static int blocking_never = 0b001; ///< Never blocks the caller
97 constexpr static int blocking_always = 0b010; ///< Always blocks until complete
98 constexpr static int blocking_mask = 0b011; ///< Mask for blocking bits
99 /// @}
100
101 /// @name Work Tracking Property Constants
102 /// @{
103 constexpr static int work_untracked = 0b000; ///< Work is not tracked
104 constexpr static int work_tracked = 0b100; ///< Outstanding work is tracked
105 constexpr static int work_mask = 0b100; ///< Mask for work tracking bit
106 /// @}
107
108
109 /// @name Constructors
110 /// @{
111
112 /** @brief Copy constructor from adapter with different property bits.
113 *
114 * Creates a copy with potentially different execution properties.
115 * If this adapter tracks work, `on_work_started()` is called.
116 *
117 * @tparam Bits_ The source adapter's property bits
118 * @param rhs The source adapter to copy from
119 */
120 template<int Bits_>
121 14x asio_executor_adapter(
122 const asio_executor_adapter<Executor, Allocator, Bits_> & rhs)
123 noexcept(std::is_nothrow_copy_constructible_v<Executor>)
124 14x : executor_(rhs.executor_), allocator_(rhs.allocator_)
125 {
126 if constexpr((Bits & work_mask) == work_tracked)
127 8x executor_.on_work_started();
128 14x }
129
130 /** @brief Move constructor from adapter with different property bits.
131 *
132 * Moves from another adapter with potentially different properties.
133 * If this adapter tracks work, `on_work_started()` is called.
134 *
135 * @tparam Bits_ The source adapter's property bits
136 * @param rhs The source adapter to move from
137 */
138 template<int Bits_>
139 27x asio_executor_adapter(
140 asio_executor_adapter<Executor, Allocator, Bits_> && rhs)
141 noexcept(std::is_nothrow_move_constructible_v<Executor>)
142 27x : executor_(std::move(rhs.executor_))
143 27x , allocator_(std::move(rhs.allocator_))
144 {
145 if constexpr((Bits & work_mask) == work_tracked)
146 12x executor_.on_work_started();
147 27x }
148
149 /** @brief Constructs from executor and allocator.
150 *
151 * @param executor The capy executor to wrap
152 * @param alloc The allocator for handler allocation
153 */
154 asio_executor_adapter(Executor executor, const Allocator & alloc)
155 noexcept(std::is_nothrow_move_constructible_v<Executor>
156 && std::is_nothrow_copy_constructible_v<Allocator>)
157 : executor_(std::move(executor)), allocator_(alloc)
158 {
159 if constexpr((Bits & work_mask) == work_tracked)
160 executor_.on_work_started();
161 }
162
163 /** @brief Constructs from adapter with different allocator.
164 *
165 * @tparam OtherAllocator The source adapter's allocator type
166 * @param executor The source adapter
167 * @param alloc The new allocator to use
168 */
169 template<typename OtherAllocator>
170 10x explicit asio_executor_adapter(
171 asio_executor_adapter<Executor, OtherAllocator, Bits> executor,
172 const Allocator & alloc)
173 noexcept(std::is_nothrow_move_constructible_v<Executor> &&
174 std::is_nothrow_copy_constructible_v<Allocator>)
175 10x : executor_(std::move(executor.executor_)), allocator_(alloc)
176 {
177 if constexpr((Bits & work_mask) == work_tracked)
178 3x executor_.on_work_started();
179 10x }
180
181
182 /** @brief Constructs from a capy executor.
183 *
184 * The allocator is obtained from the executor's context frame allocator.
185 *
186 * @param executor The capy executor to wrap
187 */
188 12x asio_executor_adapter(Executor executor)
189 noexcept(std::is_nothrow_move_constructible_v<Executor>)
190 12x : executor_(std::move(executor))
191 12x , allocator_(executor_.context().get_frame_allocator())
192 {
193 if constexpr((Bits & work_mask) == work_tracked)
194 executor_.on_work_started();
195 12x }
196
197 /** @brief Destructor.
198 *
199 * If work tracking is enabled, calls `on_work_finished()`.
200 */
201 82x ~asio_executor_adapter()
202 {
203 if constexpr((Bits & work_mask) == work_tracked)
204 26x executor_.on_work_finished();
205 82x }
206
207 /// @}
208
209 /// @name Assignment
210 /// @{
211
212 /** @brief Copy assignment from adapter with different property bits.
213 *
214 * Properly handles work tracking when changing executors.
215 *
216 * @tparam Bits_ The source adapter's property bits
217 * @param rhs The source adapter
218 * @return Reference to this adapter
219 */
220 template<int Bits_>
221 asio_executor_adapter & operator=(
222 const asio_executor_adapter<Executor, Allocator, Bits_> & rhs)
223 {
224
225 if constexpr((Bits & work_mask) == work_tracked)
226 if (rhs.executor_ != executor_)
227 {
228 rhs.executor_.on_work_started();
229 executor_.on_work_finished();
230 }
231
232 executor_ = rhs.executor_;
233 allocator_ = rhs.allocator_;
234 }
235
236 /// @}
237
238 /// @name Comparison
239 /// @{
240
241 /** @brief Equality comparison.
242 * @param rhs The adapter to compare with
243 * @return `true` if both executor and allocator are equal
244 */
245 bool operator==(const asio_executor_adapter & rhs) const noexcept
246 {
247 return executor_ == rhs.executor_
248 && allocator_ == rhs.allocator_;
249 }
250
251 /** @brief Inequality comparison.
252 * @param rhs The adapter to compare with
253 * @return `true` if executor or allocator differs
254 */
255 bool operator!=(const asio_executor_adapter & rhs) const noexcept
256 {
257 return executor_ != rhs.executor_
258 && allocator_ != rhs.allocator_;
259 }
260
261 /// @}
262
263 /// @name Execution
264 /// @{
265
266 /** @brief Executes a function according to the blocking property.
267 *
268 * The execution behavior depends on the `Bits` template parameter:
269 * - `blocking_never`: Posts the function for deferred execution
270 * - `blocking_possibly`: Dispatches (may run inline or post)
271 * - `blocking_always`: Executes the function inline immediately
272 *
273 * @tparam Function The callable type
274 * @param f The function to execute
275 */
276 template <typename Function>
277 11x void execute(Function&& f) const
278 {
279 if constexpr ((Bits & blocking_mask) == blocking_never)
280 6x executor_.post(
281 6x detail::make_continuation(std::forward<Function>(f), allocator_));
282 else if constexpr((Bits & blocking_mask) == blocking_possibly)
283 5x executor_.dispatch(
284 5x detail::make_continuation(std::forward<Function>(f), allocator_)
285 5x ).resume();
286 else if constexpr((Bits & blocking_mask) == blocking_always)
287 std::forward<Function>(f)();
288 11x }
289
290 /// @}
291
292 /// @name Accessors
293 /// @{
294
295 /** @brief Returns the associated execution context.
296 * @return Reference to the capy execution_context
297 */
298 1x execution_context & context() const {return executor_.context(); }
299
300 /** @brief Returns the associated allocator.
301 * @return Copy of the allocator
302 */
303 Allocator get_allocator() const noexcept {return allocator_;}
304
305 /** @brief Returns the underlying capy executor.
306 * @return Copy of the wrapped executor
307 */
308 const Executor get_capy_executor() const {return executor_;}
309
310 /// @}
311 private:
312
313 template<typename, typename, int>
314 friend struct asio_executor_adapter;
315 Executor executor_;
316 Allocator allocator_;
317
318 };
319
320 /** @} */ // end of asio group
321
322 }
323 }
324
325
326 #endif //BOOST_CAPY_ASIO_EXECUTOR_ADAPTER_HPP
327
328