#include #include #include namespace sql { struct query_ {}; typedef boost::proto::terminal::type QueryTerminal; QueryTerminal query = {}; struct select_ {}; typedef boost::proto::terminal::type SelectTerminal; SelectTerminal select = {}; struct where_ {}; typedef boost::proto::terminal::type WhereTerminal; WhereTerminal where = {}; struct order_by_ {}; typedef boost::proto::terminal::type OrderByTerminal; OrderByTerminal order_by = {}; struct limit_ {}; typedef boost::proto::terminal::type LimitTerminal; LimitTerminal limit = {}; struct OrderByGrammar; struct WhereGrammar; struct SelectGrammar; struct LimitGrammar: boost::proto::or_ < boost::proto::shift_left, OrderByGrammar > {}; struct OrderByGrammar: boost::proto::or_ < boost::proto::shift_left, WhereGrammar > {}; struct WhereGrammar: boost::proto::or_ < boost::proto::shift_left, SelectGrammar > {}; struct SelectGrammar: boost::proto::or_ < SelectTerminal > {}; } template void limit_eval(const Expr&) { BOOST_MPL_ASSERT(( boost::proto::matches< Expr, sql::LimitGrammar > )); } template void not_limit_eval(const Expr&) { BOOST_MPL_ASSERT(( boost::mpl::not_ > )); } int main() { limit_eval(sql::select << sql::order_by << sql::limit); limit_eval(sql::select << sql::order_by << sql::limit); limit_eval(sql::select << sql::where); limit_eval(sql::select << sql::order_by); limit_eval(sql::select << sql::limit); limit_eval(sql::select << sql::where << sql::limit); not_limit_eval(sql::select << sql::limit << sql::order_by); }