On 5/3/15 11:54 AM, Andrei Alexandrescu wrote:
On 5/3/15 12:18 AM, Meta wrote:
On Sunday, 3 May 2015 at 05:49:52 UTC, Andrei Alexandrescu wrote:
On 5/2/15 10:00 PM, Meta wrote:
It seems like it'd be a lot cheaper and cleaner to just be able to
alias
the parent method.

Yeh, that's the first solution that comes to mind. alias doesn't work
here but of course we could change the language.

Also, it could probably be made a bit simpler with
opDispatch.

I'd have to see the code, but my intuition is that things could get
quite a bit more hairy.


Andrei

IMO, using __traits and opDispatch is a fair bit cleaner, and I prefer
the syntax of a mixin template to regular mixin.

http://dpaste.dzfl.pl/d60498246577

You're right, that is lovely! I've improved it as follows:

mixin template forwardToMember(alias member, methods...)
{
     import std.algorithm : among;
     import std.traits : ParameterTypeTuple;
     template opDispatch(string sym)
     if ((methods.length == 0 || sym.among(methods)))
     {
         auto ref opDispatch(
             ParameterTypeTuple!(__traits(getMember, member, sym)) args)
         {
             return __traits(getMember, member, sym)(args);
         }
     }
}

So now ref returns are preserved and the mixin is self-contained
(doesn't require imports from the outside).

Compared to my solution, this has the advantage that if the child
defines a method, it will take precedence over the formatted one. So
that allowed me to add a feature: if no methods are specified, all are
forwarded.

There are a couple of ways in which this could and should be improved,
most notably overloads control. Even as is it's pretty darn awesome,
Meta could you please make it into a pull request? I think it should go
in std.functional.

Take that back, the opDispatch-based solution has a fatal flaw: doesn't compose properly. For example, in std.allocator it's frequent that allocators stack on top of one another, so one forwards a method call to another one which in turn forwards to another.

With code generation this obviously works out of the box because the generated code is identical to what one would write by hand to achieve the same. But the opDispatch-based solution only works one level.


Andrei

Reply via email to