Minor fix to work right for "none" fields. Already worked fine on combination fields liek "all".

-------------------------------------
enum Foo
{
    none = 0,
    optionA = 1<<0,
    optionB = 1<<1,
    optionC = 1<<2,
    optionD = 1<<3,
    all = optionA | optionB | optionC | optionD,
}

import std.traits : isIntegral;
auto bitFieldValues(T)(T value) if(is(T==enum) && isIntegral!T)
{
    // There's gotta be a better way to convert EnumMembers!T
    // to a range, right? But std.range.only() didn't work,
    // due to a template instantiation error.
    T[] members;
    foreach(m; EnumMembers!(T))
        members ~= m;

    return members
        .filter!(member => member==0? value==0 : (value&member)==member)
        .map!(member => to!string(member));
}

void main()
{
    import std.range : join;
    import std.stdio : writeln;

    Foo fooVar = Foo.optionB | Foo.optionD;

    // Output:
    // optionB | optionD
    // none
    // optionA | optionB | optionC | optionD | all

    writeln(bitFieldValues(Foo.optionB | Foo.optionD).join(" | "));
    writeln(bitFieldValues(Foo.none).join(" | "));
    writeln(bitFieldValues(Foo.all).join(" | "));
}
-------------------------------------

Reply via email to