Implementing interfaces using alias this
Biotronic via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jun 15 00:12:56 PDT 2017
On Wednesday, 14 June 2017 at 09:34:27 UTC, Balagopal Komarath
wrote:
> void main()
> {
> Test!Duck d;
> }
As has been pointed out at length by others here, it's simply not
how alias this is intended to work. I do see some arguments in
favor of working that way, but I'm not sure what's the right
solution.
Anyways, there is another solution - we could write a template
that does the conversion for us. There is std.typecons.Proxy,
which seems like a good fit, however it doesn't work quite the
way we want. Here however, is a solution that works for simple
examples. It might work for more complex examples as well, but I
simply haven't tested that:
template duckImpl(alias a, TI, Fns...) {
static if (Fns.length > 0) {
mixin duckImpl!(a, TI, Fns[1..$]);
alias thisFn = Fns[0];
enum string fnName = __traits(identifier, thisFn);
mixin("ReturnType!thisFn "~fnName~"(Parameters!thisFn
args) { return a."~fnName~"(args); }");
}
}
template duck(TI) if (is(TI == interface)) {
TI duck(T)(T t) {
import std.meta;
import std.traits;
template Functions(string s) {
alias Functions = MemberFunctionsTuple!(TI, s);
}
static class Result : TI {
private T payload;
this(T value) {
payload = value;
}
mixin duckImpl!(payload, TI, staticMap!(Functions,
__traits(allMembers, TI)));
}
return new Result(t);
}
}
interface I {
void bar();
}
struct S {
void bar() {
import std.stdio;
writeln("OHAI");
}
}
unittest {
I i = S().duck!I;
i.bar();
}
--
Biotronic
More information about the Digitalmars-d-learn
mailing list