123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948 |
- // 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;
- friend number operator+(number lhs, number rhs)
- {
- return number{lhs.value + rhs.value};
- }
- friend number operator-(number lhs, number rhs)
- {
- return number{lhs.value - rhs.value};
- }
- friend number operator*(number lhs, number rhs)
- {
- return number{lhs.value * rhs.value};
- }
- friend number operator-(number n) { return number{-n.value}; }
- friend bool operator<(number lhs, double rhs)
- {
- return lhs.value < rhs;
- }
- friend bool operator<(double lhs, number rhs)
- {
- return lhs < rhs.value;
- }
- };
- number naxpy(number a, number x, number y)
- {
- return number{a.value * x.value + y.value + 10.0};
- }
- struct empty_xform
- {};
- struct eval_xform_tag
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return n;
- }
- };
- struct eval_xform_expr
- {
- decltype(auto) operator()(term<user::number> const & expr)
- {
- return ::boost::yap::value(expr);
- }
- };
- struct eval_xform_both
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return n;
- }
- decltype(auto) operator()(term<user::number> const & expr)
- {
- throw std::logic_error("Oops! Picked the wrong overload!");
- return ::boost::yap::value(expr);
- }
- };
- struct plus_to_minus_xform_tag
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- user::number const & lhs,
- user::number const & rhs)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- term<user::number>{lhs}, term<user::number>{rhs});
- }
- };
- struct plus_to_minus_xform_expr
- {
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- ::boost::yap::left(expr), ::boost::yap::right(expr));
- }
- };
- struct plus_to_minus_xform_both
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- user::number const & lhs,
- user::number const & rhs)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- term<user::number>{lhs}, term<user::number>{rhs});
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- throw std::logic_error("Oops! Picked the wrong overload!");
- return yap::make_expression<yap::expr_kind::minus>(
- ::boost::yap::left(expr), ::boost::yap::right(expr));
- }
- };
- struct term_nonterm_xform_tag
- {
- auto operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return yap::make_terminal(n * user::number{2.0});
- }
- auto operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- user::number const & lhs,
- user::number const & rhs)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- yap::transform(::boost::yap::make_terminal(lhs), *this),
- yap::transform(::boost::yap::make_terminal(rhs), *this));
- }
- };
- struct term_nonterm_xform_expr
- {
- decltype(auto) operator()(term<user::number> const & expr)
- {
- return yap::make_terminal(
- ::boost::yap::value(expr) * user::number{2.0});
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- yap::transform(::boost::yap::left(expr), *this),
- yap::transform(::boost::yap::right(expr), *this));
- }
- };
- struct term_nonterm_xform_both
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return yap::make_terminal(n * user::number{2.0});
- }
- decltype(auto) operator()(term<user::number> const & expr)
- {
- return yap::make_terminal(
- ::boost::yap::value(expr) * user::number{2.0});
- }
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- user::number const & lhs,
- user::number const & rhs)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- yap::transform(::boost::yap::make_terminal(lhs), *this),
- yap::transform(::boost::yap::make_terminal(rhs), *this));
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- return yap::make_expression<yap::expr_kind::minus>(
- yap::transform(::boost::yap::left(expr), *this),
- yap::transform(::boost::yap::right(expr), *this));
- }
- };
- struct eval_term_nonterm_xform_tag
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return n * user::number{2.0};
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- Expr1 const & lhs,
- Expr2 const & rhs)
- {
- return boost::yap::transform(::boost::yap::as_expr(lhs), *this) -
- boost::yap::transform(::boost::yap::as_expr(rhs), *this);
- }
- };
- struct eval_term_nonterm_xform_expr
- {
- decltype(auto) operator()(term<user::number> const & expr)
- {
- return ::boost::yap::value(expr) * user::number{2.0};
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- return boost::yap::transform(::boost::yap::left(expr), *this) -
- boost::yap::transform(::boost::yap::right(expr), *this);
- }
- };
- struct eval_term_nonterm_xform_both
- {
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::terminal>, user::number const & n)
- {
- return n * user::number{2.0};
- }
- decltype(auto) operator()(term<user::number> const & expr)
- {
- return ::boost::yap::value(expr) * user::number{2.0};
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::plus>,
- Expr1 const & lhs,
- Expr2 const & rhs)
- {
- return boost::yap::transform(::boost::yap::as_expr(lhs), *this) -
- boost::yap::transform(::boost::yap::as_expr(rhs), *this);
- }
- template<typename Expr1, typename Expr2>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<Expr1, Expr2>> const & expr)
- {
- return boost::yap::transform(::boost::yap::left(expr), *this) -
- boost::yap::transform(::boost::yap::right(expr), *this);
- }
- };
- decltype(auto)
- naxpy_eager_nontemplate_xform(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<
- yap::expression<
- yap::expr_kind::multiplies,
- bh::tuple<
- ref<term<user::number> &>,
- ref<term<user::number> &>>>,
- ref<term<user::number> &>>> const & expr)
- {
- auto a = evaluate(expr.left().left());
- auto x = evaluate(expr.left().right());
- auto y = evaluate(expr.right());
- return yap::make_terminal(naxpy(a, x, y));
- }
- decltype(auto)
- naxpy_lazy_nontemplate_xform(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<
- yap::expression<
- yap::expr_kind::multiplies,
- bh::tuple<
- ref<term<user::number> &>,
- ref<term<user::number> &>>>,
- ref<term<user::number> &>>> const & expr)
- {
- decltype(auto) a = expr.left().left().value();
- decltype(auto) x = expr.left().right().value();
- decltype(auto) y = expr.right().value();
- return yap::make_terminal(naxpy)(a, x, y);
- }
- struct naxpy_xform
- {
- template<typename Expr1, typename Expr2, typename Expr3>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::plus,
- bh::tuple<
- yap::expression<
- yap::expr_kind::multiplies,
- bh::tuple<Expr1, Expr2>>,
- Expr3>> const & expr)
- {
- return yap::make_terminal(naxpy)(
- transform(expr.left().left(), naxpy_xform{}),
- transform(expr.left().right(), naxpy_xform{}),
- transform(expr.right(), naxpy_xform{}));
- }
- };
- // unary transforms
- struct disable_negate_xform_tag
- {
- auto
- operator()(yap::expr_tag<yap::expr_kind::negate>, user::number value)
- {
- return yap::make_terminal(std::move(value));
- }
- template<typename Expr>
- auto
- operator()(yap::expr_tag<yap::expr_kind::negate>, Expr const & expr)
- {
- return expr;
- }
- };
- struct disable_negate_xform_expr
- {
- template<typename Expr>
- decltype(auto) operator()(
- yap::expression<yap::expr_kind::negate, bh::tuple<Expr>> const &
- expr)
- {
- return ::boost::yap::value(expr);
- }
- };
- struct disable_negate_xform_both
- {
- decltype(auto)
- operator()(yap::expr_tag<yap::expr_kind::negate>, user::number value)
- {
- return yap::make_terminal(std::move(value));
- }
- template<typename Expr>
- decltype(auto)
- operator()(yap::expr_tag<yap::expr_kind::negate>, Expr const & expr)
- {
- return expr;
- }
- template<typename Expr>
- decltype(auto) operator()(
- yap::expression<yap::expr_kind::negate, bh::tuple<Expr>> const &
- expr)
- {
- throw std::logic_error("Oops! Picked the wrong overload!");
- return ::boost::yap::value(expr);
- }
- };
- // ternary transforms
- //[ tag_xform
- struct ternary_to_else_xform_tag
- {
- template<typename Expr>
- decltype(auto) operator()(
- boost::yap::expr_tag<yap::expr_kind::if_else>,
- Expr const & cond,
- user::number then,
- user::number else_)
- {
- return boost::yap::make_terminal(std::move(else_));
- }
- };
- //]
- //[ expr_xform
- struct ternary_to_else_xform_expr
- {
- template<typename Cond, typename Then, typename Else>
- decltype(auto)
- operator()(boost::yap::expression<
- boost::yap::expr_kind::if_else,
- boost::hana::tuple<Cond, Then, Else>> const & expr)
- {
- return ::boost::yap::else_(expr);
- }
- };
- //]
- struct ternary_to_else_xform_both
- {
- template<typename Expr>
- decltype(auto) operator()(
- yap::expr_tag<yap::expr_kind::if_else>,
- Expr const & cond,
- user::number then,
- user::number else_)
- {
- return yap::make_terminal(std::move(else_));
- }
- template<typename Cond, typename Then, typename Else>
- decltype(auto) operator()(yap::expression<
- yap::expr_kind::if_else,
- bh::tuple<Cond, Then, Else>> const & expr)
- {
- throw std::logic_error("Oops! Picked the wrong overload!");
- return ::boost::yap::else_(expr);
- }
- };
- }
- auto double_to_float(term<double> expr)
- {
- return term<float>{(float)expr.value()};
- }
- auto check_unique_ptrs_equal_7(term<std::unique_ptr<int>> && expr)
- {
- using namespace boost::hana::literals;
- BOOST_CHECK(*expr.elements[0_c] == 7);
- return std::move(expr);
- }
- int test_main(int, char * [])
- {
- {
- term<user::number> a{{1.0}};
- term<user::number> x{{42.0}};
- term<user::number> y{{3.0}};
- {
- auto expr = a;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 1);
- }
- {
- auto transformed_expr = transform(expr, user::empty_xform{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 1);
- }
- {
- auto transformed_expr = transform(expr, user::eval_xform_tag{});
- BOOST_CHECK(transformed_expr.value == 1);
- }
- {
- auto transformed_expr =
- transform(expr, user::eval_xform_expr{});
- BOOST_CHECK(transformed_expr.value == 1);
- }
- {
- auto transformed_expr =
- transform(expr, user::eval_xform_both{});
- BOOST_CHECK(transformed_expr.value == 1);
- }
- }
- {
- auto expr = x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::plus_to_minus_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39);
- }
- {
- auto transformed_expr =
- transform(expr, user::plus_to_minus_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39);
- }
- {
- auto transformed_expr =
- transform(expr, user::plus_to_minus_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39);
- }
- }
- {
- auto expr = x + user::number{3.0};
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- }
- {
- auto expr = x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 39 * 2);
- }
- }
- {
- auto expr = (x + y) + user::number{1.0};
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 46);
- }
- {
- // Differs from those below, because it matches terminals, not
- // expressions.
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 40 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 38 * 2);
- }
- {
- auto transformed_expr =
- transform(expr, user::term_nonterm_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 38 * 2);
- }
- }
- {
- auto expr = x + user::number{3.0};
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_tag{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_expr{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_both{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- }
- {
- auto expr = x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_tag{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_expr{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_both{});
- BOOST_CHECK(result.value == 39 * 2);
- }
- }
- {
- auto expr = (x + y) + user::number{1.0};
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 46);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_tag{});
- BOOST_CHECK(result.value == 38 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_expr{});
- BOOST_CHECK(result.value == 38 * 2);
- }
- {
- user::number result =
- transform(expr, user::eval_term_nonterm_xform_both{});
- BOOST_CHECK(result.value == 38 * 2);
- }
- }
- {
- auto expr = a * x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- auto transformed_expr =
- transform(expr, user::naxpy_eager_nontemplate_xform);
- {
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 55);
- }
- }
- {
- auto expr = a + (a * x + y);
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 46);
- }
- auto transformed_expr =
- transform(expr, user::naxpy_eager_nontemplate_xform);
- {
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 56);
- }
- }
- {
- auto expr = a * x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45);
- }
- auto transformed_expr =
- transform(expr, user::naxpy_lazy_nontemplate_xform);
- {
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 55);
- }
- }
- {
- auto expr = a + (a * x + y);
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 46);
- }
- auto transformed_expr =
- transform(expr, user::naxpy_lazy_nontemplate_xform);
- {
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 56);
- }
- }
- {
- auto expr = (a * x + y) * (a * x + y) + (a * x + y);
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 45 * 45 + 45);
- }
- auto transformed_expr = transform(expr, user::naxpy_xform{});
- {
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 55 * 55 + 55 + 10);
- }
- }
- }
- {
- term<double> unity{1.0};
- term<std::unique_ptr<int>> i{new int{7}};
- yap::expression<
- yap::expr_kind::plus,
- bh::tuple<ref<term<double> &>, term<std::unique_ptr<int>>>>
- expr_1 = unity + std::move(i);
- yap::expression<
- yap::expr_kind::plus,
- bh::tuple<
- ref<term<double> &>,
- yap::expression<
- yap::expr_kind::plus,
- bh::tuple<
- ref<term<double> &>,
- term<std::unique_ptr<int>>>>>>
- expr_2 = unity + std::move(expr_1);
- auto transformed_expr = transform(std::move(expr_2), double_to_float);
- transform(std::move(transformed_expr), check_unique_ptrs_equal_7);
- }
- {
- term<user::number> a{{1.0}};
- term<user::number> x{{42.0}};
- term<user::number> y{{3.0}};
- {
- auto expr = -x;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == -42);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 42);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 42);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 42);
- }
- }
- {
- auto expr = a * -x + y;
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == -39);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- }
- {
- auto expr = -(x + y);
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == -45);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- {
- auto transformed_expr =
- transform(expr, user::disable_negate_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 45);
- }
- }
- }
- {
- term<user::number> a{{1.0}};
- term<user::number> x{{42.0}};
- term<user::number> y{{3.0}};
- {
- auto expr = if_else(0 < a, x, y);
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 42);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 3);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 3);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 3);
- }
- }
- {
- auto expr = y * if_else(0 < a, x, y) + user::number{0.0};
- {
- user::number result = evaluate(expr);
- BOOST_CHECK(result.value == 126);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_tag{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 9);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_expr{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 9);
- }
- {
- auto transformed_expr =
- transform(expr, user::ternary_to_else_xform_both{});
- user::number result = evaluate(transformed_expr);
- BOOST_CHECK(result.value == 9);
- }
- }
- }
- return 0;
- }
|