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