bit-level logic operations on enums

Andrej Mitrovic andrej.mitrovich at gmail.com
Fri Mar 1 10:30:19 PST 2013


On 3/1/13, d coder <dlang.coder at gmail.com> wrote:
> enum BING_e: byte {NONE_BING = 0b00, FOO_BING = 0b01, // 1
>     BAR_BING = 0b10, BOTH_BING = 0b11}                // 2

P.S. you might want to statically verify that each enum member can be
used as a flag. E.g.e you would do "static
assert(isValidFlag!BING_e)".

Here's how I did this recently:

template isValidFlag(E)
    if (is(E == enum))
{
    static if (is(E B == enum))
        alias BaseType = B;

    static bool checkFlag()
    {
        BaseType flag;
        foreach (member; EnumMembers!E)
        {
            if (member & flag)
                return false;

            flag |= member;
        }

        return true;
    }

    enum bool isValidFlag = checkFlag();
}

unittest
{
    enum EK1 { a, b, c }    // 0b00, 0b01, 0b10
    enum EF1 { a, b, c, d } // 0b00, 0b01, 0b10, 0b11 (conflict)
    enum EK2 { a = 1 << 1, b = 1 << 2, c = 1 << 3, d = 1 << 4 }
    enum EF2 { a = 1 << 1, b = 1 << 2, c = 3 << 3, d = 1 << 4 }
    static assert(isValidFlag!EK1);
    static assert(!isValidFlag!EF1);
    static assert(isValidFlag!EK2);
    static assert(!isValidFlag!EF2);
}


More information about the Digitalmars-d mailing list