From 09057b991207debe3d12cf430ef1486ebc456019 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Thu, 1 Dec 2016 19:38:43 -0600 Subject: [PATCH] Split call_expr test into disjoint parts, which reveals that the test was masking an error. --- test/CMakeLists.txt | 1 + test/call_expr.cpp | 225 +++++------------------------------ test/call_expr_implicit.cpp | 229 ++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 197 deletions(-) create mode 100644 test/call_expr_implicit.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 40d938a..1825d2d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,6 +30,7 @@ add_test_executable(user_expression_transform_2) add_test_executable(user_expression_transform_3) add_test_executable(placeholder_eval) add_test_executable(call_expr) +add_test_executable(call_expr_implicit) add_test_executable(reference_returns) add_test_executable(depth_stress_test_left) add_test_executable(depth_stress_test_right) diff --git a/test/call_expr.cpp b/test/call_expr.cpp index 37b1152..8acc945 100644 --- a/test/call_expr.cpp +++ b/test/call_expr.cpp @@ -1,4 +1,3 @@ -#define BOOST_YAP_CONVERSION_OPERATOR_TEMPLATE #include #include @@ -131,17 +130,6 @@ namespace user { } }; - template - inline auto eval_call (tag_type, T && ...t) - { - if constexpr (sizeof...(T) == 2u) { - return tag_function((double)t...); - } else { - assert(!"Unhandled case in eval_call()"); - return; - } - } - } @@ -150,211 +138,54 @@ TEST(call_expr, test_call_expr) using namespace boost::yap::literals; { - yap::expression< - yap::expr_kind::call, - bh::tuple< - yap::placeholder<1>, - yap::placeholder<2>, - yap::placeholder<3> - > - > expr = 1_p(2_p, 3_p); + auto plus = yap::make_terminal(user::tag_type{}); + auto expr = plus(user::number{13}, 1); { - auto min = [] (int a, int b) { return a < b ? a : b; }; - int result = evaluate(expr, min, 3, 7); - EXPECT_EQ(result, 3); + auto transformed_expr = transform(expr, user::empty_xform{}); + EXPECT_TRUE((std::is_same{})); } { - int result = evaluate(expr, &user::max, 3, 7); - EXPECT_EQ(result, 7); + EXPECT_EQ("TODO: Broken test!", nullptr); +#if 0 + user::number result = transform(expr, user::eval_xform_tag{}); + EXPECT_EQ(result.value, 14); +#endif } { - int result = evaluate(expr, user::max, 3, 7); - EXPECT_EQ(result, 7); + user::number result = transform(expr, user::eval_xform_expr{}); + EXPECT_EQ(result.value, 14); + } + + { + user::number result = transform(expr, user::eval_xform_both{}); + EXPECT_EQ(result.value, 14); } } { - auto min_lambda = [] (int a, int b) { return a < b ? a : b; }; + auto plus = yap::make_terminal(user::tag_type{}); + auto thirteen = yap::make_terminal(user::number{13}); + auto expr = plus(thirteen, 1); { - auto min = yap::make_terminal(min_lambda); - auto expr = min(1_p, 2_p); - - { - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } + EXPECT_EQ("TODO: Broken test!", nullptr); +#if 0 + user::number result = transform(expr, user::eval_xform_tag{}); + EXPECT_EQ(result.value, 14); +#endif } { - term min = {{min_lambda}}; - auto expr = min(1_p, 2_p); - - { - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } - } - } - - { - struct min_function_object_t - { - auto operator() (int a, int b) const { return a < b ? a : b; } - }; - - min_function_object_t min_function_object; - - { - term min = yap::make_terminal(min_function_object); - auto expr = min(1_p, 2_p); - - { - using namespace boost::hana::literals; - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } + user::number result = transform(expr, user::eval_xform_expr{}); + EXPECT_EQ(result.value, 14); } { - term min = {{min_function_object}}; - auto expr = min(1_p, 2_p); - - { - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } - } - - { - auto min = yap::make_terminal(min_function_object_t{}); - auto expr = min(1_p, 2_p); - - { - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } - } - - { - term min = {{min_function_object_t{}}}; - auto expr = min(1_p, 2_p); - - { - int result = evaluate(expr, 3, 7); - EXPECT_EQ(result, 3); - } - } - - } - - { - auto min_lambda = [] (int a, int b) { return a < b ? a : b; }; - - { - auto min = yap::make_terminal(min_lambda); - auto expr = min(0, 1); - - { - int result = evaluate(expr); - EXPECT_EQ(result, 0); - } - } - - { - term min = {{min_lambda}}; - yap::expression< - yap::expr_kind::call, - bh::tuple< - yap::expression_ref& >, - term, - term - > - > expr = min(0, 1); - - { - int result = evaluate(expr); - EXPECT_EQ(result, 0); - } - } - } - - { - { - auto plus = yap::make_terminal(user::tag_type{}); - auto expr = plus(user::number{13}, 1); - - { - user::number result = expr; - EXPECT_EQ(result.value, 14); - } - } - - { - term plus = {{user::tag_type{}}}; - yap::expression< - yap::expr_kind::call, - bh::tuple< - yap::expression_ref& >, - term, - term - > - > expr = plus(0, 1); - - { - user::number result = expr; - EXPECT_EQ(result.value, 1); - } - } - - { - auto plus = yap::make_terminal(user::tag_type{}); - auto expr = plus(user::number{13}, 1); - - { - auto transformed_expr = transform(expr, user::empty_xform{}); - user::number result = transformed_expr; - EXPECT_EQ(result.value, 14); - } - - { - user::number result = transform(expr, user::eval_xform_tag{}); - EXPECT_EQ(result.value, 14); - } - - { - user::number result = transform(expr, user::eval_xform_expr{}); - EXPECT_EQ(result.value, 14); - } - - { - user::number result = transform(expr, user::eval_xform_both{}); - EXPECT_EQ(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{}); - EXPECT_EQ(result.value, 14); - } - - { - user::number result = transform(expr, user::eval_xform_expr{}); - EXPECT_EQ(result.value, 14); - } - - { - user::number result = transform(expr, user::eval_xform_both{}); - EXPECT_EQ(result.value, 14); - } + user::number result = transform(expr, user::eval_xform_both{}); + EXPECT_EQ(result.value, 14); } } diff --git a/test/call_expr_implicit.cpp b/test/call_expr_implicit.cpp new file mode 100644 index 0000000..4146f1d --- /dev/null +++ b/test/call_expr_implicit.cpp @@ -0,0 +1,229 @@ +#define BOOST_YAP_CONVERSION_OPERATOR_TEMPLATE +#include + +#include + +#include + + +template +using term = boost::yap::terminal; + +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}; } + + inline auto max (int a, int b) + { return a < b ? b : a; }; + + inline number tag_function (double a, double b) + { return number{a + b}; } + + struct tag_type {}; + + template + inline auto eval_call (tag_type, T && ...t) + { + if constexpr (sizeof...(T) == 2u) { + return tag_function((double)t...); + } else { + assert(!"Unhandled case in eval_call()"); + return; + } + } + +} + + +TEST(call_expr, test_call_expr) +{ + using namespace boost::yap::literals; + + { + yap::expression< + yap::expr_kind::call, + bh::tuple< + yap::placeholder<1>, + yap::placeholder<2>, + yap::placeholder<3> + > + > expr = 1_p(2_p, 3_p); + + { + auto min = [] (int a, int b) { return a < b ? a : b; }; + int result = evaluate(expr, min, 3, 7); + EXPECT_EQ(result, 3); + } + + { + int result = evaluate(expr, &user::max, 3, 7); + EXPECT_EQ(result, 7); + } + + { + int result = evaluate(expr, user::max, 3, 7); + EXPECT_EQ(result, 7); + } + } + + { + auto min_lambda = [] (int a, int b) { return a < b ? a : b; }; + + { + auto min = yap::make_terminal(min_lambda); + auto expr = min(1_p, 2_p); + + { + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + + { + term min = {{min_lambda}}; + auto expr = min(1_p, 2_p); + + { + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + } + + { + struct min_function_object_t + { + auto operator() (int a, int b) const { return a < b ? a : b; } + }; + + min_function_object_t min_function_object; + + { + term min = yap::make_terminal(min_function_object); + auto expr = min(1_p, 2_p); + + { + using namespace boost::hana::literals; + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + + { + term min = {{min_function_object}}; + auto expr = min(1_p, 2_p); + + { + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + + { + auto min = yap::make_terminal(min_function_object_t{}); + auto expr = min(1_p, 2_p); + + { + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + + { + term min = {{min_function_object_t{}}}; + auto expr = min(1_p, 2_p); + + { + int result = evaluate(expr, 3, 7); + EXPECT_EQ(result, 3); + } + } + + } + + { + auto min_lambda = [] (int a, int b) { return a < b ? a : b; }; + + { + auto min = yap::make_terminal(min_lambda); + auto expr = min(0, 1); + + { + int result = evaluate(expr); + EXPECT_EQ(result, 0); + } + } + + { + term min = {{min_lambda}}; + yap::expression< + yap::expr_kind::call, + bh::tuple< + yap::expression_ref& >, + term, + term + > + > expr = min(0, 1); + + { + int result = evaluate(expr); + EXPECT_EQ(result, 0); + } + } + } + + { + { + auto plus = yap::make_terminal(user::tag_type{}); + auto expr = plus(user::number{13}, 1); + + { + user::number result = expr; + EXPECT_EQ(result.value, 14); + } + } + + { + term plus = {{user::tag_type{}}}; + yap::expression< + yap::expr_kind::call, + bh::tuple< + yap::expression_ref& >, + term, + term + > + > expr = plus(0, 1); + + { + user::number result = expr; + EXPECT_EQ(result.value, 1); + } + } + + } + + { + term a{{1.0}}; + term x{{42.0}}; + term y{{3.0}}; + auto n = yap::make_terminal(user::naxpy); + + auto expr = n(a, x, y); + { + user::number result = evaluate(expr); + EXPECT_EQ(result.value, 55); + } + } +}