Getting enum from value

ag0aep6g via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Aug 5 10:05:28 PDT 2017


On 08/05/2017 05:33 PM, Matthew Remmel wrote:
> I feel like I'm missing something, but there has to be an easier way to 
> convert a value into an enum than switching over every possible value: i.e
> 
> enum Capitals {
>      Indiana = "Indianapolis",
>      Illinois = "Chicago",
>      Ohio = "Columbus"
> }
> 
> Capitals enumFromValue(string s) {
>      switch (s) {
>          case Capitals.Indiana:
>              return Capitals.Indiana;
>           case Capitals.Illinois:
>              return Capitals.Illinois;
>           case Capitals.Ohio:
>              return Capitals.Ohio;
>           default:
>               throw new Exception(format("No Capitals enum member with 
> value %s", s));
>      }
> }
> 
> int main() {
>      Capitals c = enumFromValue("Chicago"); // works
> 
>      // I tried using std.conv, but it matches on the enum member name
>      c = to!Capitals("Chicago") // fails, no member named Chicago
> }
> 
> With how redundant the enumFromValue(string) implementation is, I would 
> think there would be an easier way to do it. I'm sure you could use a 
> mixin, a template, or std.traits. I was hoping there was a more 
> 'builtin' way to do it though. Something along the simplicity of:
> 
> int main() {
>      Capitals c = Capitals("Chicago");
> }
> 
> Any ideas?

As far as I know, there's no built-in way to do this. But you can 
simplify and generalize your `enumFromValue`:

----
enum Capitals
{
     Indiana = "Indianapolis",
     Illinois = "Chicago",
     Ohio = "Columbus"
}

E enumFromValue(E)(string s)
{
     import std.format: format;
     import std.traits: EnumMembers;
     switch (s)
     {
         foreach (c; EnumMembers!E)
         {
             case c: return c;
         }
         default:
         immutable string msgfmt = "enum %s has no member with value %s";
         throw new Exception(format(msgfmt, E.stringof, s));
     }
}

void main()
{
     auto c = enumFromValue!Capitals("Chicago");
     assert(c == Capitals.Illinois);
}
----


More information about the Digitalmars-d-learn mailing list