#include #include #include #include namespace proto = boost::proto; using proto::_; template struct program_variable { T value; friend std::ostream &operator<<(std::ostream &s, program_variable v) { s << "V"; return s; } }; struct program_tag { friend std::ostream &operator<<(std::ostream &s, program_tag v) { s << "Program"; return s; } }; template struct fragment_expr; template struct program_expr; struct program_args : proto::or_< proto::terminal > , proto::address_of > > > {}; struct program_decl : proto::nary_expr > {}; struct program_generator : proto::or_< proto::when< proto::subscript , proto::pod_generator(_) > , proto::otherwise< proto::pod_generator(_) > > {}; struct program_domain : proto::domain {}; struct get_val : proto::callable { template struct result; template struct result &)> { typedef T& type; }; template typename result &)>::type operator()(program_variable &var) const { return var.value; } }; struct program_eval : proto::or_< proto::when< proto::terminal > , get_val(proto::_value) > , proto::otherwise< proto::_default > > {}; template struct fragment_expr { BOOST_PROTO_EXTENDS(E, fragment_expr, program_domain) }; template struct program_expr { BOOST_PROTO_BASIC_EXTENDS(E, program_expr, program_domain) typedef void result_type; // TODO : Make the type based on the type of E result_type operator()(int &a0, int &a1) const { proto::value(proto::left(proto::left(proto::left(*this)))).value = a0; proto::value(proto::left(proto::right(proto::left(*this)))).value = a1; program_eval()(proto::right(*this)); a0 = proto::value(proto::left(proto::left(proto::left(*this)))).value; a1 = proto::value(proto::left(proto::right(proto::left(*this)))).value; } }; typedef fragment_expr >::type> int_; typedef fragment_expr >::type> float_; typedef fragment_expr >::type> double_; #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, ref_a) \ template \ typename boost::proto::result_of::make_expr::type const \ Program(A_const_ref_a(N)) \ { \ return proto::make_expr(ref_a(N)); \ } \ /**/ #include BOOST_PROTO_LOCAL_ITERATE() int main() { int_ a, b, c; BOOST_AUTO(p, (Program(&a, &b)[c = b*2, a = c]) ); int ra = 0, rb = 4; p(ra, rb); assert(8 == ra); std::cout << "ra = " << ra << "\n"; return 0; }