> On Wednesday, January 25, 2012 03:22:03 Trass3r wrote:
> > So I was just reading
> > http://stackoverflow.com/questions/1448396/how-to-use-enums-as-flags-in-c
> > 
> > And did a quick test:
> 
> I think that it makes sense to use enums as flags, but I do
> _not_ think that it 
> makes sense to use an enum as the type of the variable
> _holding_ the flags.
> 
> STC var = STC.A & STC.B;
> 
> is an abimination IMHO. adding another enum to the list and
> doing something 
> like
> 
> STC var = STC.A & FOO.F;
> 
> just makes it worse. It should be something like
> 
> uint var = STC.A & FOO.F;
> 
> instead. Now anding two different enums like that is still a
> bit weird, but I 
> don't know that it should really be illegal. It's assigning
> anded enums to an 
> enum that I want to see die. I'd _love_ it if that were
> illegal.
> 
> For instance, std.socket uses flag enums, which is fine, but
> in some places it 
> uses them as the type of function parameters, which is _not_
> a good idea IMHO. 
> Whenever I think about it, I keep meaning to go and fix it,
> but I never get 
> around to it.

Indeed. enum should be only a single value, be it a number like 42, or a binary 
bit 1<<42. The type checking enforces it to be a valid value. You can easily 
turn a enum into an int, but the other direction as said before, is not so 
easy. I started on C++ recently and came across that problem, and came across 
this solution (ported shortly after to D).

 Here's my unittests. (they pass)

unittest{
        enum ETEST {
                none = 0,
                one = 1,
                two = 2,
                four = 4
        }

        alias ETEST.none none;
        alias ETEST.one one;
        alias ETEST.two two;
        alias ETEST.four four;


        HandleFlags!(ETEST, int) ftest;

        //test all flags off. Uses int checks.
        assert(ftest.state == 0);       //start empty.

        //set 2 flag
        ftest.setFlag(two, true);
        assert(ftest.state == 2);

        //set 4, should now be 6
        ftest.setFlag(four, true);
        assert(ftest.state == 6);

        //turn off 2 bit
        ftest.setFlag(two, false);
        assert(ftest.state == 4);

        //flip 1
        ftest.flipFlag(one);            //4+1
        assert(ftest.state == 5);

        //flip 1 again.
        ftest.flipFlag(one);            //4+0
        assert(ftest.state == 4);

        //check truth/else
        ETEST x = ftest.checkElse(four, none);
        assert(x == four);

        x = ftest.checkElse(one, none);
        assert(x == none);

        assert(ftest.check(four) == true);
        assert(ftest.check(two) == false);
}

Reply via email to