----- Original Message ----- From: "joel falcou" <joel.falcou@lri.fr> To: <boost-users@lists.boost.org> Sent: Friday, January 22, 2010 1:41 AM Subject: Re: [Boost-users] generate an n-deep runtime for loop
Hicham Mouline wrote:
Please refer to the first post of this thread for the initial question. I believe the compiler got stuck in an infinite loop of template instantiations from my code. It hasn't stopped printing instantiation backtraces when I interrupted it and never reached printing the actuall error :-) The code is ///@param params_seq fusion::vector< variant<>, variant<>, ...., variant<>
///@param body a callable that takes a parameters_t const-ref as an argument /// template <typename parameters_t, typename params_1_n_seq_t, typename inner_body_t, typename N = typename boost::fusion::result_of::size<parameters_t>::type > struct for_recursive { void operator()(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) const { for_iterate<N>( boost::fusion::front(params_seq), params, params_seq, body ); } }; /// Partial specialization for case 0 template <typename parameters_t, typename params_1_n_seq_t, typename inner_body_t> struct for_recursive< parameters_t, params_1_n_seq_t, inner_body_t, boost::mpl::int_<0> > { void operator()(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) const { body(params); } }; Is the second half a partial specialization of the primary template, for the case N = int_<0> ? for_iterate is a template function that applies a visitor on the front variant of the sequence. The visitor then calls for_recursive<>::operator() back with the fusion sequence with the front popped, and N decremented by 1, mpl::minus<N, int_<1>>... template <typename N, typename T, typename parameters_t, typename params_1_n_seq_t, typename inner_body_t> void for_iterate( const boost::variant< std::vector<T>, range_incr<T>, range<T>, T >& v, parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body ) { boost::apply_visitor( for_iterate_visitor<T,parameters_t,params_1_n_seq_t,inner_body_t,N>(params, params_seq, body), v ); } This visitor is below: /// /// visitor for the "for iterator" /// template <typename T, typename parameters_t, typename params_1_n_seq_t, typename inner_body_t, typename N> class for_iterate_visitor: public boost::static_visitor<> { public: for_iterate_visitor(parameters_t& params, const params_1_n_seq_t& params_seq, const inner_body_t& body) : params_(params), params_seq_(params_seq), params_reduced_seq_( boost::fusion::pop_front(params_seq) ), body_(body) {} private: typedef typename boost::fusion::result_of::size<parameters_t>::type size_of_parameters_t; typedef typename boost::mpl::minus< size_of_parameters_t , N >::type Index; typedef typename boost::mpl::minus<N, boost::mpl::int_<1> >::type Nminus1; typedef typename boost::fusion::result_of::pop_front<const params_1_n_seq_t>::type params_1_n_reduced_seq_t; public: void operator()( const std::vector<T>& v ) const { for (size_t index=0; index<v.size(); ++index) { boost::fusion::at<Index, parameters_t>(params_) = v[index]; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( const range_incr<T>& r) const { for (T param=r.min; param<=r.max; param+=r.incr) { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( const range<T>& r ) const { for (T param=r.min; param<=r.max; ++param) { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } } void operator()( T param ) const { boost::fusion::at<Index, parameters_t>(params_) = param; for_recursive<parameters_t, params_1_n_reduced_seq_t, inner_body_t, Nminus1>()( params_, params_reduced_seq_, body_ ); } private: parameters_t& params_; const params_1_n_seq_t& params_seq_; const params_1_n_reduced_seq_t& params_reduced_seq_; const inner_body_t& body_; }; The full code doesn't compile, the entry point is for_recursive<params1_t, params1_1_n_seq_t, for_print_it>()( p, p2, for_print_it() ); struct for_print_it { void operator()(const params1& p) const { std::cout<< p.field1<<std::endl; } }; regards,