Alias template param - Undefined Identifier

Chris Williams yoreanon-chrisw at yahoo.co.jp
Fri Mar 21 20:28:12 PDT 2014


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();
}


More information about the Digitalmars-d-learn mailing list