Skip to content

Instantly share code, notes, and snippets.

@PetarKirov
Last active September 2, 2020 17:35
Show Gist options
  • Save PetarKirov/f725d1f7e22d7a31860898d2d37489d0 to your computer and use it in GitHub Desktop.
Save PetarKirov/f725d1f7e22d7a31860898d2d37489d0 to your computer and use it in GitHub Desktop.
Attaching UDAs to enum members in dlang
void main()
{
import std.stdio : writeln;
import std.traits : EnumMembers;
foreach (SymbolKind kind; [EnumMembers!SymbolKind])
kind.enumUdatoString.writeln;
`----------------------`.writeln;
string example = enumToString!SymbolKind;
writeln(example);
}
string enumUdatoString(E)(E value)
{
final switch (value)
{
static foreach (memberName; __traits(allMembers, E))
case mixin(E, '.', memberName):
return __traits(getAttributes, mixin(E, '.', memberName))[0];
}
}
enum SymbolKind
{
@("No symbol")
S_YYEMPTY = -2,
@(`"end of file"`)
S_YYEOF = 0,
@("error")
S_YYerror = 1,
@(`"invalid token"`)
S_YYUNDEF = 2,
@("=")
S_EQ = 3,
/+ ... +/
@("input")
S_input = 14,
@("line")
S_line = 15,
@("exp")
S_exp = 16,
}
string enumToString(E)()
{
import std.format;
string result;
alias BaseType = BaseEnumType!E;
static foreach (memberName; __traits(allMembers, E))
{{
alias member = mixin(E.stringof, ".", memberName);
alias udaSeq = __traits(getAttributes, member);
enum BaseType value = member;
enum description = udaSeq[0]; // FIXME: Here we assume that the first UDA is a the description string
result ~= "%s.%-9s = %-2s | %s\n".format(E.stringof, memberName, value, description);
}}
return result;
}
template BaseEnumType(E)
{
static if (is(E Base == enum))
alias BaseEnumType = Base;
else
static assert (0, "`E` is not an enum type");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment