|
Boost Users : |
Subject: [Boost-users] [proto] folding a proto tree in reverse
From: Maurizio Vitale (maurizio.vitale_at_[hidden])
Date: 2009-08-29 18:02:50
I need to traverse a proto tree from right to left so that given the
statement:
(a, b, c) = expr;
I can assign in order c then b and lastly a.
A fragment that does the order a,b,c (and work, but not very
efficiently, which is why I want to go the other way) is:
template<typename E>
struct assign_aux {
assign_aux (const E& rhs) : m_rhs (rhs) {}
typedef int result_type;
template<typename T>
int operator()(const T& t, int offset) const {
int next_offset = offset - actual_width_transform () (t);
int value = systemc_eval (m_rhs.range (offset,next_offset+1));
const_cast<T&>(t) = value;
return next_offset;
}
const E& m_rhs;
};
template <typename E>
struct assign<E, proto::tag::comma> {
template<typename RHS>
const E& doit (const E& e, const RHS& rhs) {
int width = actual_width_transform () (e);
fusion::fold(proto::flatten (const_cast<systemc_expression&>(e)), width-1, assign_aux<RHS> (rhs));
return e;
}
};
template<typename E>
const systemc_expression& operator = (const E& e) const {
BOOST_MPL_ASSERT ((proto::matches<systemc_expression, lhs_systemc_grammar>));
return assign<systemc_expression>().doit (*this, e);
return *this;
}
I've tried to use fusion::reverse_view to invert the fusion sequence,
but failed. I also suspect that the resulting code wouldn't be as good
as it could be, which in my application is critical.
So I looked at alternatives and tried proto::reverse_fold_tree. Here's
my attempt:
struct assign_terminal : proto::callable {
typedef int result_type;
template<typename T, typename O, typename R>
int
operator () (T& t, O o, const R& r) const {
int width = actual_width_transform () (t);
const_cast<T&>(t) = r.range (1,0);
return o+width;
}
};
template <typename E>
struct assign<E, proto::tag::comma> {
template<typename RHS>
const E& doit (const E& e, const RHS& rhs) {
proto::reverse_fold_tree<_, int() , assign_terminal (_, proto::_state, proto::_data)>() (e, rhs);
return e;
}
};
template<typename E>
const systemc_expression& operator = (const E& e) const {
BOOST_MPL_ASSERT ((proto::matches<systemc_expression, lhs_systemc_grammar>));
return assign<systemc_expression>().doit (*this, e);
return *this;
}
But this doesn't seem to pass the data (rhs) to
assign_terminal::operator () (expr, state, data). There're really very
few examples on how to use proto::fold_tree and even fewer using the
data parameter, so I don't have much to go on.
Would anybody whose name is Eric tell me why I'm this stupid?
TIA,
Maurizio
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