On 6/24/18 7:13 PM, Per Nordlöw wrote:
On Sunday, 24 June 2018 at 21:47:14 UTC, Per Nordlöw wrote:
Further, it just struck me that we can generalize my fast solution to include enumerations with enumerator aliases that are defined directly after its original enumerator by checking with  a `static if` if the current enumerator value equals the previous then we skip it. I'm gonna post the solution here after some hacking.

Solution:

@safe:

/** Enumeration wrapper that uses optimized conversion to string (via `toString`
  * member).
  */
struct Enum(E)
if (is(E == enum))
{
     @property string toString() @safe pure nothrow @nogc
     {
         final switch (_enum)
         {
             static foreach (index, member; __traits(allMembers, E))
             {
                 static if (index == 0 ||
                           (__traits(getMember, E, __traits(allMembers, E)[index - 1]) !=
                             __traits(getMember, E, member)))
                 {
                 case __traits(getMember, E, member):
                     return member;
                 }
             }
         }
     }
     E _enum;                    // the wrapped enum
     alias _enum this;
}

@safe pure unittest
{
     import std.conv : to;
     enum X { a,
              b,
              _b = b             // enumerator alias
     }
     alias EnumX = Enum!X;
     assert(EnumX(X.a).to!string == "a");
     assert(EnumX(X.b).to!string == "b");
     assert(EnumX(X._b).to!string == "b");
}

Great! That should cover quite a few cases.

Now, about this:

Yes, I thought about that too, but the problem is that std.conv.to is used in std.stdio and I don't want to remember to always to do

     writeln("Some text:", x.toString);

instead of

     writeln("Some text:", x);

You misunderstand -- I mean fix std.conv.to so it does what you want. I don't want your code to be the only one that benefits, I want all code to benefit ;)

It's shouldn't be that difficult of a PR. Just separate out the part that takes an AliasSeq and makes the switch, and try without and with NoDuplicates (whichever works first wins).

-Steve

Reply via email to