
joel wrote:
You'll have to post your code ... I can't tell what problem you might be running into. Well, I decided to be a coward for today. I'll shelf this functional solution for later. I just added my own ternary_expr & quaternary_expr class for the moment as it seems it's all the client wants. I'll come back when I've digested those infos as I htink I'm just doing a small error.
For reference here is the code I wrote:
namespace bp = boost::proto;
struct push_front_
Must inherit from bp::callable.
{ template<class Sig> struct result; template<class This,class Seq,class Elem> struct result<This(Seq,Elem)> { typedef typename boost::fusion::result_of::push_front<Seq,Elem>::type type; };
template<class Seq,class Elem> typename result<push_front_(Seq,Elem)>::type operator()(Elem const& e, Seq& s ) const
Sequence and Element argument order is reversed here.
{ return boost::fusion::push_front(s,e); } };
struct _load : bp::transform< _load > { template<typename Expr, typename State, typename Data> struct impl : bp::transform_impl<Expr, State, Data> { typedef typename meta::strip<Expr>::type::value_type result_type;
result_type operator()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param data ) const { return expr(data); } }; };
struct eval_xpr : bp::or_< bp::when< bp::terminal< block<bp::_,bp::_> > , _load(bp::_) > , bp::when< bp::nary_expr< bp::_, bp::vararg<eval_xpr> > , bp::functional::unpack_expr<bp::tag::function>(
This will create the new expression but not evaluate it. I had incorrectly told you to use bp::function<> here for its pass-through transform, but that's not actually what you want. You want Proto's _default transform.
push_front_(bp::_, bp::terminal<functor<bp::tag_of<bp::_> > >() )
) ) > > {};
Here is some code that should get you going again: #include <boost/proto/core.hpp> #include <boost/proto/transform.hpp> #include <boost/fusion/include/push_front.hpp> namespace bp = boost::proto; struct push_front : bp::callable { template<class Sig> struct result; template<class This, class Seq, class Elem> struct result<This(Seq, Elem)> : boost::fusion::result_of::push_front< typename boost::remove_reference<Seq>::type const , typename boost::remove_reference<Elem>::type > {}; template<class Seq, class Elem> typename result<push_front(Seq const, Elem)>::type operator()(Seq const& s, Elem const& e) const { return boost::fusion::push_front(s, e); } }; template<typename T> struct functor; template<> struct functor<bp::tag::plus> { typedef int result_type; int operator()(int x, int y) const { return x + y; } }; struct eval_xpr : bp::or_< bp::when< bp::terminal< bp::_ > , bp::_value > , bp::when< bp::nary_expr< bp::_, bp::vararg<eval_xpr> > , bp::_default<eval_xpr>( bp::functional::unpack_expr<bp::tag::function>( push_front( bp::_ , bp::_make_terminal(functor<bp::tag_of<bp::_> >()) ) ) ) > > {}; int main() { bp::literal<int> x(1); bp::literal<int> y(2); int z = eval_xpr()(x + y); } Hope that helps, -- Eric Niebler BoostPro Computing http://www.boostpro.com