Call function by its string name
Kenji Hara
k.hara.pg at gmail.com
Sat Oct 19 10:58:24 PDT 2013
A quick sample code to make a table of function pointers at compiler time.
module test;
import std.typetuple;
// calculate compile-time tuple of functions declared in 'mod' module
template getFunctions(alias mod)
{
template filterPred(string name)
{
// if the 'name' is really a function, returns true
enum filterPred = is(typeof(__traits(getMember, mod, name)) ==
function);
}
alias names = Filter!(filterPred, __traits(allMembers, mod));
template mapPred(string name)
{
alias mapPred = TypeTuple!(__traits(getMember, mod, name))[0];
}
alias getFunctions = staticMap!(mapPred, names);
}
// gather functions from modname, then make function pointer table
auto makeTable(alias modname)()
{
mixin("import "~modname~";");
mixin("alias funcs = getFunctions!("~modname~");");
immutable(void*)[] make(size_t n)()
{
static if (n < funcs.length)
return cast(immutable(void*))&(funcs[n]) ~ make!(n+1)();
else
return [];
}
immutable(void*)[funcs.length] tbl = make!0()[0 .. funcs.length];
return tbl;
}
// make function pointer table
immutable func_table = makeTable!"decl"();
void main()
{
(cast(void function())func_table[0])();
assert((cast(int function(int))func_table[1])(10) == 20);
}
module decl;
void fn() { import std.stdio; writeln("call fn"); }
int bar(int n) { import std.stdio; writeln("call bar"); return n * 2; }
----
$ dmd decl.d -run test
call fn
call bar
There's no runtime cost to make function pointer table.
Kenji Hara
2013/10/20 aldanor <i.s.smirnov at gmail.com>
>
> Yes, in my case it's very specific, let's say I receive a string "fun" and
> want to call do_fun(args) or Obj.do_fun(args). Thanks, I'll try looking
> into compile-time reflection.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20131020/adbb5745/attachment-0001.html>
More information about the Digitalmars-d
mailing list