#define BOOST_YAP_CONVERSION_OPERATOR_TEMPLATE 1 #include #include #include #include #include template struct lazy_vector_expr; struct take_nth { boost::yap::terminal operator() (boost::yap::terminal> const & expr); std::size_t n; }; template struct lazy_vector_expr { using this_type = lazy_vector_expr; static const boost::yap::expr_kind kind = Kind; Tuple elements; BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(plus, this_type, ::lazy_vector_expr) BOOST_YAP_USER_BINARY_OPERATOR_MEMBER(minus, this_type, ::lazy_vector_expr) auto operator[] (std::size_t n) const { return boost::yap::evaluate(boost::yap::transform(*this, take_nth{n})); } }; boost::yap::terminal take_nth::operator() (boost::yap::terminal> const & expr) { double x = boost::yap::value(expr)[n]; return boost::yap::make_terminal(std::move(x)); } struct lazy_vector : lazy_vector_expr< boost::yap::expr_kind::terminal, boost::hana::tuple> > { template lazy_vector & operator+= (lazy_vector_expr const & rhs) { std::vector & this_vec = boost::yap::value(*this); for (int i = 0, size = (int)this_vec.size(); i < size; ++i) { this_vec[i] += rhs[i]; } return *this; } }; int main () { lazy_vector v1{{std::vector(4, 1.0)}}; lazy_vector v2{{std::vector(4, 2.0)}}; lazy_vector v3{{std::vector(4, 3.0)}}; double d1 = (v2 + v3)[2]; std::cout << d1 << "\n"; v1 += v2 - v3; std::cout << '{' << v1[0] << ',' << v1[1] << ',' << v1[2] << ',' << v1[3] << '}' << "\n"; // This expression is disallowed because it does not conform // to the implicit grammar. // (v2 + v3) += v1; return 0; }