On 28/10/2011 07:30, Eric Niebler wrote:

Regardless, I'm convinced that a complete fix is possible, and I have it
mostly coded. It would require you (the user) to disable unary function
and assign in your domain via a grammar. But. It's expensive at compile
time, and everybody pays. I need to be convinced before I proceed.

I think it would also be fine to just document the issue, and let people special-case the generator if needed.

I wouldn't want all Proto-based code to become slower just because of this.

I would be quite interested to see what the fix is, though.


Your
example code was very contrived. (Certainly you don't need to ask a
Proto expression extension type whether it is a proto expression. The
answer will always be yes.)
So what is your realistic usage scenario?
What type categorization do you want to do on the extension type that
you can't do on the raw passed-in expression?

The call goes through generic components that don't necessarily deal with Proto expressions, but some of them may have special specializations for Proto expressions.

The categorization of non-raw expressions is of course richer, because each of those went through their own generators and attached special semantic information to each node type.

In NT2, we generate expressions that look like this

template<class Expr, class ResultType>
struct expression
  : proto::extends< expression<Expr, ResultType> >
{
    typedef typename extent_type<ResultType>::type extent_type;

    expression(Expr const& expr, extent_type const& extent_)
      : proto::extends< expression<Expr, ResultType> >(expr)
      , extent(extent_)
    {
    }

    extent_type const& extent() const { return extent; }

private:
    extent_type extent;
};

It not only wraps the naked Proto expression, but it also contains what the expression represents from a logical point of view (at some point we wanted to use domains for this, but it's just not practical). The expression also contains its logical size, which is computed at runtime by the generator, and is tightly coupled with what the expression represents.

So we categorize a naked tag(a0, a1) expression as
expr_< unspecified_<Expr>, domain, tag >

The same expression with the result type information of int32_t is
expr_< scalar_< int32_<Expr> >, domain, tag >

In certain situations, I ended up with a category of unspecified_<Expr> on some of my expression types because the categorization meta-function was instantiated on an incomplete type (the expression type for the terminal).
This way quite unexepcted and hard to debug.

Regardless, we like to have to ability to inject specializations *after* the expression type has been defined, which only works if instantiation is delayed until the function is actually called.
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto

Reply via email to