On Thursday, 31 August 2017 at 15:48:12 UTC, EntangledQuanta wrote:
On Thursday, 31 August 2017 at 10:34:14 UTC, Kagamin wrote:
On Thursday, 31 August 2017 at 00:49:22 UTC, EntangledQuanta wrote:
I've already implemented a half ass library solution.

It can be improved alot.

Then, by all means, genius!

Enjoy!

mixin template virtualTemplates(alias parent, alias fn, T...) {
    import std.meta;
    alias name = Alias!(__traits(identifier, fn)[1..$]);
    mixin virtualTemplates!(parent, name, fn, T);
}

mixin template virtualTemplates(alias parent, string name, alias fn, T...) {
    import std.traits;
    static if (is(parent == interface)) {
        template templateOverloads(string name : name) {
            alias templateOverloads = T;
        }
        alias Types = T;
    } else {
        alias Types = templateOverloads!name;
    }

mixin(virtualTemplatesImpl(name, Types.length, is(parent == class)));
}

string virtualTemplatesImpl(string name, int n, bool implement) {
    import std.format;
    string result;
    foreach (i; 0..n) {
auto body = implement ? format(" { return fn!(Types[%s])(args); }", i) : ";"; result ~= format("ReturnType!(fn!(Types[%s])) %s(Parameters!(fn!(Types[%s])) args)%s\n", i, name, i, body);
    }
    return result;
}

interface I {
    void _Go(T)(T s);
    void _Leave(T)(T s);
    mixin virtualTemplates!(I, _Go, int, short, float, double);
mixin virtualTemplates!(I, "Abscond", _Leave, int, short, float, double);
}

class C : I {
    void _Go(T)(T s) { }
    void _Leave(T)(T s) { }
    mixin virtualTemplates!(C, _Go);
    mixin virtualTemplates!(C, "Abscond", _Leave);
}

unittest {
    I c = new C();

    c.Go(3.2);
    c.Abscond(3.4f);
}

Does not support multiple template parameters, or template value parameters. Use at own risk for any and all purposes.

Reply via email to