Test if an enum value is in a range of a derived enum
Andrej Mitrovic
andrej.mitrovich at gmail.com
Wed May 2 16:38:31 PDT 2012
import std.stdio;
enum Base
{
One,
Two,
Three,
Four
}
enum Subset : Base
{
Two = Base.Two,
Three = Base.Three
}
void main()
{
Base base = Base.Four;
if (cast(Subset)base)
{
writeln("yes");
}
}
This writes "yes" so cast is a blunt tool that doesn't work in this
case. to!() doesn't work either (compile error, maybe I should file
this) .
My first attempt to implement this check was to use .min/.max of each
enum like so:
import std.stdio;
enum Base
{
One,
Two,
Three,
Four
}
enum Subset : Base
{
Two = Base.Two,
Three = Base.Three
}
void isSubset(Base base)
{
if (base >= Subset.min && base <= Subset.max)
writeln("yes");
else
writeln("no");
}
void main()
{
Base base1 = Base.Three;
Base base2 = Base.Four;
isSubset(base1); // yes
isSubset(base2); // no
}
But this is wrong, because Subset might only define "One" and "Four"
in which case "Two" and "Three" will also pass as a subset even though
they're not defined in Subset.
The alternative is to convert the enum to a string and then to the
Subset enum type via the to!() template:
import std.stdio;
import std.conv;
enum Base
{
One,
Two,
Three,
Four
}
enum Subset : Base
{
One = Base.One,
Four = Base.Four
}
void isSubset(Base base)
{
try
{
to!(Subset)(to!string(base));
writeln("yes");
}
catch (ConvException)
{
writeln("no");
}
}
void main()
{
Base base1 = Base.One;
Base base2 = Base.Two;
isSubset(base1); // yes
isSubset(base2); // no
}
This works but is arguably slow. Personally I'd love it if I could use
the in operator for this, e.g.:
Base base1 = Base.Two;
assert(base1 in Subset);
Anyone know of any other solutions?
More information about the Digitalmars-d-learn
mailing list