Resolve function pointers using UDA during CT

Tim Volckmann timvol at ymail.com
Sun Feb 23 01:40:45 PST 2014


On Sunday, 9 February 2014 at 13:48:36 UTC, Philippe Sigaud wrote:
> On Sun, Feb 9, 2014 at 2:10 PM, Tim Volckmann 
> <timvol at ymail.com> wrote:
>
>> That's also possible... but how can I find all functions with 
>> MyUDA?
>
> Here is a possibility:
>
> ***********
> module myUDAFunctions;
>
> import std.stdio;
>
> struct MyUDA
> {
>    string Name;
> }
>
> @MyUDA("Function1")
> string myFirstUdaFunction(string myString)
> {
>     writeln("MyFirstUDAFunction called with ", myString);
>     return "first";
> }
>
> @MyUDA("Function2")
> string mySecondUdaFunction(string myString)
> {
>     writeln("MySecondUDAFunction called with ", myString);
>     return "second";
> }
> **************
> module myMain;
>
> import std.stdio;
> import std.traits;
> import std.typetuple;
>
> import myUDAFunctions;
>
> private
> {
>    string function(string)[string] callbacks;
> }
>
> static this()
> {
>     // Getting all symbols from module myUDAFunctions
>     // Beware: we get strings, not aliases.
>     // Hence the mixin() afterwards to inject them in our code
>     foreach(symbol; __traits(allMembers, myUDAFunctions))
>         static if (isCallable!(mixin(symbol))) // Found some 
> callable
>         {
>             // Extracting attributes
>             foreach(attribute; __traits(getAttributes, 
> mixin(symbol)))
>             {
>                 // Finding those which are MyUDA's
>                 static if (is(typeof(attribute) == MyUDA))
>                     callbacks[attribute.Name] = mixin("&" ~ 
> symbol);
>             }
>         }
> }
>
> void main(string[] args)
> {
>     writeln("Callbacks: ", callbacks);
>     writeln("Args: ", args);
>     if (args[1] in callbacks)
>     {
>         writeln(args[1], " known in callbacks");
>         callbacks[args[1]]("myString");
>     }
> }
> ************
>
> it's a be cumbersome, you should extract the pattern and put it 
> in a
> template with MyUDA and the module name as parameters.
>
> Note the ` callbacks[attribute.Name] = mixin("&" ~ symbol);` 
> line:
>
> since `symbol` is a string, we have to mix it in the code.
> And since `functionName` is seen as a call to `functionName` 
> and not
> as the function itself, I had to put an `&` before it
> (the generated code is `callbakcs["Func1"] = &Fun1;`, for 
> example)

Works as expected, thanks Jakob and Philippe!


More information about the Digitalmars-d-learn mailing list