summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/yap/test/call_expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/yap/test/call_expr.cpp')
-rw-r--r--src/boost/libs/yap/test/call_expr.cpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/boost/libs/yap/test/call_expr.cpp b/src/boost/libs/yap/test/call_expr.cpp
new file mode 100644
index 000000000..2e5c343f7
--- /dev/null
+++ b/src/boost/libs/yap/test/call_expr.cpp
@@ -0,0 +1,198 @@
+// 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>
+
+#include <sstream>
+
+
+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
+ {
+ explicit operator double() const { return value; }
+
+ double value;
+ };
+
+ number naxpy(number a, number x, number y)
+ {
+ return number{a.value * x.value + y.value + 10.0};
+ }
+
+ struct tag_type
+ {};
+
+ inline number tag_function(double a, double b) { return number{a + b}; }
+
+ struct eval_xform_tag
+ {
+ decltype(auto) operator()(
+ yap::expr_tag<yap::expr_kind::call>, tag_type, number a, double b)
+ {
+ return tag_function(a.value, b);
+ }
+
+ int operator()(
+ yap::expr_tag<yap::expr_kind::call>, tag_type, double a, double b)
+ {
+ return 42;
+ }
+
+ char const * operator()() { return "42"; }
+ };
+
+ struct empty_xform
+ {};
+
+ struct eval_xform_expr
+ {
+ decltype(auto) operator()(yap::expression<
+ yap::expr_kind::call,
+ bh::tuple<
+ ref<term<user::tag_type>>,
+ term<user::number>,
+ term<int>>> const & expr)
+ {
+ using namespace boost::hana::literals;
+ return tag_function(
+ (double)yap::value(expr.elements[1_c]).value,
+ (double)yap::value(expr.elements[2_c]));
+ }
+
+ decltype(auto) operator()(yap::expression<
+ yap::expr_kind::call,
+ bh::tuple<
+ ref<term<user::tag_type>>,
+ ref<term<user::number>>,
+ term<int>>> const & expr)
+ {
+ using namespace boost::hana::literals;
+ return tag_function(
+ (double)yap::value(expr.elements[1_c]).value,
+ (double)yap::value(expr.elements[2_c]));
+ }
+ };
+
+ struct eval_xform_both
+ {
+ decltype(auto) operator()(
+ yap::expr_tag<yap::expr_kind::call>,
+ tag_type,
+ user::number a,
+ double b)
+ {
+ return tag_function(a.value, b);
+ }
+
+ decltype(auto) operator()(yap::expression<
+ yap::expr_kind::call,
+ bh::tuple<
+ ref<term<user::tag_type>>,
+ term<user::number>,
+ term<int>>> const & expr)
+ {
+ using namespace boost::hana::literals;
+ throw std::logic_error("Oops! Picked the wrong overload!");
+ return tag_function(
+ (double)yap::value(expr.elements[1_c]).value,
+ (double)yap::value(expr.elements[2_c]));
+ }
+
+ decltype(auto) operator()(yap::expression<
+ yap::expr_kind::call,
+ bh::tuple<
+ ref<term<user::tag_type>>,
+ ref<term<user::number>>,
+ term<int>>> const & expr)
+ {
+ using namespace boost::hana::literals;
+ throw std::logic_error("Oops! Picked the wrong overload!");
+ return tag_function(
+ (double)yap::value(expr.elements[1_c]).value,
+ (double)yap::value(expr.elements[2_c]));
+ }
+ };
+}
+
+
+int test_main(int, char * [])
+{
+ {
+ using namespace boost::yap::literals;
+
+ {
+ auto plus = yap::make_terminal(user::tag_type{});
+ auto expr = plus(user::number{13}, 1);
+
+ {
+ transform(expr, user::empty_xform{});
+ }
+
+ {
+ user::number result = transform(expr, user::eval_xform_tag{});
+ BOOST_CHECK(result.value == 14);
+ }
+
+ {
+ user::number result = transform(expr, user::eval_xform_expr{});
+ BOOST_CHECK(result.value == 14);
+ }
+
+ {
+ user::number result = transform(expr, user::eval_xform_both{});
+ BOOST_CHECK(result.value == 14);
+ }
+ }
+
+ {
+ auto plus = yap::make_terminal(user::tag_type{});
+ auto thirteen = yap::make_terminal(user::number{13});
+ auto expr = plus(thirteen, 1);
+
+ {
+ user::number result = transform(expr, user::eval_xform_tag{});
+ BOOST_CHECK(result.value == 14);
+ }
+
+ {
+ user::number result = transform(expr, user::eval_xform_expr{});
+ BOOST_CHECK(result.value == 14);
+ }
+
+ {
+ user::number result = transform(expr, user::eval_xform_both{});
+ BOOST_CHECK(result.value == 14);
+ }
+ }
+
+ {
+ term<user::number> a{{1.0}};
+ term<user::number> x{{42.0}};
+ term<user::number> y{{3.0}};
+ auto n = yap::make_terminal(user::naxpy);
+
+ auto expr = n(a, x, y);
+ {
+ user::number result = evaluate(expr);
+ BOOST_CHECK(result.value == 55);
+ }
+ }
+ }
+
+ return 0;
+}