----- import std.conv; import std.stdio; import std.string; import std.traits; import std.typetuple; import std.socket; void main() { string[] enums = to!(string[])([EnumMembers!SocketOption]); writeln(enums.join("\n")); } ----- Prints: DEBUG BROADCAST REUSEADDR LINGER OOBINLINE SNDBUF RCVBUF DONTROUTE SNDTIMEO RCVTIMEO ERROR KEEPALIVE ACCEPTCONN RCVLOWAT SNDLOWAT TYPE DEBUG -- note duplicate! REUSEADDR -- note duplicate! IPV6_MULTICAST_IF IPV6_MULTICAST_LOOP IPV6_MULTICAST_HOPS IPV6_JOIN_GROUP IPV6_LEAVE_GROUP IPV6_V6ONLY The workaround for user code is to use NoDuplicate from std.typetuple: string[] enums = to!(string[])([NoDuplicates!(EnumMembers!SocketOption)]);
The root issue appears to be that enums can have identifiers with duplicate values: //---- writefln("%(%d\n%)", [EnumMembers!SocketOption]); //---- 1 32 4 128 256 4097 4098 16 4101 4102 4103 8 2 4100 4099 4104 1 //HERE 4 //HERE 9 11 10 12 13 27 //---- So I'm not entirely sure EnumMembers is actually at fault here. It's the enum to string conversion that is "breaking". But at the same time, there are too enum members with the same value, so I'm not sure this is fixable. At best, documented and worked around.
(In reply to comment #1) > So I'm not entirely sure EnumMembers is actually at fault here. It's the enum > to string conversion that is "breaking". But at the same time, there are too > enum members with the same value, so I'm not sure this is fixable. At best, > documented and worked around. Hmm yeah, you're right. I think I'll just make a pull with a doc fix, by refering to NoDuplicates if someone wants to do code-generation with this trait.
https://github.com/D-Programming-Language/phobos/pull/1541
I'm closing as "invalid", lest someone think, reading the title, that EnumMembers now doesn't return dupes.
I've renamed the title and set it as fixed. Otherwise it won't be in the changelog.