[proto] folding a proto tree in reverse

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

Sorry for the noise, please disregard the previous post. I was missing the state in the invocation of the fold. Which is ok, when you don't have a data (it gets default constructed, which would have been ok for me), but cannot possibly work with data. --

Maurizio Vitale wrote:
Sorry for the noise, please disregard the previous post. I was missing the state in the invocation of the fold. Which is ok, when you don't have a data (it gets default constructed, which would have been ok for me), but cannot possibly work with data.
Good, I was just sitting down to write a response. So did you get it working with proto::reverse_fold_tree?. Using fusion algorithms with proto::flatten will surely lead to long compile times. -- Eric Niebler BoostPro Computing http://www.boostpro.com

"Eric" == Eric Niebler <eric@boostpro.com> writes:
Eric> Maurizio Vitale wrote: >> Sorry for the noise, please disregard the previous post. I was >> missing the state in the invocation of the fold. Which is ok, >> when you don't have a data (it gets default constructed, which >> would have been ok for me), but cannot possibly work with data. Eric> Good, I was just sitting down to write a response. So did you Eric> get it working with proto::reverse_fold_tree?. Using fusion Eric> algorithms with proto::flatten will surely lead to long Eric> compile times. proto::reverse_fold_tree worked just fine in the end. I'm not too concerned about compilation time at this point. Rather the assembly code generated when evaluating fixed-point arithmetic shouldn't be too far from what you'd write by hand. Maurizio
participants (3)
-
Eric Niebler
-
Maurizio Vitale
-
Maurizio Vitale