[Issue 6946] Compile-time flags generator

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Nov 14 15:22:03 PST 2011


http://d.puremagic.com/issues/show_bug.cgi?id=6946



--- Comment #1 from bearophile_hugs at eml.cc 2011-11-14 15:21:15 PST ---
For the C# [Flags] attribute see:
http://msdn.microsoft.com/en-us/library/cc138362.aspx
http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx


In D enums EnumBaseType defaults to int:
http://www.d-programming-language.org/enum.html
but for powers of two bit flags I think using an unsigned type is saner, so for
bitFlags I have used uint as default type.

Follows a bit improved version, it always contains a "None" member too,
represented with 0:


import std.traits: isUnsigned;
import std.string: split;
import std.conv: text;
import std.algorithm: canFind;

bool isReservedWord(in string w) {
    string[] reservedWords = "abstract alias align asm
    assert auto body bool break byte case cast catch cdouble cent cfloat
    char class const continue creal dchar debug default delegate delete
    deprecated do double else enum export extern false final finally
    float for foreach foreach_reverse function goto idouble if ifloat
    immutable import in inout int interface invariant ireal is lazy long
    macro mixin module new nothrow null out override package pragma
    private protected public pure real ref return scope shared short
    static struct super switch synchronized template this throw true try
    typedef typeid typeof ubyte ucent uint ulong union unittest ushort
    version void volatile wchar while with __FILE__ __LINE__ __gshared
    __thread __traits".split();
    return canFind(reservedWords, w);
}

string bitFlags(BaseType=uint)(string enumName, string enumItems)
if (isUnsigned!BaseType) {
    assert ((enumItems.split().length + 1) < (BaseType.sizeof * 8),
            text("BaseType (", BaseType.stringof,
                 ") doesn't have enough bits to represent all the enumItems
plus None."));
    string result = text("enum ", enumName, " : ", BaseType.stringof, " {\n");
    result ~= text("    None = 0,\n");
    foreach (i, flag; enumItems.split()) {
        assert(!isReservedWord(flag), text("bitFlags: enum member '", flag, "'
is a D keyword."));
        result ~= text("    ", flag, " = (1 << ", i, "),\n");
    }
    return result ~ "}";
}

// example usages ----------------
mixin(bitFlags!size_t("MyFlags", "A B C D"));
//mixin(bitFlags!ulong("MyFlags", "A B C D")); // writeln bug 6892

mixin(bitFlags("Days", "Sunday Monday Tuesday Wednesday Thursday Friday
Saturday"));

void main() {
    import std.stdio;
    writeln(MyFlags.C);
    import std.traits, std.algorithm;
    assert(equal(map!text([EnumMembers!MyFlags]),
                 ["None", "A", "B", "C", "D"]));
    Days meetingDays = Days.Tuesday | Days.Thursday;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list