...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Given wait_all_until_error_source()
,
it might be more reasonable to make a wait_all_...()
that collects all
errors instead of presenting only the first:
template< typename Fn, typename ... Fns > std::vector< typename std::result_of< Fn() >::type > wait_all_collect_errors( Fn && function, Fns && ... functions) { std::size_t count( 1 + sizeof ... ( functions) ); typedef typename std::result_of< Fn() >::type return_t; typedef typename boost::fibers::future< return_t > future_t; typedef std::vector< return_t > vector_t; vector_t results; results.reserve( count); exception_list exceptions("wait_all_collect_errors() exceptions"); // get channel std::shared_ptr< boost::fibers::buffered_channel< future_t > > chan( wait_all_until_error_source( std::forward< Fn >( function), std::forward< Fns >( functions) ... ) ); // fill results and/or exceptions vectors future_t future; while ( boost::fibers::channel_op_status::success == chan->pop( future) ) { std::exception_ptr exp = future.get_exception_ptr(); if ( ! exp) { results.push_back( future.get() ); } else { exceptions.add( exp); } } // if there were any exceptions, throw if ( exceptions.size() ) { throw exceptions; } // no exceptions: return vector to caller return results; }
The implementation is a simple variation on wait_first_success()
,
using the same exception_list
exception class.