Eric Niebler wrote:
On 9/21/2010 9:51 AM, Eric Niebler wrote:
(proto lists members, see this thread for the rest of the discussion,
which has been happening on -users:
http://lists.boost.org/boost-users/2010/09/62747.php)
On 9/21/2010 9:19 AM, Roland Bock wrote:
On 09/21/2010 11:55 AM, Thomas Heller wrote:
snip
Solved the mistery. here is the code, explanation comes afterward:
snip
So, everything works as expected!
Thomas,
wow, this was driving me crazy, thanks for solving and explaining in all
the detail! :-)
I am still not sure if this isn't a conceptual problem, though:
The equation grammar is perfectly OK. But without or-ing it with the
addition grammar, the extension does not allow ANY valid expression to
be created. I wonder if that is a bug or a feature?
It's a feature. Imagine this grammar:
struct IntsOnlyPlease
: proto::or_
proto::terminalint
, proto::nary_exprproto::_, proto::varargIntsOnlyPlease
{};
And a integer terminal i in a domain that obeys this grammar. Now,
what should this do:
i + hello!;
You want it to fail because if it doesn't, you would create an
expression that doesn't conform to the domain's grammar. Right? Proto
accomplishes this by enforcing that all operands must conform to the
domain's grammar *and* the resulting expression must also conform.
Otherwise, the operator is disabled.
Anything else would be fundamentally broken.
This explanation is incomplete. Naturally, this operator+ would be
disabled anyway because the resulting expression doesn't conform to the
grammar regardless of whether the LHS and RHS conform. It's a question
of *when* the operator gets disabled. For a full explanation, see this
bug report:
https://svn.boost.org/trac/boost/ticket/2407
The answer is simple and logically consistent: make sure *every* valid
expression in your domain (including lone terminals) is accounted for by
your grammar.
Let me add something:
The more I thought i about the problem, the more i thought that this would
be a perfect use case for sub domains! So i tried to hack something
together:
#includeboost/proto/proto.hpp
using namespace boost;
typedef proto::terminalint::type const terminal;
struct equation;
struct addition:
proto::or_
proto::terminalproto::_,
proto::plusaddition, addition
{};
struct equation:
proto::or_
proto::equal_toaddition, addition
{};
templateclass Expr
struct extension;
struct my_domain:
proto::domain
proto::pod_generatorextension,
proto::or_equation, addition,
proto::default_domain
{};
templateclass Expr
struct lhs_extension;
struct my_lhs_domain:
proto::domain
proto::pod_generatorlhs_extension,
addition,
my_domain
{};
templateclass Expr
struct rhs_extension;
struct my_rhs_domain:
proto::domain
proto::pod_generatorrhs_extension,
addition,
my_domain
{};
templateclass Expr
struct extension
{
BOOST_PROTO_BASIC_EXTENDS(
Expr
, extensionExpr
, my_domain
)
void test() const
{}
};
templateclass Expr
struct lhs_extension
{
BOOST_PROTO_BASIC_EXTENDS(
Expr
, lhs_extensionExpr
, my_lhs_domain
)
};
templateclass Expr
struct rhs_extension
{
BOOST_PROTO_BASIC_EXTENDS(
Expr
, rhs_extensionExpr
, my_rhs_domain
)
};
template typename Grammar, typename Expr
void matches(Expr const expr)
{
expr.test();
std::cout std::boolalpha
proto::matchesExpr, Grammar::value \n;
}
int main()
{
lhs_extensionterminal const i = {};
rhs_extensionterminal const j = {};
/*matchesequation(i); // false
matchesequation(j); // false
matchesequation(i + i); // false
matchesequation(j + j); // false*/
//matchesequation(i + j); // compile error
//matchesequation(j + i); // compile error
matchesequation(i == j); // true
matchesequation(i == j + j); // true
matchesequation(i + i == j); // true
matchesequation(i + i == j + j); // true
}
This seems to be exactly what Roland wanted to achieve in the first place.
However, it looks like this design just overcomplicates stuff because we
have to specify the addition in our base domain anyway ...
Initially i was under the impression that this wasn't needed, but it seems
that proto cannot deduce something like:
lhs_expression OP rhs_expression results in expression
So the question is: is it reasonable to add features like that?
It seems valuable to me.
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto