#define BOOST_PROTO17_CONVERSION_OPERATOR_TEMPLATE #include "expression.hpp" #include template using term = boost::proto17::terminal; namespace bp17 = boost::proto17; namespace bh = boost::hana; namespace user { struct number { explicit operator double () const { return value; } friend number operator+ (number lhs, number rhs) { return number{lhs.value + rhs.value}; } double value; }; template constexpr auto eval_expression_as ( E const & expr, boost::hana::basic_type, T &&... args) { return static_cast( bp17::detail::default_eval_expr(expr, static_cast(args)...) ); } } TEST(user_eval_expression_as, test_user_eval_expression_as) { term unity{{1.0}}; double d_ = 42.0; term i{{d_}}; bp17::expression< bp17::expr_kind::plus, bh::tuple< bp17::expression_ref& >, term > > expr = unity + std::move(i); bp17::expression< bp17::expr_kind::plus, bh::tuple< bp17::expression_ref& >, bp17::expression< bp17::expr_kind::plus, bh::tuple< bp17::expression_ref& >, term > > > > unevaluated_expr = unity + std::move(expr); { user::number result = unity; EXPECT_EQ(result.value, 1); } { user::number result = expr; EXPECT_EQ(result.value, 43); } { user::number result = unevaluated_expr; EXPECT_EQ(result.value, 44); } { user::number result = evaluate(unity, 5, 6, 7); EXPECT_EQ(result.value, 1); } { double result = (double)evaluate(expr); EXPECT_EQ(result, 43); } { double result = (double)evaluate(unevaluated_expr, std::string("15")); EXPECT_EQ(result, 44); } { user::number result = bp17::evaluate_as(unity, 5, 6, 7); EXPECT_EQ(result.value, 1); } { user::number result = bp17::evaluate_as(expr); EXPECT_EQ(result.value, 43); } { user::number result = bp17::evaluate_as(unevaluated_expr, std::string("15")); EXPECT_EQ(result.value, 44); } }