include/boost/capy/ex/run.hpp

100.0% Lines (283 / 283, 3 excl) 87.5% Functions (337 / 385, 1 excl)
run.hpp
f(x) Functions (386)
Function Calls Lines Blocks
boost::capy::detail::boundary_trampoline::promise_type::unwind() :92 10x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::~promise_type() :100 95x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::get_return_object() :111 95x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::initial_suspend() :117 95x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::final_suspend() :119 93x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::final_suspend()::awaiter::await_ready() const :124 93x 100.0% 100.0% boost::capy::detail::boundary_trampoline::promise_type::final_suspend()::awaiter::await_suspend(std::__n4861::coroutine_handle<void>) :126 93x 100.0% 88.0% boost::capy::detail::boundary_trampoline::promise_type::final_suspend()::awaiter::await_resume() const :158 – – – boost::capy::detail::boundary_trampoline::promise_type::return_void() :163 93x 100.0% 100.0% boost::capy::detail::boundary_trampoline::boundary_trampoline() :169 96x 100.0% 100.0% boost::capy::detail::boundary_trampoline::~boundary_trampoline() :171 285x 100.0% 100.0% boost::capy::detail::boundary_trampoline::boundary_trampoline(boost::capy::detail::boundary_trampoline&&) :183 94x 100.0% 100.0% boost::capy::detail::boundary_trampoline::operator=(boost::capy::detail::boundary_trampoline&&) :186 96x 100.0% 100.0% boost::capy::detail::boundary_trampoline::boundary_trampoline(std::__n4861::coroutine_handle<boost::capy::detail::boundary_trampoline::promise_type>) :201 95x 100.0% 100.0% boost::capy::detail::make_boundary_trampoline() :205 95x 100.0% 44.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::~run_awaitable_ex() :242 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::~run_awaitable_ex() :242 2x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::~run_awaitable_ex() :242 4x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::~run_awaitable_ex() :242 2x 100.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::~run_awaitable_ex() :242 4x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::~run_awaitable_ex() :242 4x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::~run_awaitable_ex() :242 4x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::~run_awaitable_ex() :242 2x 80.0% 81.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::~run_awaitable_ex() :242 2x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::~run_awaitable_ex() :242 104x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::~run_awaitable_ex() :242 2x 100.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::~run_awaitable_ex() :242 2x 100.0% 71.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::~run_awaitable_ex() :242 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::run_test::throwing_post_executor, true, void>::~run_awaitable_ex() :242 1x 80.0% 64.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::~run_awaitable_ex() :242 4x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::~run_awaitable_ex() :242 2x 100.0% 87.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::~run_awaitable_ex() :242 2x 100.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::~run_awaitable_ex() :242 18x 100.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::~run_awaitable_ex() :242 2x 80.0% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::~run_awaitable_ex() :242 2x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::~run_awaitable_ex() :242 6x 100.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::~run_awaitable_ex() :242 2x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::~run_awaitable_ex() :242 2x 80.0% 79.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::destroy_inner(void*) :255 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::destroy_inner(void*) :255 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::run_test::throwing_post_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::destroy_inner(void*) :255 6x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::destroy_inner(void*) :255 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::destroy_inner(void*) :255 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::lax_task) :264 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::queuing_executor, boost::capy::quitter<int>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::queuing_executor, boost::capy::quitter<std::tuple<std::error_code> >) :264 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::thread_pool::executor_type, boost::capy::quitter<std::tuple<std::error_code> >) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::queuing_executor, boost::capy::quitter<void>) :264 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::task<bool>) :264 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::run_awaitable_ex(boost::capy::strand<boost::capy::thread_pool::executor_type>, boost::capy::task<int>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::thread_pool::executor_type, boost::capy::task<int>) :264 52x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::thread_pool::executor_type, boost::capy::task<std::tuple<std::error_code> >) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::run_awaitable_ex(boost::capy::closing_executor, boost::capy::task<void>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::queuing_executor, boost::capy::task<void>) :264 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::run_test::throwing_post_executor, true, void>::run_awaitable_ex(boost::capy::run_test::throwing_post_executor, boost::capy::task<void>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::run_awaitable_ex(boost::capy::strand<boost::capy::executor_ref>, boost::capy::task<void>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::run_awaitable_ex(boost::capy::strand<boost::capy::thread_pool::executor_type>, boost::capy::task<void>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::run_awaitable_ex(boost::capy::test::priority_executor<boost::capy::queuing_executor>, boost::capy::task<void>) :264 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::task<void>) :264 9x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::thread_pool::executor_type, boost::capy::task<void>) :264 3x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::test::custom_task<int>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::test::custom_task<void>) :264 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::run_awaitable_ex(boost::capy::queuing_executor, boost::capy::quitter<std::tuple<std::error_code> >, std::stop_token) :272 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::task<bool>, std::stop_token) :272 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::task<int>, std::stop_token) :272 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::test_executor, boost::capy::task<void>, std::stop_token) :272 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::run_awaitable_ex(boost::capy::thread_pool::executor_type, boost::capy::task<void>, std::stop_token) :272 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::run_awaitable_ex<boost::capy::test_allocator<std::byte> >(boost::capy::test_executor, boost::capy::test_allocator<std::byte>, boost::capy::task<int>) :283 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::run_awaitable_ex<std::pmr::memory_resource*>(boost::capy::test_executor, std::pmr::memory_resource*, boost::capy::task<int>) :283 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::run_awaitable_ex<boost::capy::counting_allocator<std::byte> >(boost::capy::test_executor, boost::capy::counting_allocator<std::byte>, boost::capy::task<void>) :283 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::run_awaitable_ex<std::pmr::memory_resource*>(boost::capy::test_executor, std::pmr::memory_resource*, boost::capy::task<void>) :283 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::run_awaitable_ex<std::pmr::memory_resource*>(boost::capy::thread_pool::executor_type, std::pmr::memory_resource*, boost::capy::task<void>) :283 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::run_awaitable_ex<boost::capy::test_allocator<std::byte> >(boost::capy::test_executor, boost::capy::test_allocator<std::byte>, boost::capy::task<int>, std::stop_token) :293 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::run_awaitable_ex<std::pmr::memory_resource*>(boost::capy::test_executor, std::pmr::memory_resource*, boost::capy::task<int>, std::stop_token) :293 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::await_ready() const :301 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::await_ready() const :301 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::await_ready() const :301 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::await_ready() const :301 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::await_ready() const :301 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::await_ready() const :301 52x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::await_ready() const :301 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::await_ready() const :301 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::await_ready() const :301 9x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::await_ready() const :301 3x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::await_ready() const :301 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::await_resume() :306 1x 83.3% 75.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::await_resume() :306 1x 83.3% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::await_resume() :306 2x 83.3% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::await_resume() :306 2x 83.3% 80.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::await_resume() :306 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::await_resume() :306 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::await_resume() :306 52x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::await_resume() :306 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_resume() :306 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::await_resume() :306 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::await_resume() :306 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::await_resume() :306 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 79.4% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 79.4% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 2x 79.4% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 79.4% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 2x 79.4% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 2x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 2x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 52x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::run_test::throwing_post_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 97.0% 86.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 2x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 9x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 62.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 3x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :318 1x 78.8% 61.0% boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::lax_task, boost::capy::test_executor, true, void>&&) :386 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::quitter<int>, boost::capy::queuing_executor, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, false, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::queuing_executor, true, void>&&) :386 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::quitter<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::quitter<void>, boost::capy::queuing_executor, true, void>&&) :386 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, false, void>&&) :386 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<bool>, boost::capy::test_executor, true, void>&&) :386 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, std::pmr::memory_resource*>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, false, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::test_executor, true, std::pmr::memory_resource*>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<int>, boost::capy::thread_pool::executor_type, true, void>&&) :386 52x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<std::tuple<std::error_code> >, boost::capy::thread_pool::executor_type, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::closing_executor, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::queuing_executor, true, void>&&) :386 0 0.0% 0.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::executor_ref>, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>&&) :386 2x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, false, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, std::pmr::memory_resource*>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::test_executor, true, void>&&) :386 9x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, false, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::task<void>, boost::capy::thread_pool::executor_type, true, void>&&) :386 3x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<int>, boost::capy::test_executor, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>::run_awaitable_ex(boost::capy::detail::run_awaitable_ex<boost::capy::test::custom_task<void>, boost::capy::test_executor, true, void>&&) :386 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::~run_awaitable() :411 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::~run_awaitable() :411 6x 80.0% 47.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::~run_awaitable() :411 2x 80.0% 50.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::~run_awaitable() :411 2x 80.0% 47.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::~run_awaitable() :411 2x 80.0% 47.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::~run_awaitable() :411 2x 80.0% 47.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::~run_awaitable() :411 2x 80.0% 44.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::~run_awaitable() :411 2x 80.0% 47.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::~run_awaitable() :411 2x 100.0% 88.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::~run_awaitable() :411 22x 100.0% 88.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::run_awaitable(boost::capy::lax_task, std::stop_token) :430 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::run_awaitable(boost::capy::quitter<std::tuple<std::error_code> >, std::stop_token) :430 3x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::run_awaitable(boost::capy::task<int>, std::stop_token) :430 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::run_awaitable(boost::capy::task<void>, std::stop_token) :430 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::run_awaitable<boost::capy::test_allocator<std::byte> >(boost::capy::test_allocator<std::byte>, boost::capy::task<int>) :440 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::run_awaitable<std::pmr::memory_resource*>(std::pmr::memory_resource*, boost::capy::task<int>) :440 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::run_awaitable<boost::capy::counting_allocator<std::byte> >(boost::capy::counting_allocator<std::byte>, boost::capy::task<void>) :440 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::run_awaitable<std::pmr::memory_resource*>(std::pmr::memory_resource*, boost::capy::task<void>) :440 11x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::run_awaitable<boost::capy::test_allocator<std::byte> >(boost::capy::test_allocator<std::byte>, boost::capy::task<int>, std::stop_token) :449 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::run_awaitable<std::pmr::memory_resource*>(std::pmr::memory_resource*, boost::capy::task<int>, std::stop_token) :449 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::await_ready() const :456 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::await_ready() const :456 3x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::await_ready() const :456 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::await_ready() const :456 11x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::await_resume() :461 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::await_resume() :461 3x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::await_resume() :461 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::await_resume() :461 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::await_resume() :461 2x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 3x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::await_context const*) :467 11x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::lax_task, false, void>&&) :508 0 0.0% 0.0% boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::quitter<std::tuple<std::error_code> >, false, void>&&) :508 3x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<int>, false, boost::capy::test_allocator<std::byte> >&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<int>, false, std::pmr::memory_resource*>&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<int>, false, void>&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<int>, true, boost::capy::test_allocator<std::byte> >&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<int>, true, std::pmr::memory_resource*>&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<void>, false, void>&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<void>, true, boost::capy::counting_allocator<std::byte> >&&) :508 1x 100.0% 100.0% boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>::run_awaitable(boost::capy::detail::run_awaitable<boost::capy::task<void>, true, std::pmr::memory_resource*>&&) :508 11x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::run_wrapper_ex(boost::capy::test_executor, boost::capy::counting_allocator<std::byte>) :531 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::run_wrapper_ex(boost::capy::test_executor, boost::capy::test_allocator<std::byte>) :531 2x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::run_wrapper_ex(boost::capy::test_executor, std::stop_token, boost::capy::test_allocator<std::byte>) :540 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::~run_wrapper_ex() :553 1x 75.0% 80.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::~run_wrapper_ex() :553 1x 75.0% 80.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::~run_wrapper_ex() :553 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, boost::capy::test_allocator<std::byte> >::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :566 1x 100.0% 72.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::counting_allocator<std::byte> >::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :566 1x 100.0% 71.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, boost::capy::test_allocator<std::byte> >::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :566 1x 100.0% 83.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, std::pmr::memory_resource*>::run_wrapper_ex(boost::capy::test_executor, std::pmr::memory_resource*) :593 3x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::run_wrapper_ex(boost::capy::thread_pool::executor_type, std::pmr::memory_resource*) :593 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, std::pmr::memory_resource*>::run_wrapper_ex(boost::capy::test_executor, std::stop_token, std::pmr::memory_resource*) :601 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, std::pmr::memory_resource*>::~run_wrapper_ex() :613 1x 75.0% 75.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, std::pmr::memory_resource*>::~run_wrapper_ex() :613 3x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::~run_wrapper_ex() :613 1x 75.0% 67.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, std::pmr::memory_resource*>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :626 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, std::pmr::memory_resource*>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :626 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, std::pmr::memory_resource*>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :626 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, std::pmr::memory_resource*>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :626 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::closing_executor, true, void>::run_wrapper_ex(boost::capy::closing_executor) :648 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, true, void>::run_wrapper_ex(boost::capy::queuing_executor) :648 5x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::run_test::throwing_post_executor, true, void>::run_wrapper_ex(boost::capy::run_test::throwing_post_executor) :648 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::strand<boost::capy::executor_ref>, true, void>::run_wrapper_ex(boost::capy::strand<boost::capy::executor_ref>) :648 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::run_wrapper_ex(boost::capy::strand<boost::capy::thread_pool::executor_type>) :648 2x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::run_wrapper_ex(boost::capy::test::priority_executor<boost::capy::queuing_executor>) :648 2x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::run_wrapper_ex(boost::capy::test_executor) :648 13x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, void>::run_wrapper_ex(boost::capy::thread_pool::executor_type) :648 57x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, false, void>::run_wrapper_ex(boost::capy::queuing_executor, std::stop_token) :654 1x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, void>::run_wrapper_ex(boost::capy::test_executor, std::stop_token) :654 4x 100.0% 100.0% boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, false, void>::run_wrapper_ex(boost::capy::thread_pool::executor_type, std::stop_token) :654 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::closing_executor, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, false, void>::operator()<boost::capy::quitter<std::tuple<std::error_code> > >(boost::capy::quitter<std::tuple<std::error_code> >) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, true, void>::operator()<boost::capy::quitter<int> >(boost::capy::quitter<int>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, true, void>::operator()<boost::capy::quitter<std::tuple<std::error_code> > >(boost::capy::quitter<std::tuple<std::error_code> >) && :668 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, true, void>::operator()<boost::capy::quitter<void> >(boost::capy::quitter<void>) && :668 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::queuing_executor, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 0 0.0% 0.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::run_test::throwing_post_executor, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::strand<boost::capy::executor_ref>, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::strand<boost::capy::thread_pool::executor_type>, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test::priority_executor<boost::capy::queuing_executor>, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, void>::operator()<boost::capy::task<bool> >(boost::capy::task<bool>) && :668 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, void>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, false, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::operator()<boost::capy::lax_task>(boost::capy::lax_task) && :668 0 0.0% 0.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::operator()<boost::capy::task<bool> >(boost::capy::task<bool>) && :668 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 9x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::operator()<boost::capy::test::custom_task<int> >(boost::capy::test::custom_task<int>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::test_executor, true, void>::operator()<boost::capy::test::custom_task<void> >(boost::capy::test::custom_task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, false, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, void>::operator()<boost::capy::quitter<std::tuple<std::error_code> > >(boost::capy::quitter<std::tuple<std::error_code> >) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, void>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :668 52x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, void>::operator()<boost::capy::task<std::tuple<std::error_code> > >(boost::capy::task<std::tuple<std::error_code> >) && :668 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper_ex<boost::capy::thread_pool::executor_type, true, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :668 3x 100.0% 100.0% boost::capy::detail::run_wrapper<true, boost::capy::counting_allocator<std::byte> >::run_wrapper(boost::capy::counting_allocator<std::byte>) :696 1x 100.0% 100.0% boost::capy::detail::run_wrapper<true, boost::capy::test_allocator<std::byte> >::run_wrapper(boost::capy::test_allocator<std::byte>) :696 2x 100.0% 100.0% boost::capy::detail::run_wrapper<false, boost::capy::test_allocator<std::byte> >::run_wrapper(std::stop_token, boost::capy::test_allocator<std::byte>) :704 1x 100.0% 100.0% boost::capy::detail::run_wrapper<false, boost::capy::test_allocator<std::byte> >::~run_wrapper() :716 1x 75.0% 80.0% boost::capy::detail::run_wrapper<true, boost::capy::counting_allocator<std::byte> >::~run_wrapper() :716 1x 75.0% 80.0% boost::capy::detail::run_wrapper<true, boost::capy::test_allocator<std::byte> >::~run_wrapper() :716 2x 100.0% 100.0% auto boost::capy::detail::run_wrapper<false, boost::capy::test_allocator<std::byte> >::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :729 1x 100.0% 71.0% auto boost::capy::detail::run_wrapper<true, boost::capy::counting_allocator<std::byte> >::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :729 1x 100.0% 69.0% auto boost::capy::detail::run_wrapper<true, boost::capy::test_allocator<std::byte> >::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :729 1x 100.0% 82.0% boost::capy::detail::run_wrapper<true, std::pmr::memory_resource*>::run_wrapper(std::pmr::memory_resource*) :755 13x 100.0% 100.0% boost::capy::detail::run_wrapper<false, std::pmr::memory_resource*>::run_wrapper(std::stop_token, std::pmr::memory_resource*) :762 1x 100.0% 100.0% boost::capy::detail::run_wrapper<false, std::pmr::memory_resource*>::~run_wrapper() :773 1x 75.0% 75.0% boost::capy::detail::run_wrapper<true, std::pmr::memory_resource*>::~run_wrapper() :773 13x 100.0% 100.0% auto boost::capy::detail::run_wrapper<false, std::pmr::memory_resource*>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :786 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper<true, std::pmr::memory_resource*>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :786 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper<true, std::pmr::memory_resource*>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :786 11x 100.0% 100.0% boost::capy::detail::run_wrapper<false, void>::run_wrapper(std::stop_token) :807 5x 100.0% 100.0% auto boost::capy::detail::run_wrapper<false, void>::operator()<boost::capy::lax_task>(boost::capy::lax_task) && :819 0 0.0% 0.0% auto boost::capy::detail::run_wrapper<false, void>::operator()<boost::capy::quitter<std::tuple<std::error_code> > >(boost::capy::quitter<std::tuple<std::error_code> >) && :819 3x 100.0% 100.0% auto boost::capy::detail::run_wrapper<false, void>::operator()<boost::capy::task<int> >(boost::capy::task<int>) && :819 1x 100.0% 100.0% auto boost::capy::detail::run_wrapper<false, void>::operator()<boost::capy::task<void> >(boost::capy::task<void>) && :819 1x 100.0% 100.0% auto boost::capy::run<boost::capy::closing_executor>(boost::capy::closing_executor) :862 1x 100.0% 100.0% auto boost::capy::run<boost::capy::queuing_executor>(boost::capy::queuing_executor) :862 5x 100.0% 100.0% auto boost::capy::run<boost::capy::run_test::throwing_post_executor>(boost::capy::run_test::throwing_post_executor) :862 1x 100.0% 100.0% auto boost::capy::run<boost::capy::strand<boost::capy::executor_ref> >(boost::capy::strand<boost::capy::executor_ref>) :862 1x 100.0% 100.0% auto boost::capy::run<boost::capy::strand<boost::capy::thread_pool::executor_type> >(boost::capy::strand<boost::capy::thread_pool::executor_type>) :862 2x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor>(boost::capy::test_executor) :862 12x 100.0% 100.0% auto boost::capy::run<boost::capy::thread_pool::executor_type>(boost::capy::thread_pool::executor_type) :862 57x 100.0% 100.0% auto boost::capy::run<boost::capy::queuing_executor>(boost::capy::queuing_executor, std::stop_token) :880 1x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor>(boost::capy::test_executor, std::stop_token) :880 4x 100.0% 100.0% auto boost::capy::run<boost::capy::thread_pool::executor_type>(boost::capy::thread_pool::executor_type, std::stop_token) :880 1x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor>(boost::capy::test_executor, std::pmr::memory_resource*) :899 3x 100.0% 100.0% auto boost::capy::run<boost::capy::thread_pool::executor_type>(boost::capy::thread_pool::executor_type, std::pmr::memory_resource*) :899 1x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor, boost::capy::counting_allocator<std::byte> >(boost::capy::test_executor, boost::capy::counting_allocator<std::byte>) :922 1x 100.0% 80.0% auto boost::capy::run<boost::capy::test_executor, boost::capy::test_allocator<std::byte> >(boost::capy::test_executor, boost::capy::test_allocator<std::byte>) :922 2x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor>(boost::capy::test_executor, std::stop_token, std::pmr::memory_resource*) :942 1x 100.0% 100.0% auto boost::capy::run<boost::capy::test_executor, boost::capy::test_allocator<std::byte> >(boost::capy::test_executor, std::stop_token, boost::capy::test_allocator<std::byte>) :966 1x 100.0% 82.0% boost::capy::run(std::stop_token) :986 5x 100.0% 100.0% boost::capy::run(std::pmr::memory_resource*) :1001 13x 100.0% 100.0% auto boost::capy::run<boost::capy::counting_allocator<std::byte> >(boost::capy::counting_allocator<std::byte>) :1029 1x 100.0% 78.0% auto boost::capy::run<boost::capy::test_allocator<std::byte> >(boost::capy::test_allocator<std::byte>) :1029 2x 100.0% 100.0% boost::capy::run(std::stop_token, std::pmr::memory_resource*) :1044 1x 100.0% 100.0% auto boost::capy::run<boost::capy::test_allocator<std::byte> >(std::stop_token, boost::capy::test_allocator<std::byte>) :1065 1x 100.0% 80.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/capy
9 //
10
11 #ifndef BOOST_CAPY_RUN_HPP
12 #define BOOST_CAPY_RUN_HPP
13
14 #include <boost/capy/detail/config.hpp>
15 #include <boost/capy/detail/await_suspend_helper.hpp>
16 #include <boost/capy/detail/run.hpp>
17 #include <boost/capy/concept/executor.hpp>
18 #include <boost/capy/concept/context_runnable.hpp>
19 #include <boost/capy/ex/abandon.hpp>
20 #include <boost/capy/ex/executor_ref.hpp>
21 #include <coroutine>
22 #include <boost/capy/ex/frame_alloc_mixin.hpp>
23 #include <boost/capy/ex/frame_allocator.hpp>
24 #include <boost/capy/ex/await_context.hpp>
25
26 #include <exception>
27 #include <memory_resource>
28 #include <stop_token>
29 #include <type_traits>
30 #include <utility>
31 #include <variant>
32
33 /*
34 Allocator Lifetime Strategy
35 ===========================
36
37 When using run() with a custom allocator:
38
39 co_await run(ex, alloc)(my_task());
40
41 The wrapper run(ex, alloc) returns is a temporary holding the
42 frame_memory_resource my_task()'s frame is allocated from, so it must
43 live until that frame is freed: the awaitable is awaited in the
44 full-expression that made the wrapper, and the temporary lives until
45 the co_await completes. Keeping the awaitable and awaiting it later
46 frees the task's frame through a dead resource.
47
48 The awaitable also holds a copy of the allocator. In await_suspend it
49 overwrites the promise's saved frame_allocator pointer with the
50 awaitable's resource, so tasks the inner task creates allocate from
51 it through TLS.
52 */
53
54 namespace boost::capy::detail {
55
56 /** Minimal coroutine that dispatches through the caller's executor.
57
58 Sits between the inner task and the parent when executors
59 diverge. The inner task's `final_suspend` resumes this
60 trampoline via symmetric transfer. The trampoline's own
61 `final_suspend` posts the parent through the caller's executor to
62 restore the correct execution context.
63
64 It also owns the inner task's segment. Abandoning that segment
65 resumes the trampoline on the inner executor, or has a closed
66 executor destroy it: either way it destroys the inner task, which
67 unwinds the segment, then abandons the caller's segment, which
68 unwinds the parent on its own executor. The caller's execution
69 context must outlive that.
70 */
71 struct boundary_trampoline
72 {
73 struct promise_type
74 : detail::process_frame_mixin
75 {
76 executor_ref caller_ex_;
77 continuation parent_;
78 chain_owner segment_;
79 // The inner task reports a stop-caused abandon (a quitter). For
80 // any other task such an abandon is torn down like any other.
81 bool stoppable_ = false;
82 // The awaitable's trampoline object until the inner task
83 // completes or is unwound; null afterward.
84 boundary_trampoline* owner_ = nullptr;
85 // Destroys the inner task the awaitable owns.
86 void (*destroy_inner_)(void*) noexcept = nullptr;
87 void* awaitable_ = nullptr;
88
89 // Unwind the inner segment, then hand the parent to its own
90 // segment's owner. The last touch of this frame: abandoning the
91 // parent can destroy the awaitable, and this frame with it.
92 10x void unwind() noexcept
93 {
94 10x destroy_inner_(awaitable_);
95 10x owner_ = nullptr;
96 10x auto parent = parent_;
97 10x capy::abandon(parent);
98 10x }
99
100 95x ~promise_type()
101 {
102 // Linked only when a closed executor destroyed this frame
103 // instead of resuming it to unwind.
104 95x if(owner_)
105 {
106 1x owner_->h_ = nullptr;
107 1x unwind();
108 }
109 95x }
110
111 95x boundary_trampoline get_return_object() noexcept
112 {
113 return boundary_trampoline{
114 95x std::coroutine_handle<promise_type>::from_promise(*this)};
115 }
116
117 95x std::suspend_always initial_suspend() noexcept { return {}; }
118
119 93x auto final_suspend() noexcept
120 {
121 struct awaiter
122 {
123 promise_type* p_;
124 93x bool await_ready() const noexcept { return false; }
125
126 93x auto await_suspend(
127 std::coroutine_handle<>) noexcept
128 {
129 // Nothing here touches p_ after the post or the
130 // unwind: either can destroy this frame.
131 93x auto& segment = p_->segment_;
132 // See run_async's trampoline: only a quitter run
133 // here is stopped through this owner.
134 93x BOOST_CAPY_ASSERT(
135 (p_->stoppable_ || !segment.stopped()) &&
136 "a quitter stopped a task's segment: "
137 "see quitter::handle");
138 109x if(segment.abandoned() &&
139 16x !(p_->stoppable_ && segment.stopped()))
140 {
141 9x p_->unwind();
142 }
143 else
144 {
145 // A quitter's stop: its frames are destroyed
146 // here, and the parent resumes to receive the
147 // stopped value.
148 84x if(segment.abandoned())
149 7x p_->destroy_inner_(p_->awaitable_);
150 84x p_->owner_ = nullptr;
151 84x auto ex = p_->caller_ex_;
152 84x ex.post(p_->parent_);
153 }
154 93x return detail::symmetric_transfer(
155 186x std::noop_coroutine());
156 }
157
158 − void await_resume() const noexcept {} // LCOV_EXCL_LINE final_suspend awaiter, never resumed
159 };
160 93x return awaiter{this};
161 }
162
163 93x void return_void() noexcept {}
164 void unhandled_exception() noexcept {}
165 };
166
167 std::coroutine_handle<promise_type> h_{nullptr};
168
169 96x boundary_trampoline() noexcept = default;
170
171 285x ~boundary_trampoline()
172 {
173 285x if(h_)
174 {
175 93x h_.promise().owner_ = nullptr;
176 93x h_.destroy();
177 }
178 285x }
179
180 boundary_trampoline(boundary_trampoline const&) = delete;
181 boundary_trampoline& operator=(boundary_trampoline const&) = delete;
182
183 94x boundary_trampoline(boundary_trampoline&& o) noexcept
184 94x : h_(std::exchange(o.h_, nullptr)) {}
185
186 96x boundary_trampoline& operator=(boundary_trampoline&& o) noexcept
187 {
188 96x if(this != &o)
189 {
190 96x if(h_)
191 {
192 1x h_.promise().owner_ = nullptr;
193 1x h_.destroy();
194 }
195 96x h_ = std::exchange(o.h_, nullptr);
196 }
197 96x return *this;
198 }
199
200 private:
201 95x explicit boundary_trampoline(std::coroutine_handle<promise_type> h) noexcept
202 95x : h_(h) {}
203 };
204
205 95x inline boundary_trampoline make_boundary_trampoline()
206 {
207 co_return;
208 190x }
209
210 /** Awaitable that binds a ContextRunnable to a specific executor.
211
212 Stores the executor and inner task by value. When co_awaited, the
213 co_await expression's lifetime extension keeps both alive for the
214 duration of the operation.
215
216 A dispatch trampoline handles the executor switch on completion:
217 the inner task's `final_suspend` resumes the trampoline, which
218 dispatches back through the caller's executor.
219
220 The `await_context` is owned by this awaitable and is guaranteed to
221 outlive the inner task and all awaitables in its chain. Awaitables
222 may store `await_context const*` without concern for dangling references.
223
224 @tparam Task The ContextRunnable type
225 @tparam Ex The executor type
226 @tparam InheritStopToken If true, inherit caller's stop token
227 @tparam Alloc The allocator type (void for no allocator)
228 */
229 template<ContextRunnable Task, Executor Ex, bool InheritStopToken, class Alloc = void>
230 struct [[nodiscard]] run_awaitable_ex
231 {
232 Ex ex_;
233 frame_memory_resource<Alloc> resource_;
234 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
235 await_context env_;
236 executor_ref caller_ex_;
237 boundary_trampoline tr_;
238 continuation task_cont_;
239 bool holds_work_ = false;
240 Task inner_; // Last: destroyed first, while env_ is still valid
241
242 189x ~run_awaitable_ex()
243 {
244 // Only a parent destroyed from above leaves the trampoline
245 // still linked: the inner task is still running.
246 189x if(tr_.h_ && tr_.h_.promise().owner_)
247 − std::terminate(); // LCOV_EXCL_LINE reached only in a death test's child process
248 // A parent unwound instead of resumed never reaches
249 // await_resume.
250 189x if(holds_work_)
251 13x caller_ex_.on_work_finished();
252 189x }
253
254 // Called by the trampoline to unwind the inner segment.
255 17x static void destroy_inner(void* p) noexcept
256 {
257 17x auto& self = *static_cast<run_awaitable_ex*>(p);
258 17x auto h = self.inner_.handle();
259 17x self.inner_.release();
260 17x h.destroy();
261 17x }
262
263 // void allocator, inherit stop token
264 82x run_awaitable_ex(Ex ex, Task inner)
265 requires (InheritStopToken && std::is_void_v<Alloc>)
266 82x : ex_(std::move(ex))
267 82x , inner_(std::move(inner))
268 {
269 82x }
270
271 // void allocator, explicit stop token
272 6x run_awaitable_ex(Ex ex, Task inner, std::stop_token st)
273 requires (!InheritStopToken && std::is_void_v<Alloc>)
274 6x : ex_(std::move(ex))
275 6x , st_(std::move(st))
276 6x , inner_(std::move(inner))
277 {
278 6x }
279
280 // with allocator, inherit stop token (use template to avoid void parameter)
281 template<class A>
282 requires (InheritStopToken && !std::is_void_v<Alloc> && std::same_as<A, Alloc>)
283 5x run_awaitable_ex(Ex ex, A alloc, Task inner)
284 5x : ex_(std::move(ex))
285 5x , resource_(std::move(alloc))
286 5x , inner_(std::move(inner))
287 {
288 5x }
289
290 // with allocator, explicit stop token (use template to avoid void parameter)
291 template<class A>
292 requires (!InheritStopToken && !std::is_void_v<Alloc> && std::same_as<A, Alloc>)
293 2x run_awaitable_ex(Ex ex, A alloc, Task inner, std::stop_token st)
294 2x : ex_(std::move(ex))
295 2x , resource_(std::move(alloc))
296 2x , st_(std::move(st))
297 2x , inner_(std::move(inner))
298 {
299 2x }
300
301 94x bool await_ready() const noexcept
302 {
303 94x return inner_.await_ready();
304 }
305
306 81x decltype(auto) await_resume()
307 {
308 81x if(std::exchange(holds_work_, false))
309 81x caller_ex_.on_work_finished();
310 if constexpr(stops_by_abandonment<Task>)
311 {
312 6x if(tr_.h_ && tr_.h_.promise().segment_.stopped())
313 6x return Task::promise_type::stopped_result();
314 }
315 75x return inner_.await_resume();
316 }
317
318 95x std::coroutine_handle<> await_suspend(std::coroutine_handle<> cont, await_context const* caller_env)
319 {
320 95x tr_ = make_boundary_trampoline();
321 95x auto& tp = tr_.h_.promise();
322 95x tp.owner_ = &tr_;
323 95x tp.caller_ex_ = caller_env->executor;
324 95x tp.parent_.h = cont;
325 95x tp.parent_.owner = caller_env->owner;
326 95x tp.destroy_inner_ = &run_awaitable_ex::destroy_inner;
327 95x tp.awaitable_ = this;
328 95x tp.segment_.bind(tr_.h_, ex_);
329 95x tp.stoppable_ = stops_by_abandonment<Task>;
330 95x caller_ex_ = caller_env->executor;
331 // Released once the parent resumes or is unwound. Not on the
332 // post back: the parent's chain may own the executor object and
333 // can be gone by the time post returns.
334 95x caller_ex_.on_work_started();
335 95x holds_work_ = true;
336
337 95x auto h = inner_.handle();
338 95x auto& p = h.promise();
339 95x p.set_continuation(tr_.h_);
340
341 95x env_.owner = &tp.segment_;
342 95x env_.executor = ex_;
343 if constexpr (InheritStopToken)
344 87x env_.stop_token = caller_env->stop_token;
345 else
346 8x env_.stop_token = st_;
347
348 if constexpr (!std::is_void_v<Alloc>)
349 7x env_.frame_allocator = resource_.get();
350 else
351 88x env_.frame_allocator = caller_env->frame_allocator;
352
353 95x p.set_environment(&env_);
354
355 95x task_cont_.h = h;
356 95x task_cont_.owner = &tp.segment_;
357 try
358 {
359 // A quitter starts through its gate, which checks the stop
360 // when the body would start: a stopped quitter's segment is
361 // abandoned for the stop, and the parent receives the
362 // stopped value.
363 if constexpr(stops_by_abandonment<Task>)
364 7x task_cont_.h = p.launch_handle();
365 95x ex_.post(task_cont_);
366 }
367 2x catch(...)
368 {
369 // The parent resumes with the exception: nothing may still
370 // treat the task as lent or hold work for the parent.
371 1x p.set_continuation(std::noop_coroutine());
372 1x task_cont_.h = nullptr;
373 1x tr_ = boundary_trampoline();
374 1x holds_work_ = false;
375 1x caller_ex_.on_work_finished();
376 1x throw;
377 }
378 94x return std::noop_coroutine();
379 }
380
381 // Non-copyable
382 run_awaitable_ex(run_awaitable_ex const&) = delete;
383 run_awaitable_ex& operator=(run_awaitable_ex const&) = delete;
384
385 // Movable (no noexcept - Task may throw)
386 94x run_awaitable_ex(run_awaitable_ex&&) = default;
387 run_awaitable_ex& operator=(run_awaitable_ex&&) = default;
388 };
389
390 /** Awaitable that runs a task with optional stop_token override.
391
392 Does NOT store an executor - the task inherits the caller's executor
393 directly. Executors always match, so no dispatch trampoline is needed.
394 The inner task's `final_suspend` resumes the parent directly via
395 unconditional symmetric transfer.
396
397 @tparam Task The ContextRunnable type
398 @tparam InheritStopToken If true, inherit caller's stop token
399 @tparam Alloc The allocator type (void for no allocator)
400 */
401 template<ContextRunnable Task, bool InheritStopToken, class Alloc = void>
402 struct [[nodiscard]] run_awaitable
403 {
404 frame_memory_resource<Alloc> resource_;
405 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
406 await_context env_;
407 // Set while the parent is suspended awaiting the inner task.
408 bool lent_ = false;
409 Task inner_; // Last: destroyed first, while env_ is still valid
410
411 42x ~run_awaitable()
412 {
413 // Only the unwind of an abandoned chain destroys an inner task
414 // still awaited; checked here so it terminates whatever the
415 // task type does when destroyed while lent.
416 42x auto h = inner_.handle();
417 52x if(lent_ && h && !h.done() &&
418 10x !(env_.owner && env_.owner->abandoned()))
419 − std::terminate(); // LCOV_EXCL_LINE reached only in a death test's child process
420 42x }
421
422 // void allocator, inherit stop token
423 explicit run_awaitable(Task inner)
424 requires (InheritStopToken && std::is_void_v<Alloc>)
425 : inner_(std::move(inner))
426 {
427 }
428
429 // void allocator, explicit stop token
430 5x run_awaitable(Task inner, std::stop_token st)
431 requires (!InheritStopToken && std::is_void_v<Alloc>)
432 5x : st_(std::move(st))
433 5x , inner_(std::move(inner))
434 {
435 5x }
436
437 // with allocator, inherit stop token (use template to avoid void parameter)
438 template<class A>
439 requires (InheritStopToken && !std::is_void_v<Alloc> && std::same_as<A, Alloc>)
440 14x run_awaitable(A alloc, Task inner)
441 14x : resource_(std::move(alloc))
442 14x , inner_(std::move(inner))
443 {
444 14x }
445
446 // with allocator, explicit stop token (use template to avoid void parameter)
447 template<class A>
448 requires (!InheritStopToken && !std::is_void_v<Alloc> && std::same_as<A, Alloc>)
449 2x run_awaitable(A alloc, Task inner, std::stop_token st)
450 2x : resource_(std::move(alloc))
451 2x , st_(std::move(st))
452 2x , inner_(std::move(inner))
453 {
454 2x }
455
456 21x bool await_ready() const noexcept
457 {
458 21x return inner_.await_ready();
459 }
460
461 11x decltype(auto) await_resume()
462 {
463 11x lent_ = false;
464 11x return inner_.await_resume();
465 }
466
467 21x std::coroutine_handle<> await_suspend(std::coroutine_handle<> cont, await_context const* caller_env)
468 {
469 21x env_.owner = caller_env->owner;
470 21x env_.executor = caller_env->executor;
471 if constexpr (InheritStopToken)
472 14x env_.stop_token = caller_env->stop_token;
473 else
474 7x env_.stop_token = st_;
475
476 if constexpr (!std::is_void_v<Alloc>)
477 16x env_.frame_allocator = resource_.get();
478 else
479 5x env_.frame_allocator = caller_env->frame_allocator;
480
481 // A quitter opens a segment of its own, so a stop on this run's
482 // token never abandons the caller's segment.
483 if constexpr(stops_by_abandonment<Task>)
484 {
485 // Lent only once the segment is open: opening it can throw
486 // into a quitter's body, and a lent inner task terminates
487 // in our destructor.
488 3x auto h = inner_.await_suspend(cont, &env_);
489 3x lent_ = true;
490 3x return h;
491 }
492 else
493 {
494 18x auto h = inner_.handle();
495 18x auto& p = h.promise();
496 18x p.set_continuation(cont);
497 18x p.set_environment(&env_);
498 18x lent_ = true;
499 18x return h;
500 }
501 }
502
503 // Non-copyable
504 run_awaitable(run_awaitable const&) = delete;
505 run_awaitable& operator=(run_awaitable const&) = delete;
506
507 // Movable (no noexcept - Task may throw)
508 21x run_awaitable(run_awaitable&&) = default;
509 run_awaitable& operator=(run_awaitable&&) = default;
510 };
511
512 /** Wrapper returned by run(ex, ...) that accepts a task for execution.
513
514 @tparam Ex The executor type.
515 @tparam InheritStopToken If true, inherit caller's stop token.
516 @tparam Alloc The allocator type (void for no allocator).
517 */
518 template<Executor Ex, bool InheritStopToken, class Alloc>
519 class [[nodiscard]] run_wrapper_ex
520 {
521 Ex ex_;
522 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
523 frame_memory_resource<Alloc> resource_;
524 Alloc alloc_; // Copy to pass to awaitable
525
526 std::pmr::memory_resource* saved_tls_ =
527 get_current_frame_allocator();
528 bool restored_ = false;
529
530 public:
531 3x run_wrapper_ex(Ex ex, Alloc alloc)
532 requires InheritStopToken
533 3x : ex_(std::move(ex))
534 3x , resource_(alloc)
535 3x , alloc_(std::move(alloc))
536 {
537 3x set_current_frame_allocator(&resource_);
538 3x }
539
540 1x run_wrapper_ex(Ex ex, std::stop_token st, Alloc alloc)
541 requires (!InheritStopToken)
542 1x : ex_(std::move(ex))
543 1x , st_(std::move(st))
544 1x , resource_(alloc)
545 1x , alloc_(std::move(alloc))
546 {
547 1x set_current_frame_allocator(&resource_);
548 1x }
549
550 // Restores the caller's allocator when evaluating the task argument
551 // threw. Not afterwards: a wrapper destroyed with a torn-down parent
552 // frame must not touch the tearing thread's allocator.
553 4x ~run_wrapper_ex()
554 {
555 4x if(!restored_)
556 1x set_current_frame_allocator(saved_tls_);
557 4x }
558
559 // Non-copyable, non-movable (must be used immediately)
560 run_wrapper_ex(run_wrapper_ex const&) = delete;
561 run_wrapper_ex(run_wrapper_ex&&) = delete;
562 run_wrapper_ex& operator=(run_wrapper_ex const&) = delete;
563 run_wrapper_ex& operator=(run_wrapper_ex&&) = delete;
564
565 template<ContextRunnable Task>
566 3x [[nodiscard]] auto operator()(Task t) &&
567 {
568 // The task's frame is made; the caller's own frames are not.
569 3x set_current_frame_allocator(saved_tls_);
570 3x restored_ = true;
571 if constexpr (InheritStopToken)
572 return run_awaitable_ex<Task, Ex, true, Alloc>{
573 2x std::move(ex_), std::move(alloc_), std::move(t)};
574 else
575 return run_awaitable_ex<Task, Ex, false, Alloc>{
576 1x std::move(ex_), std::move(alloc_), std::move(t), std::move(st_)};
577 }
578 };
579
580 /// Specialization for memory_resource* - stores pointer directly.
581 template<Executor Ex, bool InheritStopToken>
582 class [[nodiscard]] run_wrapper_ex<Ex, InheritStopToken, std::pmr::memory_resource*>
583 {
584 Ex ex_;
585 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
586 std::pmr::memory_resource* mr_;
587
588 std::pmr::memory_resource* saved_tls_ =
589 get_current_frame_allocator();
590 bool restored_ = false;
591
592 public:
593 4x run_wrapper_ex(Ex ex, std::pmr::memory_resource* mr)
594 requires InheritStopToken
595 4x : ex_(std::move(ex))
596 4x , mr_(mr)
597 {
598 4x set_current_frame_allocator(mr_);
599 4x }
600
601 1x run_wrapper_ex(Ex ex, std::stop_token st, std::pmr::memory_resource* mr)
602 requires (!InheritStopToken)
603 1x : ex_(std::move(ex))
604 1x , st_(std::move(st))
605 1x , mr_(mr)
606 {
607 1x set_current_frame_allocator(mr_);
608 1x }
609
610 // Restores the caller's allocator when evaluating the task argument
611 // threw. Not afterwards: a wrapper destroyed with a torn-down parent
612 // frame must not touch the tearing thread's allocator.
613 5x ~run_wrapper_ex()
614 {
615 5x if(!restored_)
616 1x set_current_frame_allocator(saved_tls_);
617 5x }
618
619 // Non-copyable, non-movable (must be used immediately)
620 run_wrapper_ex(run_wrapper_ex const&) = delete;
621 run_wrapper_ex(run_wrapper_ex&&) = delete;
622 run_wrapper_ex& operator=(run_wrapper_ex const&) = delete;
623 run_wrapper_ex& operator=(run_wrapper_ex&&) = delete;
624
625 template<ContextRunnable Task>
626 4x [[nodiscard]] auto operator()(Task t) &&
627 {
628 // The task's frame is made; the caller's own frames are not.
629 4x set_current_frame_allocator(saved_tls_);
630 4x restored_ = true;
631 if constexpr (InheritStopToken)
632 return run_awaitable_ex<Task, Ex, true, std::pmr::memory_resource*>{
633 3x std::move(ex_), mr_, std::move(t)};
634 else
635 return run_awaitable_ex<Task, Ex, false, std::pmr::memory_resource*>{
636 1x std::move(ex_), mr_, std::move(t), std::move(st_)};
637 }
638 };
639
640 /// Specialization for no allocator (void).
641 template<Executor Ex, bool InheritStopToken>
642 class [[nodiscard]] run_wrapper_ex<Ex, InheritStopToken, void>
643 {
644 Ex ex_;
645 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
646
647 public:
648 82x explicit run_wrapper_ex(Ex ex)
649 requires InheritStopToken
650 82x : ex_(std::move(ex))
651 {
652 82x }
653
654 6x run_wrapper_ex(Ex ex, std::stop_token st)
655 requires (!InheritStopToken)
656 6x : ex_(std::move(ex))
657 6x , st_(std::move(st))
658 {
659 6x }
660
661 // Non-copyable, non-movable (must be used immediately)
662 run_wrapper_ex(run_wrapper_ex const&) = delete;
663 run_wrapper_ex(run_wrapper_ex&&) = delete;
664 run_wrapper_ex& operator=(run_wrapper_ex const&) = delete;
665 run_wrapper_ex& operator=(run_wrapper_ex&&) = delete;
666
667 template<ContextRunnable Task>
668 88x [[nodiscard]] auto operator()(Task t) &&
669 {
670 if constexpr (InheritStopToken)
671 return run_awaitable_ex<Task, Ex, true>{
672 82x std::move(ex_), std::move(t)};
673 else
674 return run_awaitable_ex<Task, Ex, false>{
675 6x std::move(ex_), std::move(t), std::move(st_)};
676 }
677 };
678
679 /** Wrapper returned by run(st) or run(alloc) that accepts a task.
680
681 @tparam InheritStopToken If true, inherit caller's stop token.
682 @tparam Alloc The allocator type (void for no allocator).
683 */
684 template<bool InheritStopToken, class Alloc>
685 class [[nodiscard]] run_wrapper
686 {
687 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
688 frame_memory_resource<Alloc> resource_;
689 Alloc alloc_; // Copy to pass to awaitable
690
691 std::pmr::memory_resource* saved_tls_ =
692 get_current_frame_allocator();
693 bool restored_ = false;
694
695 public:
696 3x explicit run_wrapper(Alloc alloc)
697 requires InheritStopToken
698 3x : resource_(alloc)
699 3x , alloc_(std::move(alloc))
700 {
701 3x set_current_frame_allocator(&resource_);
702 3x }
703
704 1x run_wrapper(std::stop_token st, Alloc alloc)
705 requires (!InheritStopToken)
706 1x : st_(std::move(st))
707 1x , resource_(alloc)
708 1x , alloc_(std::move(alloc))
709 {
710 1x set_current_frame_allocator(&resource_);
711 1x }
712
713 // Restores the caller's allocator when evaluating the task argument
714 // threw. Not afterwards: a wrapper destroyed with a torn-down parent
715 // frame must not touch the tearing thread's allocator.
716 4x ~run_wrapper()
717 {
718 4x if(!restored_)
719 1x set_current_frame_allocator(saved_tls_);
720 4x }
721
722 // Non-copyable, non-movable (must be used immediately)
723 run_wrapper(run_wrapper const&) = delete;
724 run_wrapper(run_wrapper&&) = delete;
725 run_wrapper& operator=(run_wrapper const&) = delete;
726 run_wrapper& operator=(run_wrapper&&) = delete;
727
728 template<ContextRunnable Task>
729 3x [[nodiscard]] auto operator()(Task t) &&
730 {
731 // The task's frame is made; the caller's own frames are not.
732 3x set_current_frame_allocator(saved_tls_);
733 3x restored_ = true;
734 if constexpr (InheritStopToken)
735 return run_awaitable<Task, true, Alloc>{
736 2x std::move(alloc_), std::move(t)};
737 else
738 return run_awaitable<Task, false, Alloc>{
739 1x std::move(alloc_), std::move(t), std::move(st_)};
740 }
741 };
742
743 /// Specialization for memory_resource* - stores pointer directly.
744 template<bool InheritStopToken>
745 class [[nodiscard]] run_wrapper<InheritStopToken, std::pmr::memory_resource*>
746 {
747 std::conditional_t<InheritStopToken, std::monostate, std::stop_token> st_;
748 std::pmr::memory_resource* mr_;
749
750 std::pmr::memory_resource* saved_tls_ =
751 get_current_frame_allocator();
752 bool restored_ = false;
753
754 public:
755 13x explicit run_wrapper(std::pmr::memory_resource* mr)
756 requires InheritStopToken
757 13x : mr_(mr)
758 {
759 13x set_current_frame_allocator(mr_);
760 13x }
761
762 1x run_wrapper(std::stop_token st, std::pmr::memory_resource* mr)
763 requires (!InheritStopToken)
764 1x : st_(std::move(st))
765 1x , mr_(mr)
766 {
767 1x set_current_frame_allocator(mr_);
768 1x }
769
770 // Restores the caller's allocator when evaluating the task argument
771 // threw. Not afterwards: a wrapper destroyed with a torn-down parent
772 // frame must not touch the tearing thread's allocator.
773 14x ~run_wrapper()
774 {
775 14x if(!restored_)
776 1x set_current_frame_allocator(saved_tls_);
777 14x }
778
779 // Non-copyable, non-movable (must be used immediately)
780 run_wrapper(run_wrapper const&) = delete;
781 run_wrapper(run_wrapper&&) = delete;
782 run_wrapper& operator=(run_wrapper const&) = delete;
783 run_wrapper& operator=(run_wrapper&&) = delete;
784
785 template<ContextRunnable Task>
786 13x [[nodiscard]] auto operator()(Task t) &&
787 {
788 // The task's frame is made; the caller's own frames are not.
789 13x set_current_frame_allocator(saved_tls_);
790 13x restored_ = true;
791 if constexpr (InheritStopToken)
792 return run_awaitable<Task, true, std::pmr::memory_resource*>{
793 12x mr_, std::move(t)};
794 else
795 return run_awaitable<Task, false, std::pmr::memory_resource*>{
796 1x mr_, std::move(t), std::move(st_)};
797 }
798 };
799
800 /// Specialization for stop_token only (no allocator).
801 template<>
802 class [[nodiscard]] run_wrapper<false, void>
803 {
804 std::stop_token st_;
805
806 public:
807 5x explicit run_wrapper(std::stop_token st)
808 5x : st_(std::move(st))
809 {
810 5x }
811
812 // Non-copyable, non-movable (must be used immediately)
813 run_wrapper(run_wrapper const&) = delete;
814 run_wrapper(run_wrapper&&) = delete;
815 run_wrapper& operator=(run_wrapper const&) = delete;
816 run_wrapper& operator=(run_wrapper&&) = delete;
817
818 template<ContextRunnable Task>
819 5x [[nodiscard]] auto operator()(Task t) &&
820 {
821 5x return run_awaitable<Task, false, void>{std::move(t), std::move(st_)};
822 }
823 };
824
825 } // namespace boost::capy::detail
826
827 namespace boost::capy {
828
829 /** Bind a task to execute on a specific executor.
830
831 Returns a wrapper that accepts a task and produces an awaitable.
832 When co_awaited, the task runs on the specified executor.
833
834 If the inner task is abandoned before it completes, for example
835 because its execution context is torn down, the caller's chain is
836 abandoned too: it is unwound by its owner, on the owner's executor,
837 without the caller resuming. The awaitable holds work on the
838 caller's executor until the caller resumes or is unwound.
839
840 A @ref quitter's stop is not such an abandon. When the inner task
841 is a quitter and a stop ends it, the caller resumes on its own
842 executor, and the `co_await` yields the quitter's stopped value, as
843 described in @ref quitter's Await-returns.
844
845 @par Preconditions
846 The caller's execution context outlives the inner task and the
847 unwind of the caller's chain. This is not detected.
848
849 @par Example
850 @par !example example_2
851
852
853 @param ex The executor on which the task should run.
854
855 @return A wrapper that accepts a task for execution.
856
857 @see @ref task
858 @see @ref Executor
859 */
860 template<Executor Ex>
861 [[nodiscard]] auto
862 82x run(Ex ex)
863 {
864 82x return detail::run_wrapper_ex<Ex, true, void>{std::move(ex)};
865 }
866
867 /** Bind a task to an executor with a stop token.
868
869 @ref run(Ex) describes teardown and preconditions.
870
871 @param ex The executor on which the task should run.
872 @param st The stop token for cooperative cancellation.
873
874 @return A wrapper that accepts a task for execution.
875
876 @see @ref run(Ex)
877 */
878 template<Executor Ex>
879 [[nodiscard]] auto
880 6x run(Ex ex, std::stop_token st)
881 {
882 return detail::run_wrapper_ex<Ex, false, void>{
883 6x std::move(ex), std::move(st)};
884 }
885
886 /** Bind a task to an executor with a memory resource.
887
888 @ref run(Ex) describes teardown and preconditions.
889
890 @param ex The executor on which the task should run.
891 @param mr The memory resource for frame allocation.
892
893 @return A wrapper that accepts a task for execution.
894
895 @see @ref run(Ex)
896 */
897 template<Executor Ex>
898 [[nodiscard]] auto
899 4x run(Ex ex, std::pmr::memory_resource* mr)
900 {
901 return detail::run_wrapper_ex<Ex, true, std::pmr::memory_resource*>{
902 4x std::move(ex), mr};
903 }
904
905 /** Bind a task to an executor with a standard allocator.
906
907 Await the awaitable in the expression that creates it, as in
908 `co_await run(ex, alloc)(task())`: the task's frame is allocated from
909 memory the wrapper holds until the end of that expression.
910
911 @ref run(Ex) describes teardown and preconditions.
912
913 @param ex The executor on which the task should run.
914 @param alloc The allocator for frame allocation.
915
916 @return A wrapper that accepts a task for execution.
917
918 @see @ref run(Ex)
919 */
920 template<Executor Ex, detail::Allocator Alloc>
921 [[nodiscard]] auto
922 3x run(Ex ex, Alloc alloc)
923 {
924 return detail::run_wrapper_ex<Ex, true, Alloc>{
925 3x std::move(ex), std::move(alloc)};
926 }
927
928 /** Bind a task to an executor with stop token and memory resource.
929
930 @ref run(Ex) describes teardown and preconditions.
931
932 @param ex The executor on which the task should run.
933 @param st The stop token for cooperative cancellation.
934 @param mr The memory resource for frame allocation.
935
936 @return A wrapper that accepts a task for execution.
937
938 @see @ref run(Ex)
939 */
940 template<Executor Ex>
941 [[nodiscard]] auto
942 1x run(Ex ex, std::stop_token st, std::pmr::memory_resource* mr)
943 {
944 return detail::run_wrapper_ex<Ex, false, std::pmr::memory_resource*>{
945 1x std::move(ex), std::move(st), mr};
946 }
947
948 /** Bind a task to an executor with stop token and standard allocator.
949
950 Await the awaitable in the expression that creates it, as in
951 `co_await run(ex, alloc)(task())`: the task's frame is allocated from
952 memory the wrapper holds until the end of that expression.
953
954 @ref run(Ex) describes teardown and preconditions.
955
956 @param ex The executor on which the task should run.
957 @param st The stop token for cooperative cancellation.
958 @param alloc The allocator for frame allocation.
959
960 @return A wrapper that accepts a task for execution.
961
962 @see @ref run(Ex)
963 */
964 template<Executor Ex, detail::Allocator Alloc>
965 [[nodiscard]] auto
966 1x run(Ex ex, std::stop_token st, Alloc alloc)
967 {
968 return detail::run_wrapper_ex<Ex, false, Alloc>{
969 1x std::move(ex), std::move(st), std::move(alloc)};
970 }
971
972 /** Run a task with a custom stop token.
973
974 The task inherits the caller's executor. Only the stop token
975 is overridden.
976
977 @par Example
978 @par !example example_1
979
980
981 @param st The stop token for cooperative cancellation.
982
983 @return A wrapper that accepts a task for execution.
984 */
985 [[nodiscard]] inline auto
986 5x run(std::stop_token st)
987 {
988 5x return detail::run_wrapper<false, void>{std::move(st)};
989 }
990
991 /** Run a task with a custom memory resource.
992
993 The task inherits the caller's executor. The memory resource
994 is used for nested frame allocations.
995
996 @param mr The memory resource for frame allocation.
997
998 @return A wrapper that accepts a task for execution.
999 */
1000 [[nodiscard]] inline auto
1001 13x run(std::pmr::memory_resource* mr)
1002 {
1003 13x return detail::run_wrapper<true, std::pmr::memory_resource*>{mr};
1004 }
1005
1006 // MrDocs 0.8.0 reports `run: Documented parameter 'alloc' does not exist` and
1007 // pins it to the run(Ex) overload near the top of this namespace:
1008 // `detail::Allocator` is implementation-defined, so the constraint is erased
1009 // and the two single-parameter `run` overloads collapse onto one page. The
1010 // finding is grandfathered in doc/lint/baseline.json. Deleting the `@param
1011 // alloc` below clears it and produces no replacement finding, because MrDocs
1012 // has no model of this overload at all -- so it would silently drop real
1013 // documentation. Keep the `@param`.
1014 /** Run a task with a custom standard allocator.
1015
1016 Await the awaitable in the expression that creates it, as in
1017 `co_await run(alloc)(task())`: the task's frame is allocated from
1018 memory the wrapper holds until the end of that expression.
1019
1020 The task inherits the caller's executor. The allocator is used
1021 for nested frame allocations.
1022
1023 @param alloc The allocator for frame allocation.
1024
1025 @return A wrapper that accepts a task for execution.
1026 */
1027 template<detail::Allocator Alloc>
1028 [[nodiscard]] auto
1029 3x run(Alloc alloc)
1030 {
1031 3x return detail::run_wrapper<true, Alloc>{std::move(alloc)};
1032 }
1033
1034 /** Run a task with stop token and memory resource.
1035
1036 The task inherits the caller's executor.
1037
1038 @param st The stop token for cooperative cancellation.
1039 @param mr The memory resource for frame allocation.
1040
1041 @return A wrapper that accepts a task for execution.
1042 */
1043 [[nodiscard]] inline auto
1044 1x run(std::stop_token st, std::pmr::memory_resource* mr)
1045 {
1046 return detail::run_wrapper<false, std::pmr::memory_resource*>{
1047 1x std::move(st), mr};
1048 }
1049
1050 /** Run a task with stop token and standard allocator.
1051
1052 Await the awaitable in the expression that creates it, as in
1053 `co_await run(alloc)(task())`: the task's frame is allocated from
1054 memory the wrapper holds until the end of that expression.
1055
1056 The task inherits the caller's executor.
1057
1058 @param st The stop token for cooperative cancellation.
1059 @param alloc The allocator for frame allocation.
1060
1061 @return A wrapper that accepts a task for execution.
1062 */
1063 template<detail::Allocator Alloc>
1064 [[nodiscard]] auto
1065 1x run(std::stop_token st, Alloc alloc)
1066 {
1067 return detail::run_wrapper<false, Alloc>{
1068 1x std::move(st), std::move(alloc)};
1069 }
1070
1071 } // namespace boost::capy
1072
1073 #endif
1074