include/boost/capy/when_any.hpp

99.4% Lines (163/165) 93.9% List of functions (154/165)
when_any.hpp
f(x) Functions (165)
Function Calls Lines Blocks
boost::capy::detail::when_any_core::stop_callback_fn::operator()() const :139 3x 100.0% 100.0% boost::capy::detail::when_any_core::when_any_core(unsigned long) :150 34x 100.0% 100.0% boost::capy::detail::when_any_core::try_win(unsigned long) :156 53x 100.0% 100.0% boost::capy::detail::when_any_core::set_winner_exception(std::__exception_ptr::exception_ptr) :170 1x 100.0% 100.0% boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload>::when_any_io_state() :199 1x 100.0% 100.0% boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::when_any_io_state() :199 1x 100.0% 100.0% boost::capy::detail::when_any_io_state<unsigned long, unsigned long>::when_any_io_state() :199 14x 100.0% 100.0% boost::capy::detail::when_any_io_state<unsigned long>::when_any_io_state() :199 2x 100.0% 100.0% boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload>::record_error(std::error_code) :204 0 0.0% 0.0% boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::record_error(std::error_code) :204 0 0.0% 0.0% boost::capy::detail::when_any_io_state<unsigned long, unsigned long>::record_error(std::error_code) :204 13x 100.0% 100.0% boost::capy::detail::when_any_io_state<unsigned long>::record_error(std::error_code) :204 1x 100.0% 100.0% boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload>::record_exception(std::__exception_ptr::exception_ptr) :211 0 0.0% 0.0% boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::record_exception(std::__exception_ptr::exception_ptr) :211 0 0.0% 0.0% boost::capy::detail::when_any_io_state<unsigned long, unsigned long>::record_exception(std::__exception_ptr::exception_ptr) :211 7x 100.0% 100.0% boost::capy::detail::when_any_io_state<unsigned long>::record_exception(std::__exception_ptr::exception_ptr) :211 0 0.0% 0.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::get_return_object() :231 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::get_return_object() :231 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::get_return_object() :231 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::get_return_object() :231 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::get_return_object() :231 28x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::get_return_object() :231 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::initial_suspend() :237 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::initial_suspend() :237 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::initial_suspend() :237 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::initial_suspend() :237 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::initial_suspend() :237 28x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::initial_suspend() :237 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::final_suspend() :239 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::final_suspend() :239 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::final_suspend() :239 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::final_suspend() :239 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::final_suspend() :239 28x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::final_suspend() :239 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::final_suspend()::awaiter::await_ready() const :244 4x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::final_suspend()::awaiter::await_suspend(std::__n4861::coroutine_handle<void>) :245 4x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::final_suspend()::awaiter::await_resume() const :259 boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::return_void() :264 5x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::return_void() :264 43x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::return_void() :264 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::return_void() :264 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::return_void() :264 21x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::return_void() :264 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::unhandled_exception() :267 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::unhandled_exception() :267 4x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::unhandled_exception() :267 0 0.0% 0.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::unhandled_exception() :267 0 0.0% 0.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::unhandled_exception() :267 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::unhandled_exception() :267 0 0.0% 0.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<> > >::await_ready() :278 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() :278 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_ready() :278 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_ready() :278 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() :278 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::immediate_io_awaitable>::await_ready() :278 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_ready() :278 4x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() :278 23x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() :278 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<> > >::await_resume() :279 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() :279 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_resume() :279 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_resume() :279 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() :279 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::immediate_io_awaitable>::await_resume() :279 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_resume() :279 4x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() :279 23x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() :279 2x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type>) :282 7x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type>) :282 47x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type>) :282 0 0.0% 0.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type>) :282 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type>) :282 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::(anonymous namespace)::immediate_io_awaitable>::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>) :282 0 0.0% 0.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>) :282 4x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>) :282 23x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::transform_awaiter<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type>(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type>) :282 2x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<> > >(boost::capy::task<boost::capy::io_result<> >&&) :293 7x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >&&) :293 47x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type::await_transform<boost::capy::(anonymous namespace)::throwing_payload_awaitable>(boost::capy::(anonymous namespace)::throwing_payload_awaitable&&) :293 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&) :293 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >&&) :293 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::await_transform<boost::capy::(anonymous namespace)::immediate_io_awaitable>(boost::capy::(anonymous namespace)::immediate_io_awaitable&&) :293 1x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::await_transform<boost::capy::quitter<boost::capy::io_result<unsigned long> > >(boost::capy::quitter<boost::capy::io_result<unsigned long> >&&) :293 4x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >&&) :293 23x 100.0% 100.0% auto boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type::await_transform<boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >&&) :293 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::promise_type>) :310 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::promise_type>) :310 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::promise_type>) :310 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::promise_type>) :310 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::promise_type>) :310 28x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::when_any_io_runner(std::__n4861::coroutine_handle<boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::promise_type>) :310 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >::release() :324 7x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >::release() :324 47x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >::release() :324 1x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::release() :324 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >::release() :324 28x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> >::release() :324 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::(anonymous namespace)::throwing_payload_awaitable, boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload> >(boost::capy::(anonymous namespace)::throwing_payload_awaitable, boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload>*) :333 1x 100.0% 50.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) :333 1x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > boost::capy::detail::make_when_any_io_runner<1ul, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >(boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) :333 1x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >(boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :333 1x 100.0% 50.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >(boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :333 2x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :333 11x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> > boost::capy::detail::make_when_any_io_runner<1ul, boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >(boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :333 2x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long, unsigned long> > boost::capy::detail::make_when_any_io_runner<1ul, boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long> >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :333 12x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_state<unsigned long> > boost::capy::detail::make_when_any_io_runner<0ul, boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long> >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_state<unsigned long>*) :333 2x 100.0% 47.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::when_any_io_launcher(std::tuple<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >*, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :372 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::when_any_io_launcher(std::tuple<boost::capy::(anonymous namespace)::throwing_payload_awaitable>*, boost::capy::detail::when_any_io_state<boost::capy::(anonymous namespace)::throwing_move_payload>*) :372 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::when_any_io_launcher(std::tuple<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >*, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :372 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> > >::when_any_io_launcher(std::tuple<boost::capy::task<boost::capy::io_result<unsigned long> > >*, boost::capy::detail::when_any_io_state<unsigned long>*) :372 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::when_any_io_launcher(std::tuple<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >*, boost::capy::detail::when_any_io_state<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) :372 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::when_any_io_launcher(std::tuple<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >*, boost::capy::detail::when_any_io_state<unsigned long, unsigned long>*) :372 11x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() const :380 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_ready() const :380 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_ready() const :380 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() const :380 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_ready() const :380 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_ready() const :380 11x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 1x 57.1% 59.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 1x 57.1% 59.0% boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 2x 90.0% 76.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 2x 57.1% 59.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 1x 57.1% 59.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :385 11x 92.9% 82.0% auto boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*)::{lambda<unsigned long... $N0>(std::integer_sequence<unsigned long, ($N0)...>)#1}::operator()<0ul, 1ul>(std::integer_sequence<unsigned long, 0ul, 1ul>) const :402 2x 80.0% 62.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() const :409 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::await_resume() const :409 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::await_resume() const :409 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() const :409 2x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::await_resume() const :409 1x 100.0% 100.0% boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::await_resume() const :409 11x 100.0% 100.0% void boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 1x 100.0% 100.0% void boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >::launch_one<1ul>(boost::capy::executor_ref, std::stop_token) :413 1x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 1x 100.0% 100.0% void boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 2x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >::launch_one<1ul>(boost::capy::executor_ref, std::stop_token) :413 2x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> > >::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 2x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 1x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::launch_one<1ul>(boost::capy::executor_ref, std::stop_token) :413 1x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::launch_one<0ul>(boost::capy::executor_ref, std::stop_token) :413 11x 100.0% 86.0% void boost::capy::detail::when_any_io_launcher<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >::launch_one<1ul>(boost::capy::executor_ref, std::stop_token) :413 11x 100.0% 86.0% boost::capy::detail::when_any_io_homogeneous_state<unsigned long>::when_any_io_homogeneous_state(unsigned long) :444 13x 100.0% 89.0% boost::capy::detail::when_any_io_homogeneous_state<unsigned long>::record_error(std::error_code) :450 6x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_state<unsigned long>::record_exception(std::__exception_ptr::exception_ptr) :457 4x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> >::when_any_io_homogeneous_state(unsigned long) :476 3x 100.0% 88.0% boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> >::record_error(std::error_code) :482 1x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> >::record_exception(std::__exception_ptr::exception_ptr) :489 2x 100.0% 100.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > > boost::capy::detail::make_when_any_io_homogeneous_runner<boost::capy::task<boost::capy::io_result<> >, boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> > >(boost::capy::task<boost::capy::io_result<> >, boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> >*, unsigned long) :503 7x 100.0% 47.0% boost::capy::detail::when_any_io_runner<boost::capy::detail::when_any_io_homogeneous_state<unsigned long> > boost::capy::detail::make_when_any_io_homogeneous_runner<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_homogeneous_state<unsigned long> >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::detail::when_any_io_homogeneous_state<unsigned long>*, unsigned long) :503 47x 100.0% 47.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > > >::when_any_io_homogeneous_launcher(std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > >*, boost::capy::detail::when_any_io_homogeneous_state<std::tuple<> >*) :546 3x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > > >::when_any_io_homogeneous_launcher(std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > >*, boost::capy::detail::when_any_io_homogeneous_state<unsigned long>*) :546 13x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > > >::await_ready() const :554 3x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > > >::await_ready() const :554 13x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :559 3x 81.5% 72.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > > >::await_suspend(std::__n4861::coroutine_handle<void>, boost::capy::io_env const*) :559 13x 100.0% 79.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > > >::await_resume() const :603 3x 100.0% 100.0% boost::capy::detail::when_any_io_homogeneous_launcher<std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > > >::await_resume() const :603 13x 100.0% 100.0% boost::capy::task<std::variant<std::error_code, std::pair<unsigned long, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<std::__detail::__iter_traits::value_type>::type&>)()).await_resume)())>::type> > > boost::capy::when_any<std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > > >(std::vector<boost::capy::task<boost::capy::io_result<unsigned long> >, std::allocator<boost::capy::task<boost::capy::io_result<unsigned long> > > >&&) :651 14x 100.0% 44.0% boost::capy::task<std::variant<std::error_code, unsigned long> > boost::capy::when_any<std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > > >(std::vector<boost::capy::task<boost::capy::io_result<> >, std::allocator<boost::capy::task<boost::capy::io_result<> > > >&&) :730 3x 100.0% 44.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::(anonymous namespace)::immediate_io_awaitable>::type&>)()).await_resume)())>::type, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::(anonymous namespace)::immediate_io_awaitable, boost::capy::task<boost::capy::io_result<unsigned long> >) :775 1x 100.0% 42.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::(anonymous namespace)::throwing_payload_awaitable>::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::(anonymous namespace)::throwing_payload_awaitable>(boost::capy::(anonymous namespace)::throwing_payload_awaitable) :775 1x 100.0% 44.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::quitter<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::quitter<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> > >(boost::capy::quitter<boost::capy::io_result<unsigned long> >, boost::capy::quitter<boost::capy::io_result<unsigned long> >) :775 2x 100.0% 41.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) :775 1x 100.0% 41.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >, boost::capy::task<boost::capy::io_result<unsigned long> >) :775 11x 100.0% 41.0% boost::capy::task<std::variant<std::error_code, boost::capy::detail::io_result_payload<decltype ((((declval<std::decay<boost::capy::task<boost::capy::io_result<unsigned long> > >::type&>)()).await_resume)())>::type> > boost::capy::when_any<boost::capy::task<boost::capy::io_result<unsigned long> > >(boost::capy::task<boost::capy::io_result<unsigned long> >) :775 2x 100.0% 42.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 // Copyright (c) 2026 Steve Gerbino
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_WHEN_ANY_HPP
12 #define BOOST_CAPY_WHEN_ANY_HPP
13
14 #include <boost/capy/detail/config.hpp>
15 #include <boost/capy/detail/io_result_combinators.hpp>
16 #include <boost/capy/continuation.hpp>
17 #include <boost/capy/concept/executor.hpp>
18 #include <boost/capy/concept/io_awaitable.hpp>
19 #include <coroutine>
20 #include <boost/capy/ex/executor_ref.hpp>
21 #include <boost/capy/ex/frame_alloc_mixin.hpp>
22 #include <boost/capy/ex/frame_allocator.hpp>
23 #include <boost/capy/ex/io_env.hpp>
24 #include <boost/capy/task.hpp>
25
26 #include <array>
27 #include <atomic>
28 #include <exception>
29 #include <memory>
30 #include <mutex>
31 #include <optional>
32 #include <ranges>
33 #include <stdexcept>
34 #include <stop_token>
35 #include <tuple>
36 #include <type_traits>
37 #include <utility>
38 #include <variant>
39 #include <vector>
40
41 /*
42 when_any - Race multiple io_result tasks, select first success
43 =============================================================
44
45 OVERVIEW:
46 ---------
47 when_any launches N io_result-returning tasks concurrently. A task
48 wins by returning !ec; errors and exceptions do not win. Once a
49 winner is found, stop is requested for siblings and the winner's
50 payload is returned. If no winner exists (all fail), the first
51 error_code is returned or the last exception is rethrown.
52
53 ARCHITECTURE:
54 -------------
55 The design mirrors when_all but with inverted completion semantics:
56
57 when_all: complete when remaining_count reaches 0 (all done)
58 when_any: complete when has_winner becomes true (first done)
59 BUT still wait for remaining_count to reach 0 for cleanup
60
61 Key components:
62 - when_any_core: Shared state tracking winner and completion
63 - when_any_io_runner: Wrapper coroutine for each child task
64 - when_any_io_launcher/when_any_io_homogeneous_launcher:
65 Awaitables that start all runners concurrently
66
67 CRITICAL INVARIANTS:
68 --------------------
69 1. Only a task returning !ec can become the winner (via atomic CAS)
70 2. All tasks must complete before parent resumes (cleanup safety)
71 3. Stop is requested immediately when winner is determined
72 4. Exceptions and errors do not claim winner status
73
74 POSITIONAL VARIANT:
75 -------------------
76 The variadic overload returns std::variant<error_code, R1, R2, ..., Rn>.
77 Index 0 is error_code (failure/no-winner). Index 1..N identifies the
78 winning child and carries its payload.
79
80 RANGE OVERLOAD:
81 ---------------
82 The range overload returns variant<error_code, pair<size_t, T>> for
83 non-void children or variant<error_code, size_t> for void children.
84
85 MEMORY MODEL:
86 -------------
87 Synchronization chain from winner's write to parent's read:
88
89 1. Winner thread writes result_ (non-atomic)
90 2. Winner thread calls signal_completion() -> fetch_sub(acq_rel) on remaining_count_
91 3. Last task thread (may be winner or non-winner) calls signal_completion()
92 -> fetch_sub(acq_rel) on remaining_count_, observing count becomes 0
93 4. Last task returns caller_ex_.dispatch(continuation_) via symmetric transfer
94 5. Parent coroutine resumes and reads result_
95
96 Synchronization analysis:
97 - All fetch_sub operations on remaining_count_ form a release sequence
98 - Winner's fetch_sub releases; subsequent fetch_sub operations participate
99 in the modification order of remaining_count_
100 - Last task's fetch_sub(acq_rel) synchronizes-with prior releases in the
101 modification order, establishing happens-before from winner's writes
102 - Executor dispatch() is expected to provide queue-based synchronization
103 (release-on-post, acquire-on-execute) completing the chain to parent
104 - Even inline executors work (same thread = sequenced-before)
105
106 EXCEPTION SEMANTICS:
107 --------------------
108 Exceptions do NOT claim winner status. If a child throws, the exception
109 is recorded but the combinator keeps waiting for a success. Only when
110 all children complete without a winner does the combinator check: if
111 any exception was recorded, it is rethrown (exception beats error_code).
112 */
113
114 namespace boost {
115 namespace capy {
116
117 namespace detail {
118
119 /** Core shared state for when_any operations.
120
121 Contains all members and methods common to both heterogeneous (variadic)
122 and homogeneous (range) when_any implementations. State classes embed
123 this via composition to avoid CRTP destructor ordering issues.
124
125 @par Thread Safety
126 Atomic operations protect winner selection and completion count.
127 */
128 struct when_any_core
129 {
130 std::atomic<std::size_t> remaining_count_;
131 std::size_t winner_index_{0};
132 std::exception_ptr winner_exception_;
133 std::stop_source stop_source_;
134
135 // Bridges parent's stop token to our stop_source
136 struct stop_callback_fn
137 {
138 std::stop_source* source_;
139 3x void operator()() const noexcept { source_->request_stop(); }
140 };
141 using stop_callback_t = std::stop_callback<stop_callback_fn>;
142 std::optional<stop_callback_t> parent_stop_callback_;
143
144 continuation continuation_;
145 io_env const* caller_env_ = nullptr;
146
147 // Placed last to avoid padding (1-byte atomic followed by 8-byte aligned members)
148 std::atomic<bool> has_winner_{false};
149
150 34x explicit when_any_core(std::size_t count) noexcept
151 34x : remaining_count_(count)
152 {
153 34x }
154
155 /** Atomically claim winner status; exactly one task succeeds. */
156 53x bool try_win(std::size_t index) noexcept
157 {
158 53x bool expected = false;
159 53x if(has_winner_.compare_exchange_strong(
160 expected, true, std::memory_order_acq_rel))
161 {
162 23x winner_index_ = index;
163 23x stop_source_.request_stop();
164 23x return true;
165 }
166 30x return false;
167 }
168
169 /** @pre try_win() returned true. */
170 1x void set_winner_exception(std::exception_ptr ep) noexcept
171 {
172 1x winner_exception_ = ep;
173 1x }
174
175 // Runners signal completion directly via final_suspend; no member function needed.
176 };
177
178 } // namespace detail
179
180 namespace detail {
181
182 // State for io_result-aware when_any: only !ec wins.
183 template<typename... Ts>
184 struct when_any_io_state
185 {
186 static constexpr std::size_t task_count = sizeof...(Ts);
187 using variant_type = std::variant<std::error_code, Ts...>;
188
189 when_any_core core_;
190 std::optional<variant_type> result_;
191 std::array<continuation, task_count> runner_handles_{};
192
193 // Last failure (error or exception) for the all-fail case.
194 // Last writer wins — no priority between errors and exceptions.
195 std::mutex failure_mu_;
196 std::error_code last_error_;
197 std::exception_ptr last_exception_;
198
199 18x when_any_io_state()
200 18x : core_(task_count)
201 {
202 18x }
203
204 14x void record_error(std::error_code ec)
205 {
206 14x std::lock_guard lk(failure_mu_);
207 14x last_error_ = ec;
208 14x last_exception_ = nullptr;
209 14x }
210
211 7x void record_exception(std::exception_ptr ep)
212 {
213 7x std::lock_guard lk(failure_mu_);
214 7x last_exception_ = ep;
215 7x last_error_ = {};
216 7x }
217 };
218
219 // Wrapper coroutine for io_result-aware when_any children.
220 // unhandled_exception records the exception but does NOT claim winner status.
221 template<typename StateType>
222 struct BOOST_CAPY_CORO_DESTROY_WHEN_COMPLETE when_any_io_runner
223 {
224 struct promise_type
225 : frame_alloc_mixin
226 {
227 StateType* state_ = nullptr;
228 std::size_t index_ = 0;
229 io_env env_;
230
231 87x when_any_io_runner get_return_object() noexcept
232 {
233 return when_any_io_runner(
234 87x std::coroutine_handle<promise_type>::from_promise(*this));
235 }
236
237 87x std::suspend_always initial_suspend() noexcept { return {}; }
238
239 87x auto final_suspend() noexcept
240 {
241 struct awaiter
242 {
243 promise_type* p_;
244 4x bool await_ready() const noexcept { return false; }
245 4x auto await_suspend(std::coroutine_handle<> h) noexcept
246 {
247 4x auto& core = p_->state_->core_;
248 4x auto* counter = &core.remaining_count_;
249 4x auto* caller_env = core.caller_env_;
250 4x auto& cont = core.continuation_;
251
252 4x h.destroy();
253
254 4x auto remaining = counter->fetch_sub(1, std::memory_order_acq_rel);
255 4x if(remaining == 1)
256 2x return detail::symmetric_transfer(caller_env->executor.dispatch(cont));
257 2x return detail::symmetric_transfer(std::noop_coroutine());
258 }
259 void await_resume() const noexcept {} // LCOV_EXCL_LINE final_suspend awaiter, never resumed
260 };
261 87x return awaiter{this};
262 }
263
264 74x void return_void() noexcept {}
265
266 // Exceptions do NOT win in io_result when_any
267 13x void unhandled_exception() noexcept
268 {
269 13x state_->record_exception(std::current_exception());
270 13x }
271
272 template<class Awaitable>
273 struct transform_awaiter
274 {
275 std::decay_t<Awaitable> a_;
276 promise_type* p_;
277
278 87x bool await_ready() { return a_.await_ready(); }
279 87x decltype(auto) await_resume() { return a_.await_resume(); }
280
281 template<class Promise>
282 85x auto await_suspend(std::coroutine_handle<Promise> h)
283 {
284 using R = decltype(a_.await_suspend(h, &p_->env_));
285 if constexpr (std::is_same_v<R, std::coroutine_handle<>>)
286 85x return detail::symmetric_transfer(a_.await_suspend(h, &p_->env_));
287 else
288 return a_.await_suspend(h, &p_->env_);
289 }
290 };
291
292 template<class Awaitable>
293 87x auto await_transform(Awaitable&& a)
294 {
295 using A = std::decay_t<Awaitable>;
296 if constexpr (IoAwaitable<A>)
297 {
298 return transform_awaiter<Awaitable>{
299 172x std::forward<Awaitable>(a), this};
300 }
301 else
302 {
303 static_assert(sizeof(A) == 0, "requires IoAwaitable");
304 }
305 85x }
306 };
307
308 std::coroutine_handle<promise_type> h_;
309
310 87x explicit when_any_io_runner(std::coroutine_handle<promise_type> h) noexcept
311 87x : h_(h)
312 {
313 87x }
314
315 when_any_io_runner(when_any_io_runner&& other) noexcept
316 : h_(std::exchange(other.h_, nullptr))
317 {
318 }
319
320 when_any_io_runner(when_any_io_runner const&) = delete;
321 when_any_io_runner& operator=(when_any_io_runner const&) = delete;
322 when_any_io_runner& operator=(when_any_io_runner&&) = delete;
323
324 87x auto release() noexcept
325 {
326 87x return std::exchange(h_, nullptr);
327 }
328 };
329
330 // Runner coroutine: only tries to win when the child returns !ec.
331 template<std::size_t I, IoAwaitable Awaitable, typename StateType>
332 when_any_io_runner<StateType>
333 33x make_when_any_io_runner(Awaitable inner, StateType* state)
334 {
335 auto result = co_await std::move(inner);
336
337 if(!result.ec)
338 {
339 // Success: try to claim winner
340 if(state->core_.try_win(I))
341 {
342 try
343 {
344 state->result_.emplace(
345 std::in_place_index<I + 1>,
346 detail::extract_io_payload(std::move(result)));
347 }
348 catch(...)
349 {
350 state->core_.set_winner_exception(std::current_exception());
351 }
352 }
353 }
354 else
355 {
356 // Error: record but don't win
357 state->record_error(result.ec);
358 }
359 66x }
360
361 // Launcher for io_result-aware when_any.
362 template<IoAwaitable... Awaitables>
363 class when_any_io_launcher
364 {
365 using state_type = when_any_io_state<
366 io_result_payload_t<awaitable_result_t<Awaitables>>...>;
367
368 std::tuple<Awaitables...>* tasks_;
369 state_type* state_;
370
371 public:
372 18x when_any_io_launcher(
373 std::tuple<Awaitables...>* tasks,
374 state_type* state)
375 18x : tasks_(tasks)
376 18x , state_(state)
377 {
378 18x }
379
380 18x bool await_ready() const noexcept
381 {
382 18x return sizeof...(Awaitables) == 0;
383 }
384
385 18x std::coroutine_handle<> await_suspend(
386 std::coroutine_handle<> continuation, io_env const* caller_env)
387 {
388 18x state_->core_.continuation_.h = continuation;
389 18x state_->core_.caller_env_ = caller_env;
390
391 18x if(caller_env->stop_token.stop_possible())
392 {
393 4x state_->core_.parent_stop_callback_.emplace(
394 2x caller_env->stop_token,
395 2x when_any_core::stop_callback_fn{&state_->core_.stop_source_});
396
397 2x if(caller_env->stop_token.stop_requested())
398 1x state_->core_.stop_source_.request_stop();
399 }
400
401 18x auto token = state_->core_.stop_source_.get_token();
402 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
403 2x (..., launch_one<Is>(caller_env->executor, token));
404 18x }(std::index_sequence_for<Awaitables...>{});
405
406 36x return std::noop_coroutine();
407 18x }
408
409 18x void await_resume() const noexcept {}
410
411 private:
412 template<std::size_t I>
413 33x void launch_one(executor_ref caller_ex, std::stop_token token)
414 {
415 33x auto runner = make_when_any_io_runner<I>(
416 33x std::move(std::get<I>(*tasks_)), state_);
417
418 33x auto h = runner.release();
419 33x h.promise().state_ = state_;
420 33x h.promise().index_ = I;
421 33x h.promise().env_ = io_env{caller_ex, token,
422 33x state_->core_.caller_env_->frame_allocator};
423
424 33x state_->runner_handles_[I].h = std::coroutine_handle<>{h};
425 33x caller_ex.post(state_->runner_handles_[I]);
426 66x }
427 };
428
429 /** Shared state for homogeneous io_result-aware when_any (range overload).
430
431 @tparam T The payload type extracted from io_result.
432 */
433 template<typename T>
434 struct when_any_io_homogeneous_state
435 {
436 when_any_core core_;
437 std::optional<T> result_;
438 std::unique_ptr<continuation[]> runner_handles_;
439
440 std::mutex failure_mu_;
441 std::error_code last_error_;
442 std::exception_ptr last_exception_;
443
444 13x explicit when_any_io_homogeneous_state(std::size_t count)
445 13x : core_(count)
446 13x , runner_handles_(std::make_unique<continuation[]>(count))
447 {
448 13x }
449
450 6x void record_error(std::error_code ec)
451 {
452 6x std::lock_guard lk(failure_mu_);
453 6x last_error_ = ec;
454 6x last_exception_ = nullptr;
455 6x }
456
457 4x void record_exception(std::exception_ptr ep)
458 {
459 4x std::lock_guard lk(failure_mu_);
460 4x last_exception_ = ep;
461 4x last_error_ = {};
462 4x }
463 };
464
465 /** Specialization for void io_result children (no payload storage). */
466 template<>
467 struct when_any_io_homogeneous_state<std::tuple<>>
468 {
469 when_any_core core_;
470 std::unique_ptr<continuation[]> runner_handles_;
471
472 std::mutex failure_mu_;
473 std::error_code last_error_;
474 std::exception_ptr last_exception_;
475
476 3x explicit when_any_io_homogeneous_state(std::size_t count)
477 3x : core_(count)
478 3x , runner_handles_(std::make_unique<continuation[]>(count))
479 {
480 3x }
481
482 1x void record_error(std::error_code ec)
483 {
484 1x std::lock_guard lk(failure_mu_);
485 1x last_error_ = ec;
486 1x last_exception_ = nullptr;
487 1x }
488
489 2x void record_exception(std::exception_ptr ep)
490 {
491 2x std::lock_guard lk(failure_mu_);
492 2x last_exception_ = ep;
493 2x last_error_ = {};
494 2x }
495 };
496
497 /** Create an io_result-aware runner for homogeneous when_any (range path).
498
499 Only tries to win when the child returns !ec.
500 */
501 template<IoAwaitable Awaitable, typename StateType>
502 when_any_io_runner<StateType>
503 54x make_when_any_io_homogeneous_runner(
504 Awaitable inner, StateType* state, std::size_t index)
505 {
506 auto result = co_await std::move(inner);
507
508 if(!result.ec)
509 {
510 if(state->core_.try_win(index))
511 {
512 using PayloadT = io_result_payload_t<
513 awaitable_result_t<Awaitable>>;
514 if constexpr (!std::is_same_v<PayloadT, std::tuple<>>)
515 {
516 try
517 {
518 state->result_.emplace(
519 extract_io_payload(std::move(result)));
520 }
521 catch(...)
522 {
523 state->core_.set_winner_exception(
524 std::current_exception());
525 }
526 }
527 }
528 }
529 else
530 {
531 state->record_error(result.ec);
532 }
533 108x }
534
535 /** Launches all io_result-aware homogeneous runners concurrently. */
536 template<IoAwaitableRange Range>
537 class when_any_io_homogeneous_launcher
538 {
539 using Awaitable = std::ranges::range_value_t<Range>;
540 using PayloadT = io_result_payload_t<awaitable_result_t<Awaitable>>;
541
542 Range* range_;
543 when_any_io_homogeneous_state<PayloadT>* state_;
544
545 public:
546 16x when_any_io_homogeneous_launcher(
547 Range* range,
548 when_any_io_homogeneous_state<PayloadT>* state)
549 16x : range_(range)
550 16x , state_(state)
551 {
552 16x }
553
554 16x bool await_ready() const noexcept
555 {
556 16x return std::ranges::empty(*range_);
557 }
558
559 16x std::coroutine_handle<> await_suspend(
560 std::coroutine_handle<> continuation, io_env const* caller_env)
561 {
562 16x state_->core_.continuation_.h = continuation;
563 16x state_->core_.caller_env_ = caller_env;
564
565 16x if(caller_env->stop_token.stop_possible())
566 {
567 4x state_->core_.parent_stop_callback_.emplace(
568 2x caller_env->stop_token,
569 2x when_any_core::stop_callback_fn{&state_->core_.stop_source_});
570
571 2x if(caller_env->stop_token.stop_requested())
572 1x state_->core_.stop_source_.request_stop();
573 }
574
575 16x auto token = state_->core_.stop_source_.get_token();
576
577 // Phase 1: Create all runners without dispatching.
578 16x std::size_t index = 0;
579 70x for(auto&& a : *range_)
580 {
581 54x auto runner = make_when_any_io_homogeneous_runner(
582 54x std::move(a), state_, index);
583
584 54x auto h = runner.release();
585 54x h.promise().state_ = state_;
586 54x h.promise().index_ = index;
587 54x h.promise().env_ = io_env{caller_env->executor, token,
588 54x caller_env->frame_allocator};
589
590 54x state_->runner_handles_[index].h = std::coroutine_handle<>{h};
591 54x ++index;
592 }
593
594 // Phase 2: Post all runners. Any may complete synchronously.
595 16x auto* handles = state_->runner_handles_.get();
596 16x std::size_t count = state_->core_.remaining_count_.load(std::memory_order_relaxed);
597 70x for(std::size_t i = 0; i < count; ++i)
598 54x caller_env->executor.post(handles[i]);
599
600 32x return std::noop_coroutine();
601 70x }
602
603 16x void await_resume() const noexcept {}
604 };
605
606 } // namespace detail
607
608 /** Race a range of io_result-returning awaitables (non-void payloads).
609
610 Only a child returning !ec can win. Errors and exceptions do not
611 claim winner status. If all children fail, the last failure
612 is reported — either the last error_code at variant index 0,
613 or the last exception rethrown.
614
615 @param awaitables Range of io_result-returning awaitables (must
616 not be empty).
617
618 @return A task yielding variant<error_code, pair<size_t, PayloadT>>
619 where index 0 is failure and index 1 carries the winner's
620 index and payload.
621
622 @throws std::invalid_argument if range is empty.
623 @throws Rethrows last exception when no winner and the last
624 failure was an exception.
625
626 @par Example
627 @code
628 task<void> example()
629 {
630 std::vector<io_task<size_t>> reads;
631 for (auto& buf : buffers)
632 reads.push_back(stream.read_some(buf));
633
634 auto result = co_await when_any(std::move(reads));
635 if (result.index() == 1)
636 {
637 auto [idx, n] = std::get<1>(result);
638 }
639 }
640 @endcode
641
642 @see IoAwaitableRange, when_any
643 */
644 template<IoAwaitableRange R>
645 requires detail::is_io_result_v<
646 awaitable_result_t<std::ranges::range_value_t<R>>>
647 && (!std::is_same_v<
648 detail::io_result_payload_t<
649 awaitable_result_t<std::ranges::range_value_t<R>>>,
650 std::tuple<>>)
651 14x [[nodiscard]] auto when_any(R&& awaitables)
652 -> task<std::variant<std::error_code,
653 std::pair<std::size_t,
654 detail::io_result_payload_t<
655 awaitable_result_t<std::ranges::range_value_t<R>>>>>>
656 {
657 using Awaitable = std::ranges::range_value_t<R>;
658 using PayloadT = detail::io_result_payload_t<
659 awaitable_result_t<Awaitable>>;
660 using result_type = std::variant<std::error_code,
661 std::pair<std::size_t, PayloadT>>;
662 using OwnedRange = std::remove_cvref_t<R>;
663
664 auto count = std::ranges::size(awaitables);
665 if(count == 0)
666 throw std::invalid_argument("when_any requires at least one awaitable");
667
668 OwnedRange owned_awaitables = std::forward<R>(awaitables);
669
670 detail::when_any_io_homogeneous_state<PayloadT> state(count);
671
672 co_await detail::when_any_io_homogeneous_launcher<OwnedRange>(
673 &owned_awaitables, &state);
674
675 // Winner found
676 if(state.core_.has_winner_.load(std::memory_order_acquire))
677 {
678 if(state.core_.winner_exception_)
679 std::rethrow_exception(state.core_.winner_exception_);
680 co_return result_type{std::in_place_index<1>,
681 std::pair{state.core_.winner_index_, std::move(*state.result_)}};
682 }
683
684 // No winner — report last failure
685 if(state.last_exception_)
686 std::rethrow_exception(state.last_exception_);
687 co_return result_type{std::in_place_index<0>, state.last_error_};
688 28x }
689
690 /** Race a range of void io_result-returning awaitables.
691
692 Only a child returning !ec can win. Returns the winner's index
693 at variant index 1, or error_code at index 0 on all-fail.
694
695 @param awaitables Range of io_result<>-returning awaitables (must
696 not be empty).
697
698 @return A task yielding variant<error_code, size_t> where index 0
699 is failure and index 1 carries the winner's index.
700
701 @throws std::invalid_argument if range is empty.
702 @throws Rethrows first exception when no winner and at least one
703 child threw.
704
705 @par Example
706 @code
707 task<void> example()
708 {
709 std::vector<io_task<>> jobs;
710 jobs.push_back(background_work_a());
711 jobs.push_back(background_work_b());
712
713 auto result = co_await when_any(std::move(jobs));
714 if (result.index() == 1)
715 {
716 auto winner = std::get<1>(result);
717 }
718 }
719 @endcode
720
721 @see IoAwaitableRange, when_any
722 */
723 template<IoAwaitableRange R>
724 requires detail::is_io_result_v<
725 awaitable_result_t<std::ranges::range_value_t<R>>>
726 && std::is_same_v<
727 detail::io_result_payload_t<
728 awaitable_result_t<std::ranges::range_value_t<R>>>,
729 std::tuple<>>
730 3x [[nodiscard]] auto when_any(R&& awaitables)
731 -> task<std::variant<std::error_code, std::size_t>>
732 {
733 using OwnedRange = std::remove_cvref_t<R>;
734 using result_type = std::variant<std::error_code, std::size_t>;
735
736 auto count = std::ranges::size(awaitables);
737 if(count == 0)
738 throw std::invalid_argument("when_any requires at least one awaitable");
739
740 OwnedRange owned_awaitables = std::forward<R>(awaitables);
741
742 detail::when_any_io_homogeneous_state<std::tuple<>> state(count);
743
744 co_await detail::when_any_io_homogeneous_launcher<OwnedRange>(
745 &owned_awaitables, &state);
746
747 // Winner found
748 if(state.core_.has_winner_.load(std::memory_order_acquire))
749 {
750 if(state.core_.winner_exception_)
751 std::rethrow_exception(state.core_.winner_exception_);
752 co_return result_type{std::in_place_index<1>,
753 state.core_.winner_index_};
754 }
755
756 // No winner — report last failure
757 if(state.last_exception_)
758 std::rethrow_exception(state.last_exception_);
759 co_return result_type{std::in_place_index<0>, state.last_error_};
760 6x }
761
762 /** Race io_result-returning awaitables, selecting the first success.
763
764 Overload selected when all children return io_result<Ts...>.
765 Only a child returning !ec can win. Errors and exceptions do
766 not claim winner status.
767
768 @return A task yielding variant<error_code, R1, ..., Rn> where
769 index 0 is the failure/no-winner case and index i+1
770 identifies the winning child.
771 */
772 template<IoAwaitable... As>
773 requires (sizeof...(As) > 0)
774 && detail::all_io_result_awaitables<As...>
775 18x [[nodiscard]] auto when_any(As... as)
776 -> task<std::variant<
777 std::error_code,
778 detail::io_result_payload_t<awaitable_result_t<As>>...>>
779 {
780 using result_type = std::variant<
781 std::error_code,
782 detail::io_result_payload_t<awaitable_result_t<As>>...>;
783
784 detail::when_any_io_state<
785 detail::io_result_payload_t<awaitable_result_t<As>>...> state;
786 std::tuple<As...> awaitable_tuple(std::move(as)...);
787
788 co_await detail::when_any_io_launcher<As...>(
789 &awaitable_tuple, &state);
790
791 // Winner found: return their result
792 if(state.result_.has_value())
793 co_return std::move(*state.result_);
794
795 // Winner claimed but payload construction failed
796 if(state.core_.winner_exception_)
797 std::rethrow_exception(state.core_.winner_exception_);
798
799 // No winner — report last failure
800 if(state.last_exception_)
801 std::rethrow_exception(state.last_exception_);
802 co_return result_type{std::in_place_index<0>, state.last_error_};
803 36x }
804
805 } // namespace capy
806 } // namespace boost
807
808 #endif
809