www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get enum value name as string at compile time?

reply Steven Schveighoffer <schveiguy gmail.com> writes:
Consider the enum:

enum Foo { a, b }

Foo.a.stringof => "a"
enum x = Foo.a;
x.stringof => "cast(Foo)0"

Is there another way I can take an enum value that's known at compile 
time (but not the actual identifier), and get the name of it? I know I 
can use a switch, or to!string. But I was hoping this was easy for the 
compiler to figure out some way without involving CTFE.

-Steve
Sep 13 2020
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Monday, 14 September 2020 at 03:48:51 UTC, Steven 
Schveighoffer wrote:
 Consider the enum:

 enum Foo { a, b }

 Foo.a.stringof => "a"
 enum x = Foo.a;
 x.stringof => "cast(Foo)0"

 Is there another way I can take an enum value that's known at 
 compile time (but not the actual identifier), and get the name 
 of it? I know I can use a switch, or to!string. But I was 
 hoping this was easy for the compiler to figure out some way 
 without involving CTFE.
It is a bit weird that x.stringof doesn't simply return the name like Foo.a.stringof does. Anyways, this works: template enumName(alias a) { import std.meta : staticIndexOf, staticMap; alias T = typeof(a); enum getValue(string name) = __traits(getMember, T, name); alias enumValues = staticMap!(getValue, __traits(allMembers, T)); enum enumName = __traits(allMembers, T)[staticIndexOf!(a, enumValues)]; } enum Foo { a = 2, b = 19 } enum x = Foo.a; pragma(msg, enumName!x); // "a" -- Simen
Sep 13 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/14/20 2:25 AM, Simen Kjærås wrote:
 On Monday, 14 September 2020 at 03:48:51 UTC, Steven Schveighoffer wrote:
 Consider the enum:

 enum Foo { a, b }

 Foo.a.stringof => "a"
 enum x = Foo.a;
 x.stringof => "cast(Foo)0"

 Is there another way I can take an enum value that's known at compile 
 time (but not the actual identifier), and get the name of it? I know I 
 can use a switch, or to!string. But I was hoping this was easy for the 
 compiler to figure out some way without involving CTFE.
It is a bit weird that x.stringof doesn't simply return the name like Foo.a.stringof does. Anyways, this works: template enumName(alias a) {     import std.meta : staticIndexOf, staticMap;     alias T = typeof(a);     enum getValue(string name) = __traits(getMember, T, name);     alias enumValues = staticMap!(getValue, __traits(allMembers, T));     enum enumName = __traits(allMembers, T)[staticIndexOf!(a, enumValues)]; } enum Foo { a = 2, b = 19 } enum x = Foo.a; pragma(msg, enumName!x); // "a"
Thanks. I never considered doing something like that. Not sure I like that better than the CTFE version. I just punted and used to!string in my code anyway. A CTFE linear search in a compile-time array probably wouldn't be too bad, especially when the list of elements is not long. Again, we could use that ... DIP to make things a lot less complex. -Steve
Sep 14 2020