On 10.05.2017 16:03, Biotronic wrote:


A few things here - functions.fn would not do what you want, and neither
would __traits(identifier).
functions.fn would treat "fn" like a part of name, not a string value,
so this will make the poor compiler barf.
__traits(identifier, fn) expects fn to be a symbol, while here it's a
string. In fact, it's exactly the string you want __traits to return.
Lastly, you'll still need a mixin, whether it's for __traits(identifier,
fn) or just fn - they're just strings. Something like this:

static foreach (fn; CFunctions!functions) {
    mixin("typeof(__traits(getMember, functions, fn))* "~fn~";");
}

Yes, this works and is a few times faster.
It's slightly faster when inlining the condition:

static foreach(fn;__traits(allMembers, functions)){
    static if (isFunction!(__traits(getMember, functions, fn)) &&
(functionLinkage!(__traits(getMember, functions, fn)) == "C" || functionLinkage!(__traits(getMember, functions, fn)) == "Windows")){
        mixin("typeof(functions."~fn~")* "~fn~";");
    }
}

With the DMD debug build, I measured the following times on my machine:

Baselines:

just imports:
0m0.318s

copy-pasted generated code after printing it with pragma(msg, ...):
0m0.341s

Compile-time code generation:

old version:
0m2.569s

static foreach, uninlined:
0m0.704s

static foreach inlined:
0m0.610s

Still not great, but a notable improvement.


isFunction and functionLinkage are slow, so I got rid of them (as well as the dependency on std.traits):

static foreach(fn;__traits(allMembers, functions)){
    static if(fn != "object" && fn != "llvm" && fn != "orEmpty"):
    mixin("typeof(functions."~fn~")* "~fn~";");
}

timing:
0m0.350s

(This is not perfect as you'll need to edit the list in case you are adding more non-c-function members to that module, but I guess it is a good trade-off.)



You can achieve essentially the same using a string mixin:

mixin({
    string r;
    foreach(fn;__traits(allMembers, functions))
        if(fn != "object" && fn != "llvm" && fn != "orEmpty")
            r~="typeof(functions."~fn~")* "~fn~";";
    return r;
}());

timing:
0m0.370s



In case the original semantics should be preserved, I think this is the best option:

mixin({
    string r;
    foreach(fn;CFunctions!functions)
        r~="typeof(functions."~fn~")* "~fn~";";
    return r;
}());

timing:
0m0.740s

Reply via email to