Casting from an enum type to another enum type

Meta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jun 24 11:16:40 PDT 2015


On Wednesday, 24 June 2015 at 15:29:03 UTC, Roland Hadinger wrote:
> Hi!
>
> What is the straightest way to safely cast from one enum type A 
> to another enum type B, when B, in terms of values as well as 
> identifiers, is a strict subset of A?
>
> Ideally, that should be as simple as "to!B(a)". So far I've 
> tried a couple of things, and one way I found was to first cast 
> A to int, then cast that to B, but that is not really 
> straightforward.
>
> Example:
>
> import std.stdio;
> import std.conv;
>
> enum Color { r, o, y, g, b, i, v }
>
> enum StyleColor : int { o = Color.o, b = Color.b }
>
> void main()
> {
>     auto c = Color.g;
>
>     // Problem: the result is not guaranteed to be a StyleColor.
>     // Does not throw, needs extra checks.
>     auto d1 = cast(StyleColor) c;
>
>     // Typesafe, but is not exactly straightforward.
>     auto d2 = to!StyleColor(cast(int) c);
>
>     // Error: template std.conv.toImpl cannot deduce
>     // function from argument types !(StyleColor)(Color)
>     //
>     // Changing "enum StyleColor : Color" to "enum StyleColor : 
> int"
>     // in the definition above does not help either.
>     auto d3 = to!StyleColor(c);
> }

std.conv.to really should be able to do this, but I guess not 
many people have needed to do this. You can write an "extension" 
to `to` which does it for you:

import std.traits;

auto to(To, From)(From f)
if (is(From == enum) && is(To == enum) && is(OriginalType!From : 
OriginalType!To))
{
     return cast(To)f;
}

enum Color { r, o, y, g, b, i, v }

enum StyleColor : int { o = Color.o, b = Color.b }

void main()
{
	auto c = Color.g;
	auto s = c.to!StyleColor;
}


More information about the Digitalmars-d-learn mailing list