// 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 #include #include #include #include template using term = boost::yap::terminal; template using ref = boost::yap::expression_ref; namespace yap = boost::yap; namespace bh = boost::hana; template struct user_expr { static boost::yap::expr_kind const kind = Kind; Tuple elements; }; BOOST_YAP_USER_BINARY_OPERATOR(plus, user_expr, user_expr) template using user_term = boost::yap::terminal; template using user_ref = boost::yap::expression_ref; struct thing {}; std::string fix_tti(std::string s) { // msvc: remove struct/class prefixes static const std::regex estruct("(struct|class) "); s = std::regex_replace(s, estruct, ""); // gcc/clang: strip integral literals suffixes static const std::regex eint("(\\d)u?l{0,2}"); s = std::regex_replace(s, eint, "$1"); return s; } int test_main(int, char * []) { { BOOST_CHECK( yap::op_string(yap::expr_kind::terminal) == std::string("term")); BOOST_CHECK( yap::op_string(yap::expr_kind::unary_plus) == std::string("+")); BOOST_CHECK(yap::op_string(yap::expr_kind::negate) == std::string("-")); BOOST_CHECK( yap::op_string(yap::expr_kind::dereference) == std::string("*")); BOOST_CHECK( yap::op_string(yap::expr_kind::complement) == std::string("~")); BOOST_CHECK( yap::op_string(yap::expr_kind::address_of) == std::string("&")); BOOST_CHECK( yap::op_string(yap::expr_kind::logical_not) == std::string("!")); BOOST_CHECK(yap::op_string(yap::expr_kind::pre_inc) == std::string("++")); BOOST_CHECK(yap::op_string(yap::expr_kind::pre_dec) == std::string("--")); BOOST_CHECK( yap::op_string(yap::expr_kind::post_inc) == std::string("++(int)")); BOOST_CHECK( yap::op_string(yap::expr_kind::post_dec) == std::string("--(int)")); BOOST_CHECK( yap::op_string(yap::expr_kind::shift_left) == std::string("<<")); BOOST_CHECK( yap::op_string(yap::expr_kind::shift_right) == std::string(">>")); BOOST_CHECK( yap::op_string(yap::expr_kind::multiplies) == std::string("*")); BOOST_CHECK(yap::op_string(yap::expr_kind::divides) == std::string("/")); BOOST_CHECK(yap::op_string(yap::expr_kind::modulus) == std::string("%")); BOOST_CHECK( yap::op_string(yap::expr_kind::multiplies_assign) == std::string("*=")); BOOST_CHECK( yap::op_string(yap::expr_kind::divides_assign) == std::string("/=")); BOOST_CHECK( yap::op_string(yap::expr_kind::modulus_assign) == std::string("%=")); BOOST_CHECK( yap::op_string(yap::expr_kind::plus_assign) == std::string("+=")); BOOST_CHECK( yap::op_string(yap::expr_kind::minus_assign) == std::string("-=")); BOOST_CHECK( yap::op_string(yap::expr_kind::bitwise_and_assign) == std::string("&=")); BOOST_CHECK( yap::op_string(yap::expr_kind::bitwise_or_assign) == std::string("|=")); BOOST_CHECK( yap::op_string(yap::expr_kind::bitwise_xor_assign) == std::string("^=")); BOOST_CHECK( yap::op_string(yap::expr_kind::subscript) == std::string("[]")); BOOST_CHECK(yap::op_string(yap::expr_kind::if_else) == std::string("?:")); BOOST_CHECK(yap::op_string(yap::expr_kind::call) == std::string("()")); BOOST_CHECK( yap::op_string(yap::expr_kind(-1)) == std::string("** ERROR: UNKNOWN OPERATOR! **")); } { user_term unity{1.0}; int i_ = 42; user_term i{std::move(i_)}; user_expr< yap::expr_kind::plus, bh::tuple &>, user_term>> expr = unity + std::move(i); user_expr< yap::expr_kind::plus, bh::tuple< user_ref &>, user_expr< yap::expr_kind::plus, bh::tuple< user_ref &>, user_term>>>> unevaluated_expr = unity + std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & expr<+> term[=1] & term[=42] )"); } user_term a_thing{bh::make_tuple(thing{})}; { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } user_term const const_unity{1.0}; user_expr< yap::expr_kind::plus, bh::tuple< user_ref &>, user_ref const &>>> nonconst_plus_const = unity + const_unity; { std::ostringstream oss; yap::print(oss, nonconst_plus_const); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & term[=1] const & )"); } auto nonconst_plus_nonconst_plus_const = unity + nonconst_plus_const; { std::ostringstream oss; yap::print(oss, nonconst_plus_nonconst_plus_const); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & expr<+> & term[=1] & term[=1] const & )"); } auto const const_nonconst_plus_const = nonconst_plus_const; auto nonconst_plus_nonconst_plus_const_2 = unity + const_nonconst_plus_const; { std::ostringstream oss; yap::print(oss, nonconst_plus_nonconst_plus_const_2); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & expr<+> const & term[=1] & term[=1] const & )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::plus, bh::tuple &>, term>> expr = unity + std::move(i); yap::expression< yap::expr_kind::plus, bh::tuple< ref &>, yap::expression< yap::expr_kind::plus, bh::tuple &>, term>>>> unevaluated_expr = unity + std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & expr<+> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::plus, bh::tuple &>, ref const &>>> nonconst_plus_const = unity + const_unity; { std::ostringstream oss; yap::print(oss, nonconst_plus_const); BOOST_CHECK(oss.str() == R"(expr<+> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::minus, bh::tuple &>, term>> expr = unity - std::move(i); yap::expression< yap::expr_kind::minus, bh::tuple< ref &>, yap::expression< yap::expr_kind::minus, bh::tuple &>, term>>>> unevaluated_expr = unity - std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<-> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<-> term[=1] & expr<-> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::minus, bh::tuple &>, ref const &>>> nonconst_minus_const = unity - const_unity; { std::ostringstream oss; yap::print(oss, nonconst_minus_const); BOOST_CHECK(oss.str() == R"(expr<-> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::less, bh::tuple &>, term>> expr = unity < std::move(i); yap::expression< yap::expr_kind::less, bh::tuple< ref &>, yap::expression< yap::expr_kind::less, bh::tuple &>, term>>>> unevaluated_expr = unity < std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<<> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<<> term[=1] & expr<<> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::less, bh::tuple &>, ref const &>>> nonconst_less_const = unity < const_unity; { std::ostringstream oss; yap::print(oss, nonconst_less_const); BOOST_CHECK(oss.str() == R"(expr<<> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::greater, bh::tuple &>, term>> expr = unity > std::move(i); yap::expression< yap::expr_kind::greater, bh::tuple< ref &>, yap::expression< yap::expr_kind::greater, bh::tuple &>, term>>>> unevaluated_expr = unity > std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<>> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<>> term[=1] & expr<>> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::greater, bh::tuple &>, ref const &>>> nonconst_greater_const = unity > const_unity; { std::ostringstream oss; yap::print(oss, nonconst_greater_const); BOOST_CHECK(oss.str() == R"(expr<>> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::less_equal, bh::tuple &>, term>> expr = unity <= std::move(i); yap::expression< yap::expr_kind::less_equal, bh::tuple< ref &>, yap::expression< yap::expr_kind::less_equal, bh::tuple &>, term>>>> unevaluated_expr = unity <= std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<<=> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<<=> term[=1] & expr<<=> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::less_equal, bh::tuple &>, ref const &>>> nonconst_less_equal_const = unity <= const_unity; { std::ostringstream oss; yap::print(oss, nonconst_less_equal_const); BOOST_CHECK(oss.str() == R"(expr<<=> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::greater_equal, bh::tuple &>, term>> expr = unity >= std::move(i); yap::expression< yap::expr_kind::greater_equal, bh::tuple< ref &>, yap::expression< yap::expr_kind::greater_equal, bh::tuple &>, term>>>> unevaluated_expr = unity >= std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<>=> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<>=> term[=1] & expr<>=> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::greater_equal, bh::tuple &>, ref const &>>> nonconst_greater_equal_const = unity >= const_unity; { std::ostringstream oss; yap::print(oss, nonconst_greater_equal_const); BOOST_CHECK(oss.str() == R"(expr<>=> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::equal_to, bh::tuple &>, term>> expr = unity == std::move(i); yap::expression< yap::expr_kind::equal_to, bh::tuple< ref &>, yap::expression< yap::expr_kind::equal_to, bh::tuple &>, term>>>> unevaluated_expr = unity == std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<==> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<==> term[=1] & expr<==> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::equal_to, bh::tuple &>, ref const &>>> nonconst_equal_to_const = unity == const_unity; { std::ostringstream oss; yap::print(oss, nonconst_equal_to_const); BOOST_CHECK(oss.str() == R"(expr<==> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::not_equal_to, bh::tuple &>, term>> expr = unity != std::move(i); yap::expression< yap::expr_kind::not_equal_to, bh::tuple< ref &>, yap::expression< yap::expr_kind::not_equal_to, bh::tuple &>, term>>>> unevaluated_expr = unity != std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr term[=1] & expr term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::not_equal_to, bh::tuple &>, ref const &>>> nonconst_not_equal_to_const = unity != const_unity; { std::ostringstream oss; yap::print(oss, nonconst_not_equal_to_const); BOOST_CHECK(oss.str() == R"(expr term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::logical_or, bh::tuple &>, term>> expr = unity || std::move(i); yap::expression< yap::expr_kind::logical_or, bh::tuple< ref &>, yap::expression< yap::expr_kind::logical_or, bh::tuple &>, term>>>> unevaluated_expr = unity || std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<||> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<||> term[=1] & expr<||> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::logical_or, bh::tuple &>, ref const &>>> nonconst_logical_or_const = unity || const_unity; { std::ostringstream oss; yap::print(oss, nonconst_logical_or_const); BOOST_CHECK(oss.str() == R"(expr<||> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::logical_and, bh::tuple &>, term>> expr = unity && std::move(i); yap::expression< yap::expr_kind::logical_and, bh::tuple< ref &>, yap::expression< yap::expr_kind::logical_and, bh::tuple &>, term>>>> unevaluated_expr = unity && std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<&&> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<&&> term[=1] & expr<&&> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::logical_and, bh::tuple &>, ref const &>>> nonconst_logical_and_const = unity && const_unity; { std::ostringstream oss; yap::print(oss, nonconst_logical_and_const); BOOST_CHECK(oss.str() == R"(expr<&&> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::bitwise_and, bh::tuple &>, term>> expr = unity & std::move(i); yap::expression< yap::expr_kind::bitwise_and, bh::tuple< ref &>, yap::expression< yap::expr_kind::bitwise_and, bh::tuple &>, term>>>> unevaluated_expr = unity & std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<&> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<&> term[=1] & expr<&> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::bitwise_and, bh::tuple &>, ref const &>>> nonconst_bitwise_and_const = unity & const_unity; { std::ostringstream oss; yap::print(oss, nonconst_bitwise_and_const); BOOST_CHECK(oss.str() == R"(expr<&> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::bitwise_or, bh::tuple &>, term>> expr = unity | std::move(i); yap::expression< yap::expr_kind::bitwise_or, bh::tuple< ref &>, yap::expression< yap::expr_kind::bitwise_or, bh::tuple &>, term>>>> unevaluated_expr = unity | std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<|> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<|> term[=1] & expr<|> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::bitwise_or, bh::tuple &>, ref const &>>> nonconst_bitwise_or_const = unity | const_unity; { std::ostringstream oss; yap::print(oss, nonconst_bitwise_or_const); BOOST_CHECK(oss.str() == R"(expr<|> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::bitwise_xor, bh::tuple &>, term>> expr = unity ^ std::move(i); yap::expression< yap::expr_kind::bitwise_xor, bh::tuple< ref &>, yap::expression< yap::expr_kind::bitwise_xor, bh::tuple &>, term>>>> unevaluated_expr = unity ^ std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<^> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<^> term[=1] & expr<^> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::bitwise_xor, bh::tuple &>, ref const &>>> nonconst_bitwise_xor_const = unity ^ const_unity; { std::ostringstream oss; yap::print(oss, nonconst_bitwise_xor_const); BOOST_CHECK(oss.str() == R"(expr<^> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::comma, bh::tuple &>, term>> expr = (unity, std::move(i)); yap::expression< yap::expr_kind::comma, bh::tuple< ref &>, yap::expression< yap::expr_kind::comma, bh::tuple &>, term>>>> unevaluated_expr = (unity, std::move(expr)); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<,> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<,> term[=1] & expr<,> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::comma, bh::tuple &>, ref const &>>> nonconst_comma_const = (unity, const_unity); { std::ostringstream oss; yap::print(oss, nonconst_comma_const); BOOST_CHECK(oss.str() == R"(expr<,> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::mem_ptr, bh::tuple &>, term>> expr = unity->*std::move(i); yap::expression< yap::expr_kind::mem_ptr, bh::tuple< ref &>, yap::expression< yap::expr_kind::mem_ptr, bh::tuple &>, term>>>> unevaluated_expr = unity->*std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<->*> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<->*> term[=1] & expr<->*> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::mem_ptr, bh::tuple &>, ref const &>>> nonconst_mem_ptr_const = unity->*const_unity; { std::ostringstream oss; yap::print(oss, nonconst_mem_ptr_const); BOOST_CHECK(oss.str() == R"(expr<->*> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::assign, bh::tuple &>, term>> expr = unity = std::move(i); yap::expression< yap::expr_kind::assign, bh::tuple< ref &>, yap::expression< yap::expr_kind::assign, bh::tuple &>, term>>>> unevaluated_expr = unity = std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<=> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<=> term[=1] & expr<=> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::shift_left_assign, bh::tuple &>, term>> expr = unity <<= std::move(i); yap::expression< yap::expr_kind::shift_left_assign, bh::tuple< ref &>, yap::expression< yap::expr_kind::shift_left_assign, bh::tuple &>, term>>>> unevaluated_expr = unity <<= std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<<<=> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<<<=> term[=1] & expr<<<=> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::shift_left_assign, bh::tuple &>, ref const &>>> nonconst_shift_left_assign_const = unity <<= const_unity; { std::ostringstream oss; yap::print(oss, nonconst_shift_left_assign_const); BOOST_CHECK(oss.str() == R"(expr<<<=> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } { term unity{1.0}; int i_ = 42; term i{std::move(i_)}; yap::expression< yap::expr_kind::shift_right_assign, bh::tuple &>, term>> expr = unity >>= std::move(i); yap::expression< yap::expr_kind::shift_right_assign, bh::tuple< ref &>, yap::expression< yap::expr_kind::shift_right_assign, bh::tuple &>, term>>>> unevaluated_expr = unity >>= std::move(expr); { std::ostringstream oss; yap::print(oss, unity); BOOST_CHECK(oss.str() == R"(term[=1] )"); } { std::ostringstream oss; yap::print(oss, expr); BOOST_CHECK(oss.str() == R"(expr<>>=> term[=1] & term[=42] )"); } { std::ostringstream oss; yap::print(oss, unevaluated_expr); BOOST_CHECK(oss.str() == R"(expr<>>=> term[=1] & expr<>>=> term[=1] & term[=42] )"); } term a_thing(thing{}); { std::ostringstream oss; yap::print(oss, a_thing); BOOST_CHECK(fix_tti(oss.str()) == R"(term[=<>] )"); } term const const_unity{1.0}; yap::expression< yap::expr_kind::shift_right_assign, bh::tuple &>, ref const &>>> nonconst_shift_right_assign_const = unity >>= const_unity; { std::ostringstream oss; yap::print(oss, nonconst_shift_right_assign_const); BOOST_CHECK(oss.str() == R"(expr<>>=> term[=1] & term[=1] const & )"); } { using namespace yap::literals; std::ostringstream oss; yap::print(oss, 1_p); BOOST_CHECK(fix_tti(oss.str()) == R"(term>[=1] )"); } } return 0; }