#include #include #include #include #include template struct iter_wrapper { Iter it; }; template auto make_iter_wrapper (Iter it) { return iter_wrapper{it}; } // container -> wrapped-begin transform struct begin { template auto operator() (boost::yap::terminal_tag, Cont const & cont) -> decltype(boost::yap::make_terminal(make_iter_wrapper(cont.begin()))) { return boost::yap::make_terminal(make_iter_wrapper(cont.begin())); } }; // wrapped-iterator -> dereferenced value transform struct deref { template auto operator() (boost::yap::terminal_tag, iter_wrapper wrapper) -> decltype(boost::yap::make_terminal(*wrapper.it)) { return boost::yap::make_terminal(*wrapper.it); } }; // wrapped-iterator increment transform, using side effects struct incr { template auto operator() (boost::yap::terminal_tag, iter_wrapper & wrapper) -> decltype(++wrapper.it, boost::yap::make_terminal(wrapper.it)) { ++wrapper.it; return boost::yap::make_terminal(wrapper.it); } }; template < template class Cont, typename T, typename A, typename Expr, typename Op > Cont & op_assign (Cont & cont, Expr const & e, Op && op) { decltype(auto) expr = boost::yap::as_expr(e); auto expr2 = boost::yap::transform(expr, begin{}); for (auto && x : cont) { op(x, boost::yap::evaluate(boost::yap::transform(expr2, deref{}))); boost::yap::transform(expr2, incr{}); } return cont; } template < template class Cont, typename T, typename A, typename Expr > Cont & assign (Cont & cont, Expr const & expr) { return op_assign(cont, expr, [](auto & cont_value, auto && expr_value) { cont_value = std::forward(expr_value); }); } template < template class Cont, typename T, typename A, typename Expr > Cont & operator+= (Cont & cont, Expr const & expr) { return op_assign(cont, expr, [](auto & cont_value, auto && expr_value) { cont_value += std::forward(expr_value); }); } template < template class Cont, typename T, typename A, typename Expr > Cont & operator-= (Cont & cont, Expr const & expr) { return op_assign(cont, expr, [](auto & cont_value, auto && expr_value) { cont_value -= std::forward(expr_value); }); } template struct is_mixed : std::false_type {}; template struct is_mixed> : std::true_type {}; template struct is_mixed> : std::true_type {}; BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(negate, boost::yap::expression, is_mixed); // - BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(multiplies, boost::yap::expression, is_mixed); // * BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(divides, boost::yap::expression, is_mixed); // / BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(modulus, boost::yap::expression, is_mixed); // % BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(plus, boost::yap::expression, is_mixed); // + BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(minus, boost::yap::expression, is_mixed); // - BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(less, boost::yap::expression, is_mixed); // < BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(greater, boost::yap::expression, is_mixed); // > BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(less_equal, boost::yap::expression, is_mixed); // <= BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(greater_equal, boost::yap::expression, is_mixed); // >= BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(equal_to, boost::yap::expression, is_mixed); // == BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(not_equal_to, boost::yap::expression, is_mixed); // != BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(logical_or, boost::yap::expression, is_mixed); // || BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(logical_and, boost::yap::expression, is_mixed); // && BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_and, boost::yap::expression, is_mixed); // & BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_or, boost::yap::expression, is_mixed); // | BOOST_YAP_USER_UDT_ANY_BINARY_OPERATOR(bitwise_xor, boost::yap::expression, is_mixed); // ^ namespace user { struct sin_tag {}; template inline auto eval_call (sin_tag, T && x) { return std::sin(x); } } int main() { int n = 10; std::vector a,b,c,d; std::list e; std::list> f; int i; for(i = 0;i < n; ++i) { a.push_back(i); b.push_back(2*i); c.push_back(3*i); d.push_back(i); e.push_back(0.0); f.push_back(std::complex(1.0, 1.0)); } assign(b, 2); assign(d, a + b * c); a += if_else(d < 30, b, c); assign(e, c); e += e - 4 / (c + 1); auto sin = boost::yap::make_terminal(user::sin_tag{}); f -= sin(0.1 * e * std::complex(0.2, 1.2)); std::list::const_iterator ei = e.begin(); std::list>::const_iterator fi = f.begin(); for (i = 0; i < n; ++i) { std::cout << "a(" << i << ") = " << a[i] << " b(" << i << ") = " << b[i] << " c(" << i << ") = " << c[i] << " d(" << i << ") = " << d[i] << " e(" << i << ") = " << *ei++ << " f(" << i << ") = " << *fi++ << std::endl; } return 0; }