1 module nxt.enum_ex; 2 3 @safe: 4 5 /** Enumeration wrapper that uses optimized conversion to string (via `toString` 6 * member). 7 * 8 * See_Also: https://forum.dlang.org/thread/ppndhxvzayedgpbjculm@forum.dlang.org?page=1 9 * 10 * TODO: Move logic to `std.conv.to`. 11 */ 12 struct Enum(E) 13 if (is(E == enum)) { 14 @property string toString() pure nothrow @safe @nogc => toStringFaster(_enum); 15 E _enum; // the wrapped enum 16 alias _enum this; 17 } 18 19 /// 20 pure @safe unittest { 21 enum X { a, 22 b, 23 _b = b // enumerator alias 24 } 25 alias EnumX = Enum!X; 26 assert(EnumX(X.a).toString == "a"); 27 assert(EnumX(X.b).toString == "b"); 28 assert(EnumX(X._b).toString == "b"); // alias encodes to original 29 } 30 31 /** Fast and more generic implementation of `std.conv.to` for enumerations. 32 */ 33 string toStringFaster(T)(const scope T value) pure nothrow @safe @nogc 34 if (is(T == enum)) { 35 import std.meta : AliasSeq; 36 /* TODO: skip wrapping in `AliasSeq` when `allMembers` can be iterated 37 * directly when a bug in compiler has been fixed */ 38 alias members = AliasSeq!(__traits(allMembers, T)); 39 final switch (value) { 40 static foreach (index, member; members) { 41 static if (index == 0 || 42 (__traits(getMember, T, members[index - 1]) != 43 __traits(getMember, T, member))) { 44 case __traits(getMember, T, member): 45 return member; 46 } 47 } 48 } 49 } 50 51 /// 52 pure nothrow @safe @nogc unittest { 53 enum E { unknown, x, y, z, } 54 assert(E.x.toStringFaster == "x"); 55 assert(E.y.toStringFaster == "y"); 56 assert(E.z.toStringFaster == "z"); 57 } 58 59 /** Faster implementation of `std.conv.to` for enumerations with no aliases. 60 */ 61 string toStringNonAliases(T)(const scope T value) pure nothrow @safe @nogc 62 if (is(T == enum)) /+ TODO: check for no aliases +/ 63 { 64 final switch (value) { 65 static foreach (member; __traits(allMembers, T)) { 66 case __traits(getMember, T, member): 67 return member; 68 } 69 } 70 } 71 72 /// 73 pure nothrow @safe @nogc unittest { 74 enum E { unknown, x, y, z, } 75 assert(E.x.toStringNonAliases == "x"); 76 assert(E.y.toStringNonAliases == "y"); 77 assert(E.z.toStringNonAliases == "z"); 78 }