[Semi-OT] to!string(enumType)

ag0aep6g via Digitalmars-d digitalmars-d at puremagic.com
Thu May 18 16:15:46 PDT 2017


On 05/19/2017 12:31 AM, Stefan Koch wrote:
> string enumToString(E)(E v)
> {
>      static assert(is(E == enum), "emumToString is only meant for enums");
>      mixin ({
>      string result = "final switch(v) {\n";
>      foreach(m;[__traits(allMembers, E)])
>      {
>          result ~= "\tcase E." ~ m ~ " :\n"
>              ~ "\t\treturn \"" ~ m ~ "\";\n"
>              ~ "\tbreak;\n";
>      }
>      return result ~ "}";
>      } ());
> }

I'm sure that can be de-uglified a fair bit without hurting performance.

1) "final switch(v) {" and the closing brace can be moved out of the 
string. This should be completely free.

2) No need for `break` after `return`. Also free.

3) With a static foreach over `__traits(allMembers, E)` you can get rid 
of the function literal. Doesn't seem to affect performance much if at all.

So far:

----
string enumToString(E)(E v)
{
     static assert(is(E == enum),
         "emumToString is only meant for enums");
     final switch (v)
     {
         foreach(m; __traits(allMembers, E))
         {
             mixin("case E." ~ m ~ ": return \"" ~ m ~ "\";");
         }
     }
}
----

4) If EnumMembers is an option, you can get rid of the string mixin 
altogether:

----
string enumToString(E)(E v)
{
     import std.meta: AliasSeq;
     import std.traits: EnumMembers;
     static assert(is(E == enum),
         "emumToString is only meant for enums");
     alias memberNames = AliasSeq!(__traits(allMembers, E));
     final switch(v)
     {
         foreach(i, m; EnumMembers!E)
         {
             case m: return memberNames[i];
         }
     }
}
----

That takes a bit longer. May just be the time it takes to parse the 
std.* modules. Object size stays the same.


More information about the Digitalmars-d mailing list