On 2/8/2010 9:05 AM, David A. Greene wrote:
If I have a grammar like this:
typedef boost::proto::literalstd::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
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