#ifndef FORK_HPP_INCLUDED #define FORK_HPP_INCLUDED // Copyright (c) 2007 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // http://www.boost.org/LICENSE_1_0.txt #include "future.hpp" #include "thread.hpp" #include #include class fork_canceled: public std::exception { public: char const * what() const throw() { return "std::fork_canceled"; } }; template class task { private: Fn fn_; future ft_; public: task( Fn fn, future const & ft ): fn_( fn ), ft_( ft ) { } void operator()() // throw() { try { ft_.set_value( fn_() ); } catch( std::thread_cancel const & ) { ft_.set_exception( copy_exception( fork_canceled() ) ); } catch( ... ) { ft_.set_exception( current_exception() ); } } }; template class task< void, Fn > { private: Fn fn_; future ft_; public: task( Fn fn, future const & ft ): fn_( fn ), ft_( ft ) { } void operator()() // throw() { try { fn_(); ft_.set_value(); } catch( std::thread_cancel const & ) { ft_.set_exception( copy_exception( fork_canceled() ) ); } catch( ... ) { ft_.set_exception( current_exception() ); } } }; void fork_impl( boost::function< void() > const & fn ); template< class Fn > future< typename boost::result_of::type > fork( Fn fn ) { typedef typename boost::result_of::type R; future ft; task fw( fn, ft ); fork_impl( fw ); return ft; } template< class Fn, class A1 > future< typename boost::result_of::type > fork( Fn fn, A1 a1 ) { return fork( boost::bind( fn, a1 ) ); } template< class Fn, class A1, class A2 > future< typename boost::result_of::type > fork( Fn fn, A1 a1, A2 a2 ) { return fork( boost::bind( fn, a1, a2 ) ); } template< class Fn, class A1, class A2, class A3 > future< typename boost::result_of::type > fork( Fn fn, A1 a1, A2 a2, A3 a3 ) { return fork( boost::bind( fn, a1, a2, a3 ) ); } #endif // #ifndef FORK_HPP_INCLUDED