#include #include #include #include namespace mpl = boost::mpl; namespace proto = boost::proto; namespace detail { // Define has_which trait BOOST_MPL_HAS_XXX_TRAIT_DEF(which) template struct get_which { typedef Grammar type; }; // Only proto::or_, proto::switch_ and proto::if_ have branches and // need to define a which member. template struct get_which< typename Expr , typename Grammar , typename boost::enable_if_c >::value>::type > { typedef typename proto::matches::which type; }; } template struct algorithm : proto::transform > { typedef Grammar proto_grammar; // Cheating! relies on Proto implementation details (the // presence of a nested which typedef in proto::matches). template struct impl : Actions::template when::type, Actions>::template impl {}; }; namespace boost { namespace proto { template struct is_callable > : mpl::true_ {}; }} struct int_terminal : proto::terminal {}; struct char_terminal : proto::terminal {}; struct plus_int_int : proto::plus {}; struct my_grammar : proto::or_< int_terminal , char_terminal , plus_int_int > {}; struct my_actions; struct print : proto::callable { typedef std::string result_type; result_type operator()(int) const { return "int"; } result_type operator()(char) const { return "char"; } template result_type operator()(T1 res, T2 t2) const { res += " + "; res += t2; return res; } }; struct my_actions { template struct when; template struct when : proto::call {}; template struct when : proto::call {}; template struct when : proto::call< print( proto::call(proto::_left)> , proto::call(proto::_right)> ) > {}; }; int main() { proto::literal i(8), j(9); proto::literal a('a'), b('b'); std::cout << algorithm()(a) << "\n"; // printing char proto::assert_matches_not >(a); //std::cout << algorithm()(a) << "\n"; // precondition violation proto::assert_matches_not >(i); //std::cout << algorithm()(i) << "\n"; // precondition violation std::cout << algorithm()(j) << "\n"; // printing int std::cout << algorithm()(j) << "\n"; // printing int std::cout << algorithm()(a) << "\n"; // printing char std::cout << algorithm()(i + i) << "\n"; // printing int + int }