On Wednesday, 19 March 2014 at 00:07:04 UTC, Chris Williams wrote:
...probably something along the lines of making all of my functions a static function in a struct, which I then pass into a template which processes UDAs to generate functions at the top with the same names as the originals in the struct, which call the struct variants. It's also a longer to write and debug.

Here's a simple (unsafe and inflexible) implementation, should anyone want to build it out into something that can accept multiple arguments and return types.


import std.stdio;

string wrap(string wrapperName, string structName, string innerName) { return "void " ~ innerName ~ "() {" ~wrapperName~ "( &"~structName~"."~innerName~" );}";
}

template decorate(T) {
    template ForeachMember(Mbr...) {
static if (__traits(getAttributes, __traits(getMember, T, Mbr[0])).length > 0) {
            static if (Mbr.length > 1) {
                enum ForeachMember =
                    wrap(
__traits(identifier, __traits(getAttributes, __traits(getMember, T, Mbr[0]))[0]),
                        __traits(identifier, T),
                        Mbr[0]
                    )
                    ~ ForeachMember!(Mbr[1..$])
                ;
            }
            else {
                enum ForeachMember =
                    wrap(
__traits(identifier, __traits(getAttributes, __traits(getMember, T, Mbr[0]))[0]),
                        __traits(identifier, T),
                        Mbr[0]
                    )
                ;
            }
        }
        else {
            static if (Mbr.length > 1) {
enum ForeachMember = "" ~ ForeachMember!(Mbr[1..$]);
            }
            else {
                enum ForeachMember = "";
            }
        }
    }

    enum decorate = ForeachMember!(__traits(allMembers, T));
}

void BeforeAfter(void function() fun) {
    writeln("Before");
    write("\t"); fun();
    writeln("After");
}

void Llama(void function() fun) {
    writeln("Llama");
    write("\t"); fun();
    writeln("Llama");
}

struct Foo {
    @BeforeAfter
    static void hello() {
        writeln("Hello");
    }

    @Llama
    static void and() {
        writeln("and");
    }

    @BeforeAfter
    static void goodbye() {
        writeln("Goodbye");
    }
}

mixin(decorate!(Foo));

void main() {
   hello();
   and();
   goodbye();
}

Reply via email to