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