|
Boost Users : |
Subject: Re: [Boost-users] generate an n-deep runtime for loop
From: Hicham Mouline (hicham_at_[hidden])
Date: 2010-01-24 04:00:54
----- Original Message -----
From: "joel falcou" <joel.falcou_at_[hidden]>
To: <boost-users_at_[hidden]>
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,
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net