// 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 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; int test_main(int, char * []) { { term unity = {{1.0}}; using plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple &>, term>>; { plus_expr_type plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr))), ref &> &&>)); } { plus_expr_type plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), ref &> &>)); } { plus_expr_type const plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), ref &> const &>)); } { term const unity = {{1.0}}; using plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple const &>, term>>; { plus_expr_type plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr))), ref const &> &&>)); } { plus_expr_type plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), ref const &> &>)); } { plus_expr_type const plus_expr = unity + term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), ref const &> const &>)); } } { term unity = {{1.0}}; using plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple &>, term>>; plus_expr_type plus_expr = unity + term{{1}}; using plus_plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple, term>>; { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr_ref))), ref &> &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), ref &> &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref const plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), ref &> &>)); } } { term unity = {{1.0}}; using plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple &>, term>>; plus_expr_type const plus_expr = unity + term{{1}}; using plus_plus_expr_type = yap::expression< yap::expr_kind::plus, bh::tuple, term>>; { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr_ref))), ref &> const &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), ref &> const &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + term{{1}}; ref const plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), ref &> const &>)); } } } { user_term unity = {{1.0}}; using plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple &>, user_term>>; { plus_expr_type plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr))), user_ref &> &&>)); } { plus_expr_type plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), user_ref &> &>)); } { plus_expr_type const plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), user_ref &> const &>)); } { user_term const unity = {{1.0}}; using plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple const &>, user_term>>; { plus_expr_type plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr))), user_ref const &> &&>)); } { plus_expr_type plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr)), user_ref const &> &>)); } { plus_expr_type const plus_expr = unity + user_term{{1}}; BOOST_MPL_ASSERT( (std::is_same< decltype(yap::left(plus_expr)), user_ref const &> const &>)); } } { user_term unity = {{1.0}}; using plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple &>, user_term>>; plus_expr_type plus_expr = unity + user_term{{1}}; using plus_plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple, user_term>>; { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr_ref))), user_ref &> &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), user_ref &> &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref const plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), user_ref &> &>)); } } { user_term unity = {{1.0}}; using plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple &>, user_term>>; plus_expr_type const plus_expr = unity + user_term{{1}}; using plus_plus_expr_type = user_expr< yap::expr_kind::plus, bh::tuple, user_term>>; { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(std::move(plus_expr_ref))), user_ref &> const &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), user_ref &> const &>)); } { plus_plus_expr_type plus_plus_expr = plus_expr + user_term{{1}}; user_ref const plus_expr_ref = bh::front(plus_plus_expr.elements); BOOST_MPL_ASSERT((std::is_same< decltype(yap::left(plus_expr_ref)), user_ref &> const &>)); } } } return 0; }