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