Good Day D Community,
I just did a little test run of using core.reflect
on the enum TOK
within DMD.
(Which was successful yay. ;))
Then I compared it against the __traits
version.
import dmd.tokens;
version(UseCoreReflect)
{
import core.reflect.reflect;
static immutable e = cast(immutable EnumDeclaration) nodeFromName("TOK");
pragma(msg,
() {
import std.conv;
string result;
result ~= "enum " ~ e.name ~ " {\n";
foreach(m;e.members)
{
IntegerLiteral l = cast(IntegerLiteral) m.value;
result ~= " " ~ m.name ~ " = " ~ to!string(l.value) ~ ",\n";
}
result ~= "}";
return result;
} ()
);
}
version(UseTraits)
{
enum members = __traits(allMembers, TOK);
pragma(msg,
() {
import std.conv;
string result;
result ~= "enum " ~ TOK.stringof ~ "{\n";
static foreach(m;members)
{
result ~= " " ~ m ~ " = " ~ to!string(cast(int)mixin("TOK." ~ m)) ~ ",\n";
}
result ~= "}";
return result;
} ()
);
}
In terms of code I do prefer the core.traits
version because that one does not use a mixin and doesn't force you to do a static foreach
also it can trivially be factored into a runtime function which doesn't stress CTFE out. Whereas the __traits
version cannot trivially be factored to do most of the work at runtime.
I guess you could build a string[]
with member names and index that runtime but it's not as trivial as just calling the function at runtime with an EnumDeclaration
object generated at compile time.
Please let me know what you think.
P.S. In terms of performance the core.reflect
version is faster by 2% on average which doesn't matter in the slightest using such tiny test-cases.