/* enumTo/FromString */
void main()
{
enum Color { RED, GREEN, BLUE }
Color c;
assert(enumToString(Color.RED) == "RED");
assert(enumFromString("GREEN", c) && c == Color.GREEN);
assert(!enumFromString("WHITE", c));
}
////////////////////////////////////////////////////////////////////////
/**
* Returns the enum member name whose value is v.
*/
string enumToString(Enum)(Enum v) pure nothrow
if (is(Enum == enum))
{
mixin (enumToStringGen!(Enum).code);
}
private template enumToStringGen(Enum)
{
template generate(alias members)
{
static if (members.length)
{
enum m = members[0];
enum code =
"if (v == Enum." ~ m ~ ") return `" ~ m ~ "`;" ~
generate!(members[1 .. $]).code;
}
else
{
enum code = "assert(0);";
}
}
enum code = generate!(__traits(allMembers, Enum)).code;
}
unittest
{
enum E { a, b, c }
assert(enumToString(E.a) == "a");
assert(enumToString(E.b) == "b");
assert(enumToString(E.c) == "c");
}
/**
* Gets the enum member value from an enum member name s.
*/
bool enumFromString(Enum)(string s, out Enum v) nothrow
if (is(Enum == enum))
{
mixin (enumFromStringGen!(Enum).code);
}
private template enumFromStringGen(Enum)
{
template generate(alias members)
{
static if (members.length)
{
enum m = members[0];
enum code =
"if (s == `" ~ m ~ "`) return (v = Enum." ~ m ~ "), true;" ~
generate!(members[1 .. $]).code;
}
else
{
enum code = "return false;";
}
}
enum code = generate!(__traits(allMembers, Enum)).code;
}
unittest
{
enum E { a, b, c }
E v;
assert(enumFromString("a", v) && v == E.a);
assert(enumFromString("b", v) && v == E.b);
assert(enumFromString("c", v) && v == E.c);
assert(!enumFromString("d", v));
}