/*============================================================================== Copyright (c) 2010 Thomas Heller Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #include #include #include #include #include namespace proto = boost::proto; namespace phoenix = boost::phoenix; namespace impl { template struct phoenix_to_cpp { phoenix_to_cpp( OutStream& ostr ) : ostr(ostr), level(1) {}; OutStream& ostr; int level; template ::type> struct eval : proto::null_eval {}; template struct eval { typedef OutStream& result_type; result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const { proto::eval(proto::child_c<0>(expr), ctx); ctx.ostr << " - "; proto::eval(proto::child_c<1>(expr), ctx); return ctx.ostr; } }; template struct eval { typedef OutStream& result_type; result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const { proto::eval(proto::child_c<0>(expr), ctx); ctx.ostr << " + "; proto::eval(proto::child_c<1>(expr), ctx); return ctx.ostr; } }; template struct eval { typedef OutStream& result_type; result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const { /*ctx.ostr << std::setw(ctx.level*4) << " ";*/ proto::eval(proto::child_c<0>(expr), ctx); ctx.ostr << ";\n"; /*ctx.ostr << std::setw(ctx.level*4) << " ";*/ proto::eval(proto::child_c<1>(expr), ctx); ctx.ostr << ";"; return ctx.ostr; } }; template struct eval { typedef OutStream& result_type; template void output(OutStream& os, E const& expr) const { std::cout << typeid( expr ).name() << "\n\n"; std::cout << typeid( typename phoenix::make_argument >::type ).name() << "\n\n"; } void output(OutStream& os, typename phoenix::make_argument >::type const& expr) { os << "arg" << 0; } void output(OutStream& os, typename phoenix::make_argument >::type const& expr) { os << "arg" << 1; } void output(OutStream& os, typename phoenix::make_argument >::type const& expr) { os << "arg" << 2; } void output(OutStream& os, typename phoenix::make_argument >::type const& expr) { os << "arg" << 3; } /*phoenix::actor< proto::basic_expr< boost::proto::tag::function , proto::list3< proto::basic_expr< proto::tag::terminal , proto::term< phoenix::funcwrap > > , Env , proto::basic_expr< proto::tag::terminal , proto::term< N > > > > > const& expr) const */ result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const { output( ctx.ostr, expr ); return ctx.ostr; } }; }; } template void phoenix_to_cpp(Expr const& expr) { std::cout << "template \n"; std::cout << "Result f("; for( unsigned i = 0; i < phoenix::arity(expr); ++i ) { std::cout << "Arg" << i << " arg" << i; if( i != phoenix::arity(expr)-1 ) std::cout << ", "; } std::cout << ")\n{\n"; impl::phoenix_to_cpp ctx(std::cout); proto::eval( expr, ctx ); std::cout << "\n}\n"; } int main() { using phoenix::arg_names::arg1; using phoenix::arg_names::arg2; using phoenix::arg_names::arg3; phoenix_to_cpp( (arg1 + arg2, arg1 - arg2, arg1 + arg2 - arg3 ) ); }