Resolve function pointers using UDA during CT

Philippe Sigaud philippe.sigaud at gmail.com
Sun Feb 9 05:48:13 PST 2014


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)


More information about the Digitalmars-d-learn mailing list