
On 2/8/2010 9:05 AM, David A. Greene wrote:
If I have a grammar like this:
typedef boost::proto::literal<std::string>::type StringTerminal;
typedef or_< StringTerminal, ...
Rule;
and I do this:
checkMatch<Rule>(boost::proto::lit(std::string("str"))); checkMatch<Rule>(std::string("str")); checkMatch<Rule>("str");
where checkMatch is a wrapper around matches<>, the first line is the only one that passes. This is presumably because the string needs to be "protoized" and to match StringTerminal it has to be cast to std::string explicitly. <snip>
proto::convertible_to is your friend here, as well as proto::as_expr. See below: #include <boost/proto/proto.hpp> namespace proto = boost::proto; struct Rule : proto::terminal< proto::convertible_to< std::string > > {}; template< typename Rule, typename T > void checkMatch( T const & t ) { typedef typename proto::result_of::as_expr< T >::type expr_type; BOOST_MPL_ASSERT(( proto::matches< expr_type, Rule > )); } int main() { checkMatch<Rule>(proto::lit(std::string("str"))); checkMatch<Rule>(std::string("str")); checkMatch<Rule>("str"); } As its name implies, proto::convertible_to matches terminal types that have an implicit conversion. proto::result_of::as_expr converts non-proto types to proto::terminals and leaves proto expression types alone. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com