123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // Copyright (C) 2016-2018 T. Zachary Laine
- //
- // 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 <boost/yap/expression.hpp>
- #include <boost/test/minimal.hpp>
- template<typename T>
- using term = boost::yap::terminal<boost::yap::expression, T>;
- template<typename T>
- using ref = boost::yap::expression_ref<boost::yap::expression, T>;
- namespace yap = boost::yap;
- namespace bh = boost::hana;
- namespace user {
- struct number
- {
- double value;
- };
- struct eval_xform
- {
- auto
- operator()(yap::expr_tag<yap::expr_kind::terminal>, number const & n)
- {
- return n;
- }
- template<typename Expr>
- decltype(auto) operator()(
- yap::expression<yap::expr_kind::negate, bh::tuple<Expr>> const &
- expr)
- {
- number const n = transform(yap::value(expr), *this);
- return number{-n.value};
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- number const lhs = transform(yap::left(expr), *this);
- number const rhs = transform(yap::right(expr), *this);
- return number{lhs.value + rhs.value};
- }
- };
- }
- template<typename Expr>
- auto make_ref(Expr && expr)
- {
- using type = yap::detail::operand_type_t<yap::expression, Expr>;
- return yap::detail::make_operand<type>{}(static_cast<Expr &&>(expr));
- }
- int test_main(int, char * [])
- {
- {
- {
- term<user::number> a{{1.0}};
- {
- user::number result = transform(a, user::eval_xform{});
- BOOST_CHECK(result.value == 1);
- }
- {
- user::number result = transform(make_ref(a), user::eval_xform{});
- BOOST_CHECK(result.value == 1);
- }
- {
- user::number result = transform(-a, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr = make_ref(a);
- user::number result = transform(-expr, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr = -a;
- user::number result = transform(expr, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr1 = make_ref(a);
- auto expr2 = make_ref(expr1);
- user::number result = transform(expr2, user::eval_xform{});
- BOOST_CHECK(result.value == 1);
- }
- {
- auto expr1 = -a;
- auto expr2 = make_ref(expr1);
- user::number result = transform(expr2, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr1 = make_ref(a);
- auto expr2 = -expr1;
- user::number result = transform(expr2, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr1 = a;
- auto expr2 = make_ref(expr1);
- auto expr3 = make_ref(expr2);
- user::number result = transform(expr3, user::eval_xform{});
- BOOST_CHECK(result.value == 1);
- }
- {
- auto expr1 = -a;
- auto expr2 = make_ref(expr1);
- auto expr3 = make_ref(expr2);
- user::number result = transform(expr3, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr1 = make_ref(a);
- auto expr2 = -expr1;
- auto expr3 = make_ref(expr2);
- user::number result = transform(expr3, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- {
- auto expr1 = make_ref(a);
- auto expr2 = make_ref(expr1);
- auto expr3 = -expr2;
- user::number result = transform(expr3, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- }
- {
- user::number result =
- transform(-term<user::number>{{1.0}}, user::eval_xform{});
- BOOST_CHECK(result.value == -1);
- }
- }
- {
- term<user::number> a{{1.0}};
- term<user::number> x{{41.0}};
- {
- user::number result = transform(a + x, user::eval_xform{});
- BOOST_CHECK(result.value == 42);
- }
- {
- user::number result =
- transform(make_ref(a) + make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == 42);
- }
- {
- user::number result = transform(make_ref(a) + x, user::eval_xform{});
- BOOST_CHECK(result.value == 42);
- }
- {
- user::number result = transform(a + make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == 42);
- }
- {
- user::number result = transform(a + x, user::eval_xform{});
- BOOST_CHECK(result.value == 42);
- }
- {
- user::number result =
- transform(-make_ref(a) + make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == 40);
- }
- {
- user::number result = transform(-make_ref(a) + x, user::eval_xform{});
- BOOST_CHECK(result.value == 40);
- }
- {
- user::number result = transform(-a + make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == 40);
- }
- {
- user::number result = transform(-a + x, user::eval_xform{});
- BOOST_CHECK(result.value == 40);
- }
- {
- user::number result =
- transform(make_ref(a) + -make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == -40);
- }
- {
- user::number result = transform(make_ref(a) + -x, user::eval_xform{});
- BOOST_CHECK(result.value == -40);
- }
- {
- user::number result = transform(a + -make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == -40);
- }
- {
- user::number result = transform(a + -x, user::eval_xform{});
- BOOST_CHECK(result.value == -40);
- }
- {
- user::number result =
- transform(-make_ref(a) + -make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == -42);
- }
- {
- user::number result = transform(-make_ref(a) + -x, user::eval_xform{});
- BOOST_CHECK(result.value == -42);
- }
- {
- user::number result = transform(-a + -make_ref(x), user::eval_xform{});
- BOOST_CHECK(result.value == -42);
- }
- {
- user::number result = transform(-a + -x, user::eval_xform{});
- BOOST_CHECK(result.value == -42);
- }
- }
- return 0;
- }
|