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