Commit daa5a857 authored by Dominik Charousset's avatar Dominik Charousset

improved pattern matching unit test

parent 622f6303
...@@ -47,310 +47,340 @@ void foobar(index_token<Pos, Max>) { ...@@ -47,310 +47,340 @@ void foobar(index_token<Pos, Max>) {
foobar(index_token<Pos+1, Max>{}); foobar(index_token<Pos+1, Max>{});
} }
void test_simple_guards() {
auto ascending = [](int a, int b, int c) -> bool {
return a < b && b < c;
};
auto expr0_a = gcall(ascending, _x1, _x2, _x3);
CPPA_CHECK(ge_invoke(expr0_a, 1, 2, 3));
CPPA_CHECK(!ge_invoke(expr0_a, 3, 2, 1));
int ival0 = 2;
auto expr0_b = gcall(ascending, _x1, std::ref(ival0), _x2);
CPPA_CHECK(ge_invoke(expr0_b, 1, 3));
++ival0;
CPPA_CHECK(!ge_invoke(expr0_b, 1, 3));
auto expr0_c = gcall(ascending, 10, _x1, 30);
CPPA_CHECK(!ge_invoke(expr0_c, 10));
CPPA_CHECK(ge_invoke(expr0_c, 11));
// user-defined expressions using '+', '<', '%'
auto expr1 = _x1 + _x2;
auto expr2 = _x1 + _x2 < _x3;
auto expr3 = _x1 % _x2 == 0;
CPPA_CHECK_EQUAL((ge_invoke(expr1, 2, 3)), 5);
CPPA_CHECK(expr2(1, 2, 4));
CPPA_CHECK_EQUAL((ge_invoke(expr1, std::string{"1"}, std::string{"2"})), "12");
CPPA_CHECK(expr3(100, 2));
// user-defined expressions using '||'
auto expr4 = _x1 == "-h" || _x1 == "--help";
CPPA_CHECK(ge_invoke(expr4, string("-h")));
CPPA_CHECK(ge_invoke(expr4, string("--help")));
CPPA_CHECK(!ge_invoke(expr4, string("-g")));
}
int main() { void test_container_guards() {
CPPA_TEST(test_match); auto expr5 = _x1.starts_with("--");
/* test guard evaluation */ { CPPA_CHECK(ge_invoke(expr5, string("--help")));
// ascending values CPPA_CHECK(!ge_invoke(expr5, string("-help")));
auto ascending = [](int a, int b, int c) -> bool { // container search (x in y)
return a < b && b < c; vector<string> vec1{"hello", "world"};
}; auto expr6 = _x1.in(vec1);
auto expr0_a = gcall(ascending, _x1, _x2, _x3); CPPA_CHECK(ge_invoke(expr6, string("hello")));
CPPA_CHECK(ge_invoke(expr0_a, 1, 2, 3)); CPPA_CHECK(ge_invoke(expr6, string("world")));
CPPA_CHECK(!ge_invoke(expr0_a, 3, 2, 1)); CPPA_CHECK(!ge_invoke(expr6, string("hello world")));
int ival0 = 2; auto expr7 = _x1.in(std::ref(vec1));
auto expr0_b = gcall(ascending, _x1, std::ref(ival0), _x2); CPPA_CHECK(ge_invoke(expr7, string("hello")));
CPPA_CHECK(ge_invoke(expr0_b, 1, 3)); CPPA_CHECK(ge_invoke(expr7, string("world")));
++ival0; CPPA_CHECK(!ge_invoke(expr7, string("hello world")));
CPPA_CHECK(!ge_invoke(expr0_b, 1, 3)); vec1.emplace_back("hello world");
auto expr0_c = gcall(ascending, 10, _x1, 30); CPPA_CHECK(!ge_invoke(expr6, string("hello world")));
CPPA_CHECK(!ge_invoke(expr0_c, 10)); CPPA_CHECK(ge_invoke(expr7, string("hello world")));
CPPA_CHECK(ge_invoke(expr0_c, 11)); // container search (x in y) for initializer lists
// user-defined expressions using '+', '<', '%' auto expr11 = _x1.in({"one", "two"});
auto expr1 = _x1 + _x2; CPPA_CHECK(ge_invoke(expr11, string("one")));
auto expr2 = _x1 + _x2 < _x3; CPPA_CHECK(ge_invoke(expr11, string("two")));
auto expr3 = _x1 % _x2 == 0; CPPA_CHECK(!ge_invoke(expr11, string("three")));
CPPA_CHECK_EQUAL((ge_invoke(expr1, 2, 3)), 5); // container search (x not in y)
CPPA_CHECK(expr2(1, 2, 4)); auto expr12 = _x1.not_in({"hello", "world"});
CPPA_CHECK_EQUAL((ge_invoke(expr1, std::string{"1"}, std::string{"2"})), "12"); CPPA_CHECK(ge_invoke(expr12, string("foo")));
CPPA_CHECK(expr3(100, 2)); CPPA_CHECK(!ge_invoke(expr12, string("hello")));
// user-defined expressions using '||' // user-defined function to evaluate whether container is sorted
auto expr4 = _x1 == "-h" || _x1 == "--help"; std::vector<int> expr21_vec_a{1, 2, 3};
CPPA_CHECK(ge_invoke(expr4, string("-h"))); std::vector<int> expr21_vec_b{1, 0, 2};
CPPA_CHECK(ge_invoke(expr4, string("--help"))); auto expr21 = gcall(vec_sorted, _x1);
CPPA_CHECK(!ge_invoke(expr4, string("-g"))); CPPA_CHECK(ge_invoke(expr21, expr21_vec_a));
} CPPA_CHECK(!ge_invoke(expr21, expr21_vec_b));
/* guard expressions on containers */ { auto expr22 = _x1.empty() && _x2.not_empty();
auto expr5 = _x1.starts_with("--"); CPPA_CHECK(ge_invoke(expr22, std::string(""), std::string("abc")));
CPPA_CHECK(ge_invoke(expr5, string("--help"))); }
CPPA_CHECK(!ge_invoke(expr5, string("-help")));
// container search (x in y) void test_user_defined_expressions() {
vector<string> vec1{"hello", "world"}; int ival = 5;
auto expr6 = _x1.in(vec1); auto expr8 = _x1 == ival;
CPPA_CHECK(ge_invoke(expr6, string("hello"))); auto expr9 = _x1 == std::ref(ival);
CPPA_CHECK(ge_invoke(expr6, string("world"))); CPPA_CHECK(ge_invoke(expr8, 5));
CPPA_CHECK(!ge_invoke(expr6, string("hello world"))); CPPA_CHECK(ge_invoke(expr9, 5));
auto expr7 = _x1.in(std::ref(vec1)); ival = 10;
CPPA_CHECK(ge_invoke(expr7, string("hello"))); CPPA_CHECK(!ge_invoke(expr9, 5));
CPPA_CHECK(ge_invoke(expr7, string("world"))); CPPA_CHECK(ge_invoke(expr9, 10));
CPPA_CHECK(!ge_invoke(expr7, string("hello world"))); // user-defined expressions w/ wide range of operators
vec1.emplace_back("hello world"); auto expr13 = _x1 * _x2 < _x3 - _x4;
CPPA_CHECK(!ge_invoke(expr6, string("hello world"))); CPPA_CHECK(ge_invoke(expr13, 1, 1, 4, 2));
CPPA_CHECK(ge_invoke(expr7, string("hello world"))); auto expr14 = _x1 + _x2;
// container search (x in y) for initializer lists static_assert(std::is_same<decltype(ge_invoke(expr14, 1, 2)), int>::value,
auto expr11 = _x1.in({"one", "two"}); "wrong return type");
CPPA_CHECK(ge_invoke(expr11, string("one"))); CPPA_CHECK_EQUAL((ge_invoke(expr14, 2, 3)), 5);
CPPA_CHECK(ge_invoke(expr11, string("two"))); auto expr15 = _x1 + _x2 + _x3;
CPPA_CHECK(!ge_invoke(expr11, string("three"))); static_assert(std::is_same<decltype(ge_invoke(expr15, 1, 2, 3)), int>::value,
// container search (x not in y) "wrong return type");
auto expr12 = _x1.not_in({"hello", "world"}); CPPA_CHECK_EQUAL((ge_invoke(expr15, 7, 10, 25)), 42);
CPPA_CHECK(ge_invoke(expr12, string("foo"))); // user-defined operations on containers such as 'size' and 'front'
CPPA_CHECK(!ge_invoke(expr12, string("hello"))); std::string expr16_str;// = "expr16";
// user-defined function to evaluate whether container is sorted auto expr16_a = _x1.size();
std::vector<int> expr21_vec_a{1, 2, 3}; auto expr16_b = _x1.front() == 'e';
std::vector<int> expr21_vec_b{1, 0, 2}; CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), false);
auto expr21 = gcall(vec_sorted, _x1); CPPA_CHECK_EQUAL((ge_invoke(expr16_a, expr16_str)), 0);
CPPA_CHECK(ge_invoke(expr21, expr21_vec_a)); expr16_str = "expr16";
CPPA_CHECK(!ge_invoke(expr21, expr21_vec_b)); CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), true);
auto expr22 = _x1.empty() && _x2.not_empty(); CPPA_CHECK_EQUAL((ge_invoke(expr16_a, expr16_str)), expr16_str.size());
CPPA_CHECK(ge_invoke(expr22, std::string(""), std::string("abc"))); expr16_str.front() = '_';
} CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), false);
/* user-defined expressions */ { }
int ival = 5;
auto expr8 = _x1 == ival; void test_gref() {
auto expr9 = _x1 == std::ref(ival); int expr17_value = 42;
CPPA_CHECK(ge_invoke(expr8, 5)); auto expr17 = gref(expr17_value) == 42;
CPPA_CHECK(ge_invoke(expr9, 5)); CPPA_CHECK_EQUAL(ge_invoke(expr17), true);
ival = 10; expr17_value = 0;
CPPA_CHECK(!ge_invoke(expr9, 5)); CPPA_CHECK_EQUAL(ge_invoke(expr17), false);
CPPA_CHECK(ge_invoke(expr9, 10)); int expr18_value = 42;
// user-defined expressions w/ wide range of operators auto expr18_a = gref(expr18_value) == 42;
auto expr13 = _x1 * _x2 < _x3 - _x4; CPPA_CHECK_EQUAL(ge_invoke(expr18_a), true);
CPPA_CHECK(ge_invoke(expr13, 1, 1, 4, 2)); expr18_value = 0;
auto expr14 = _x1 + _x2; CPPA_CHECK_EQUAL(ge_invoke(expr18_a), false);
static_assert(std::is_same<decltype(ge_invoke(expr14, 1, 2)), int>::value, auto expr18_b = gref(expr18_value) == _x1;
"wrong return type"); auto expr18_c = std::ref(expr18_value) == _x1;
CPPA_CHECK_EQUAL((ge_invoke(expr14, 2, 3)), 5); CPPA_CHECK_EQUAL((ge_invoke(expr18_b, 0)), true);
auto expr15 = _x1 + _x2 + _x3; CPPA_CHECK_EQUAL((ge_invoke(expr18_c, 0)), true);
static_assert(std::is_same<decltype(ge_invoke(expr15, 1, 2, 3)), int>::value, bool enable_case1 = true;
"wrong return type"); auto expr19 = (
CPPA_CHECK_EQUAL((ge_invoke(expr15, 7, 10, 25)), 42); on<anything>().when(gref(enable_case1) == false) >> [] { return 1; },
// user-defined operations on containers such as 'size' and 'front' on<anything>() >> [] { return 2; }
std::string expr16_str;// = "expr16"; );
auto expr16_a = _x1.size(); any_tuple expr19_tup = make_cow_tuple("hello guard!");
auto expr16_b = _x1.front() == 'e'; CPPA_CHECK_EQUAL(expr19(expr19_tup), 2);
CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), false); partial_function expr20 = expr19;
CPPA_CHECK_EQUAL((ge_invoke(expr16_a, expr16_str)), 0); enable_case1 = false;
expr16_str = "expr16"; CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1));
CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), true); partial_function expr21 {
CPPA_CHECK_EQUAL((ge_invoke(expr16_a, expr16_str)), expr16_str.size()); on(atom("add"), arg_match) >> [](int a, int b) {
expr16_str.front() = '_'; return a + b;
CPPA_CHECK_EQUAL((ge_invoke(expr16_b, expr16_str)), false); }
} };
/* user-defined expressions using 'gref' */ { CPPA_CHECK(expr21(make_any_tuple(atom("add"), 1, 2)) == make_any_tuple(3));
int expr17_value = 42; CPPA_CHECK(!expr21(make_any_tuple(atom("sub"), 1, 2)));
auto expr17 = gref(expr17_value) == 42; }
CPPA_CHECK_EQUAL(ge_invoke(expr17), true);
expr17_value = 0; void test_match_function() {
CPPA_CHECK_EQUAL(ge_invoke(expr17), false); auto res0 = match(5) (
int expr18_value = 42; on_arg_match.when(_x1 < 6) >> [&](int i) {
auto expr18_a = gref(expr18_value) == 42; CPPA_CHECK_EQUAL(i, 5);
CPPA_CHECK_EQUAL(ge_invoke(expr18_a), true); }
expr18_value = 0; );
CPPA_CHECK_EQUAL(ge_invoke(expr18_a), false); CPPA_CHECK(res0);
auto expr18_b = gref(expr18_value) == _x1; auto res1 = match("value=42") (
auto expr18_c = std::ref(expr18_value) == _x1; on(kvp_split).when(_x1.not_empty()) >> [&](const vector<string>& vec) {
CPPA_CHECK_EQUAL((ge_invoke(expr18_b, 0)), true); CPPA_CHECK_EQUAL("value", vec[0]);
CPPA_CHECK_EQUAL((ge_invoke(expr18_c, 0)), true); CPPA_CHECK_EQUAL("42", vec[1]);
bool enable_case1 = true; }
auto expr19 = ( );
on<anything>().when(gref(enable_case1) == false) >> [] { return 1; }, CPPA_CHECK(res1);
on<anything>() >> [] { return 2; } auto res2 = match("42") (
); on(toint) >> [&](int i) {
any_tuple expr19_tup = make_cow_tuple("hello guard!"); CPPA_CHECK_EQUAL(42, i);
CPPA_CHECK_EQUAL(expr19(expr19_tup), 2); }
partial_function expr20 = expr19; );
enable_case1 = false; CPPA_CHECK(res2);
CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1)); auto res3 = match("abc") (
partial_function expr21 { on<string>().when(_x1 == "abc") >> [&] { }
on(atom("add"), arg_match) >> [](int a, int b) { );
return a + b; CPPA_CHECK(res3);
} CPPA_CHECK(res3.is<void>());
}; // match vectors
CPPA_CHECK(expr21(make_any_tuple(atom("add"), 1, 2)) == make_any_tuple(3)); auto res4 = match(std::vector<int>{1, 2, 3}) (
CPPA_CHECK(!expr21(make_any_tuple(atom("sub"), 1, 2))); on<int, int, int>().when( _x1 + _x2 + _x3 == 6
} && _x2(is_even)
/* test 'match' function */ { && _x3 % 2 == 1 ) >> [&] { }
auto res0 = match(5) ( );
on_arg_match.when(_x1 < 6) >> [&](int i) { CPPA_CHECK(res4);
CPPA_CHECK_EQUAL(i, 5); vector<string> vec{"a", "b", "c"};
} auto res5 = match(vec) (
); on("a", "b", val<string>) >> [](string&) -> string {
CPPA_CHECK(res0); return "C";
auto res1 = match("value=42") ( }
on(kvp_split).when(_x1.not_empty()) >> [&](const vector<string>& vec) { );
CPPA_CHECK_EQUAL("value", vec[0]); CPPA_CHECK_EQUAL(res5, "C");
CPPA_CHECK_EQUAL("42", vec[1]); }
}
); void test_match_each() {
CPPA_CHECK(res1); string sum;
auto res2 = match("42") ( vector<string> sum_args = { "-h", "--version", "-wtf" };
on(toint) >> [&](int i) { auto iter1 = match_each(begin(sum_args), end(sum_args)) (
CPPA_CHECK_EQUAL(42, i); on<string>().when(_x1.in({"-h", "--help"})) >> [&](const string& s) {
} sum += s;
); },
CPPA_CHECK(res2); on<string>().when(_x1 == "-v" || _x1 == "--version") >> [&](const string& s) {
auto res3 = match("abc") ( sum += s;
on<string>().when(_x1 == "abc") >> [&] { } },
); on<string>().when(_x1.starts_with("-")) >> [&](const string& str) {
CPPA_CHECK(res3); match_each(str.begin() + 1, str.end()) (
CPPA_CHECK(res3.is<void>()); on<char>().when(_x1.in({'w', 't', 'f'})) >> [&](char c) {
// match vectors sum += c;
auto res4 = match(std::vector<int>{1, 2, 3}) ( },
on<int, int, int>().when( _x1 + _x2 + _x3 == 6 on<char>() >> CPPA_FAILURE_CB("guard didn't match"),
&& _x2(is_even) others() >> CPPA_FAILURE_CB("unexpected match")
&& _x3 % 2 == 1 ) >> [&] { } );
); }
CPPA_CHECK(res4); );
vector<string> vec{"a", "b", "c"}; CPPA_CHECK(iter1 == end(sum_args));
auto res5 = match(vec) ( CPPA_CHECK_EQUAL(sum, "-h--versionwtf");
on("a", "b", val<string>) >> [](string&) -> string { auto iter2 = match_each(begin(sum_args), end(sum_args)) (
return "C"; on("-h") >> [] { }
} );
); CPPA_CHECK(iter2 == (begin(sum_args) + 1));
CPPA_CHECK_EQUAL(res5, "C"); }
}
/* test 'match_each' */ { void test_match_stream() {
string sum; bool success = false;
vector<string> sum_args = { "-h", "--version", "-wtf" }; istringstream iss("hello world");
auto iter1 = match_each(begin(sum_args), end(sum_args)) ( success = match_stream<string>(iss) (
on<string>().when(_x1.in({"-h", "--help"})) >> [&](const string& s) { on("hello", "world") >> CPPA_CHECKPOINT_CB()
sum += s; );
}, CPPA_CHECK_EQUAL(success, true);
on<string>().when(_x1 == "-v" || _x1 == "--version") >> [&](const string& s) { auto extract_name = [](const string& kvp) -> optional<string> {
sum += s; auto vec = split(kvp, '=');
}, if (vec.size() == 2 && vec.front() == "--name") return vec.back();
on<string>().when(_x1.starts_with("-")) >> [&](const string& str) { return none;
match_each(str.begin() + 1, str.end()) ( };
on<char>().when(_x1.in({'w', 't', 'f'})) >> [&](char c) { const char* svec[] = {"-n", "foo", "--name=bar", "-p", "2"};
sum += c; success = match_stream<string>(begin(svec), end(svec)) (
}, (on("-n", arg_match) || on(extract_name)) >> [](const string& name) -> bool {
on<char>() >> CPPA_FAILURE_CB("guard didn't match"), CPPA_CHECK(name == "foo" || name == "bar");
others() >> CPPA_FAILURE_CB("unexpected match") return name == "foo" || name == "bar";
); },
} on("-p", arg_match) >> [&](const string& port) -> match_hint {
); auto i = toint(port);
CPPA_CHECK(iter1 == end(sum_args)); if (i) {
CPPA_CHECK_EQUAL(sum, "-h--versionwtf"); CPPA_CHECK_EQUAL(*i, 2);
auto iter2 = match_each(begin(sum_args), end(sum_args)) ( return match_hint::handle;
on("-h") >> [] { }
);
CPPA_CHECK(iter2 == (begin(sum_args) + 1));
}
/* test match_stream */ {
bool success = false;
istringstream iss("hello world");
success = match_stream<string>(iss) (
on("hello", "world") >> CPPA_CHECKPOINT_CB()
);
CPPA_CHECK_EQUAL(success, true);
auto extract_name = [](const string& kvp) -> optional<string> {
auto vec = split(kvp, '=');
if (vec.size() == 2 && vec.front() == "--name") return vec.back();
return none;
};
const char* svec[] = {"-n", "foo", "--name=bar", "-p", "2"};
success = match_stream<string>(begin(svec), end(svec)) (
(on("-n", arg_match) || on(extract_name)) >> [](const string& name) -> bool {
CPPA_CHECK(name == "foo" || name == "bar");
return name == "foo" || name == "bar";
},
on("-p", arg_match) >> [&](const string& port) -> match_hint {
auto i = toint(port);
if (i) {
CPPA_CHECK_EQUAL(*i, 2);
return match_hint::handle;
}
else return match_hint::skip;
},
on_arg_match >> [](const string& arg) -> match_hint {
CPPA_FAILURE("unexpected string: " << arg);
return match_hint::skip;
} }
); else return match_hint::skip;
CPPA_CHECK_EQUAL(success, true); },
} on_arg_match >> [](const string& arg) -> match_hint {
// utility macro to identify invoked functors CPPA_FAILURE("unexpected string: " << arg);
return match_hint::skip;
}
);
CPPA_CHECK_EQUAL(success, true);
}
void test_behavior() {
std::string last_invoked_fun; std::string last_invoked_fun;
# define bhvr_check(pf, tup, expected_result, str) { \ # define bhvr_check(pf, tup, expected_result, str) { \
last_invoked_fun = ""; \ last_invoked_fun = ""; \
CPPA_CHECK_EQUAL(static_cast<bool>(pf(tup)), expected_result); \ CPPA_CHECK_EQUAL(static_cast<bool>(pf(tup)), expected_result); \
CPPA_CHECK_EQUAL(last_invoked_fun, str); \ CPPA_CHECK_EQUAL(last_invoked_fun, str); \
} }
/* test if match hints are evaluated properly */ { behavior bhvr1 {
behavior bhvr1 { on<int>() >> [&](int i) -> match_hint {
on<int>() >> [&](int i) -> match_hint { last_invoked_fun = "<int>@1";
last_invoked_fun = "<int>@1"; return (i == 42) ? match_hint::skip : match_hint::handle;
return (i == 42) ? match_hint::skip : match_hint::handle; },
}, on<float>() >> [&] {
on<float>() >> [&] { last_invoked_fun = "<float>@2";
last_invoked_fun = "<float>@2"; },
}, on<int>() >> [&] {
on<int>() >> [&] { last_invoked_fun = "<int>@3";
last_invoked_fun = "<int>@3"; },
}, others() >> [&] {
others() >> [&] { last_invoked_fun = "<*>@4";
last_invoked_fun = "<*>@4"; }
} };
}; bhvr_check(bhvr1, make_any_tuple(42), false, "<int>@1");
bhvr_check(bhvr1, make_any_tuple(42), false, "<int>@1"); bhvr_check(bhvr1, make_any_tuple(24), true, "<int>@1");
bhvr_check(bhvr1, make_any_tuple(24), true, "<int>@1"); bhvr_check(bhvr1, make_any_tuple(2.f), true, "<float>@2");
bhvr_check(bhvr1, make_any_tuple(2.f), true, "<float>@2"); bhvr_check(bhvr1, make_any_tuple(""), true, "<*>@4");
bhvr_check(bhvr1, make_any_tuple(""), true, "<*>@4"); partial_function pf0 {
} on<int, int>() >> [&] { last_invoked_fun = "<int, int>@1"; },
/* test or_else concatenation */ { on<float>() >> [&] { last_invoked_fun = "<float>@2"; }
partial_function pf0 { };
on<int, int>() >> [&] { last_invoked_fun = "<int, int>@1"; }, auto pf1 = pf0.or_else (
on<float>() >> [&] { last_invoked_fun = "<float>@2"; } on<int, int>() >> [&] { last_invoked_fun = "<int, int>@3"; },
}; on<string>() >> [&] { last_invoked_fun = "<string>@4"; }
auto pf1 = pf0.or_else ( );
on<int, int>() >> [&] { last_invoked_fun = "<int, int>@3"; }, bhvr_check(pf0, make_any_tuple(1, 2), true, "<int, int>@1");
on<string>() >> [&] { last_invoked_fun = "<string>@4"; } bhvr_check(pf1, make_any_tuple(1, 2), true, "<int, int>@1");
); bhvr_check(pf0, make_any_tuple("hi"), false, "");
bhvr_check(pf0, make_any_tuple(1, 2), true, "<int, int>@1"); bhvr_check(pf1, make_any_tuple("hi"), true, "<string>@4");
bhvr_check(pf1, make_any_tuple(1, 2), true, "<int, int>@1"); partial_function pf11 {
bhvr_check(pf0, make_any_tuple("hi"), false, ""); on_arg_match >> [&](int) { last_invoked_fun = "<int>@1"; }
bhvr_check(pf1, make_any_tuple("hi"), true, "<string>@4"); };
partial_function pf11 { partial_function pf12 {
on_arg_match >> [&](int) { last_invoked_fun = "<int>@1"; } on_arg_match >> [&](int) { last_invoked_fun = "<int>@2"; },
}; on_arg_match >> [&](float) { last_invoked_fun = "<float>@2"; }
partial_function pf12 { };
on_arg_match >> [&](int) { last_invoked_fun = "<int>@2"; }, auto pf13 = pf11.or_else(pf12);
on_arg_match >> [&](float) { last_invoked_fun = "<float>@2"; } bhvr_check(pf13, make_any_tuple(42), true, "<int>@1");
}; bhvr_check(pf13, make_any_tuple(42.24f), true, "<float>@2");
auto pf13 = pf11.or_else(pf12); }
bhvr_check(pf13, make_any_tuple(42), true, "<int>@1");
bhvr_check(pf13, make_any_tuple(42.24f), true, "<float>@2"); void test_pattern_matching() {
} auto res = match(make_any_tuple(42, 4.2f)) (
/* check result of pattern matching */ { on(42, arg_match) >> [](double d) {
auto res = match(make_any_tuple(42, 4.2f)) ( return d;
on(42, arg_match) >> [](double d) { },
return d; on(42, arg_match) >> [](float f) {
}, return f;
on(42, arg_match) >> [](float f) { }
return f; );
} CPPA_CHECK(res && res.is<float>() && get<float>(res) == 4.2f);
); auto res2 = match(make_any_tuple(23, 4.2f)) (
CPPA_CHECK(res && res.is<float>() && get<float>(res) == 4.2f); on(42, arg_match) >> [](double d) {
auto res2 = match(make_any_tuple(23, 4.2f)) ( return d;
on(42, arg_match) >> [](double d) { },
return d; on(42, arg_match) >> [](float f) {
}, return f;
on(42, arg_match) >> [](float f) { }
return f; );
} CPPA_CHECK(!res2);
); }
CPPA_CHECK(!res2);
} void test_wildcards() {
auto expr = (
on(any_vals, arg_match) >> [](int a, int b) {
cout << "invoked: " << a << ", " << b << endl;
}
);
CPPA_CHECK(expr(make_any_tuple(1, 2, 3)));
CPPA_CHECK(expr(make_any_tuple(1, 2)));
partial_function pf = expr;
CPPA_CHECK(pf(make_any_tuple(1, 2)));
CPPA_CHECK(pf(make_any_tuple(1, 2, 3)));
behavior bhvr = expr;
CPPA_CHECK(bhvr(make_any_tuple(1, 2)));
CPPA_CHECK(bhvr(make_any_tuple(1, 2, 3)));
}
int main() {
CPPA_TEST(test_match);
test_wildcards();
test_simple_guards();
test_container_guards();
test_user_defined_expressions();
test_gref();
test_match_function();
test_match_each();
test_match_stream();
test_behavior();
test_pattern_matching();
return CPPA_TEST_RESULT(); return CPPA_TEST_RESULT();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment