
Hi Olivier, This is very elegant on the context of the future library. I was thinking on some kind of mpl generation for the exception_ptr library but I didn't thounk to wrappe the call. ----- Original Message ----- From: "Kowalke Oliver (QD IT PA AS)" <Oliver.Kowalke@qimonda.com> To: <boost@lists.boost.org> Sent: Monday, April 14, 2008 9:26 AM Subject: Re: [boost] Review Request: future library (Gaskill version)
Sorry - didn't read your docu carefully. As you say in the docs 'However, arbitrary user-defined exception types cannot be supported.'.
What about to specify an mpl::vector with arbitrary user-defined exception types? I'm using your future library siunce last year with this little modification (at least for me it works). Oliver
template< typename R, typename V = mpl::vector<>
class future_wrapper { public: future_wrapper(const boost::function<R (void)> &fn, const promise<R> &ft ) : fn_(fn), ft_(ft) {}; // stores fn and ft void operator()() throw() { // executes fn() and places the outcome into ft
typedef typename boost::mpl::fold< V, detail::exec_function, detail::catch_exception< boost::mpl::_1, boost::mpl::_2 > >::type exec_type;
detail::catch_ellipsis< exec_type >::exec( fn_, ft_); } private: boost::function<R (void)> fn_; promise<R> ft_; };
struct exec_function { template< typename R > static void exec( boost::function< R ( void) > const& fn, boost::promise< R > & ft) { ft.set( fn() ); }
static void exec( boost::function< void ( void) > const& fn, boost::promise< void > & ft) { fn(); ft.set(); } };
template< typename P, typename E > struct catch_exception { template< typename R > static void exec( boost::function< R ( void) > const& fn, boost::promise< R > & ft) { try { P::exec( fn, ft); } catch ( E const& e) { ft.set_exception( e); } }
static void exec( boost::function< void ( void) > const& fn, boost::promise< void > & ft) { try { P::exec( fn, ft); } catch ( E const& e) { ft.set_exception( e); } } };
template< typename P > struct catch_ellipsis { template< typename R > static void exec( boost::function< R ( void) > const& fn, boost::promise< R > & ft) { try { P::exec( fn, ft); } catch (...) { ft.set_exception(boost::detail::current_exception() ); } }
static void exec( boost::function< void ( void) > const& fn, boost::promise< void > & ft) { try { P::exec( fn, ft); } catch (...) { ft.set_exception(boost::detail::current_exception() ); } } };
Hello, is it correct that user defined exceptions thrown by the defered function object will be rethrown as as std::runtime_error (if it was derived from std::exception) or std::bad_exception? If yes - what about specifying an mpl::vector with user defined exception types (passing to future_wrapper etc.)? regards, oliver
I see only a problem: the interface of the future_wrapper is changed. Maybe something like template< typename R, typename V = BOOST_EXCEPTION_PTR_USER_EXCEPTION_VECTOR class future_wrapper ... allow to preserv the interface. Another problem is that we need to do the same for each class using the exception_ptr library. It will be nice if the exec_function, the catch_exception and the catch_ellipsis do not depend directly on the promise<R>. I don't know if it is possible to make a wrap_call template with a template parameter Promise and having these three classes nested. template <class template<class> PromiseTmpl> struct wrap_call { struct exec_function { template< typename R, class Policy= promise_policy< PromiseTmpl< R >
static void exec( boost::function< R ( void) > const& fn, PromiseTmpl< R > & ft) { Policy::set(ft, fn() ); } // ...
template < typename V = BOOST_EXCEPTION_PTR_USER_EXCEPTION_VECTOR > struct call { typedef typename boost::mpl::fold< V, wrap_call<PromiseTmpl>::exec_function, wrap_call<PromiseTmpl>::catch_exception< boost::mpl::_1, boost::mpl::_2 > >::type exec_type; typedef wrap_call<PromiseTmpl>::catch_ellipsis< exec_type > type; }; } A policy class should be needed to take care of the promise concept interface template <class Promise> struct promise_policy { void set(Promise& p, const R &v) {p.set(v);} void set_exception(Promise& p, const exception_ptr&e) {p.set_exception(e);} }; And use it as follows template< typename R, typename V = BOOST_EXCEPTION_PTR_USER_EXCEPTION_VECTOR class future_wrapper { // ... future_wrapper(const boost::function<R (void)> &fn, const promise<R> &ft ) : fn_(fn), ft_(ft) {}; // stores fn and ft void operator()() throw() { // executes fn() and places the outcome into ft exception_ptr::wrap_call<promise>::call<V>::exec( fn_, ft_); } // ... Do you think that this could work? Best _____________________ Vicente Juan Botet Escriba