#include "stdafx.h" #include #include #include #include #include #include namespace boost { namespace proto { namespace detail { // Define has_which trait BOOST_MPL_HAS_XXX_TRAIT_DEF(which) BOOST_MPL_HAS_XXX_TRAIT_DEF(rule_name) template struct get_rule_name { typedef Grammar type; }; template struct get_rule_name< Grammar , typename boost::enable_if_c::value >::type > { typedef typename Grammar::rule_name type; }; template struct get_which : get_rule_name {}; // 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< mpl::and_< has_which > , mpl::not_ > >::value >::type > : get_which::which> {}; } template struct named_rule : Grammar { typedef Name rule_name; }; 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 {}; }; template struct is_callable > : mpl::true_ {}; }} namespace mpl = boost::mpl; namespace proto = boost::proto; struct nothing : proto::named_rule > {}; struct int_terminal : proto::named_rule > {}; struct char_terminal : proto::named_rule > {}; struct plus_int_int : proto::named_rule > {}; //struct my_grammar // : proto::or_< // int_terminal // , char_terminal // , plus_int_int // > //{}; struct my_grammar : proto::switch_ { template struct case_ : nothing {}; }; template<> struct my_grammar::case_ : proto::or_< int_terminal , char_terminal > {}; template<> struct my_grammar::case_ : //proto::or_< 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 << proto::algorithm()(a) << "\n"; // printing char proto::assert_matches_not >(a); //std::cout << proto::algorithm()(a) << "\n"; // precondition violation proto::assert_matches_not >(i); //std::cout << proto::algorithm()(i) << "\n"; // precondition violation std::cout << proto::algorithm()(j) << "\n"; // printing int std::cout << proto::algorithm()(j) << "\n"; // printing int std::cout << proto::algorithm()(a) << "\n"; // printing char std::cout << proto::algorithm()(i + i) << "\n"; // printing int + int }