EnumMembers

Evaluates to an AliasSeq containing the members of an enum type.

The elements of the AliasSeq are in the same order as they are in the enum declaration.

An enum can have multiple members with the same value, so if code needs the enum values to be unique (e.g. if it's generating a switch statement from them), then phobos.sys.meta.Unique can be used to filter out the duplicate values - e.g. Unique!(isEqual, EnumMembers!E).

Examples

Create an array of enum values.

enum Sqrts : real
{
    one = 1,
    two = 1.41421,
    three = 1.73205
}
auto sqrts = [EnumMembers!Sqrts];
assert(sqrts == [Sqrts.one, Sqrts.two, Sqrts.three]);

A generic function rank(v) in the following example uses this template for finding a member e in an enum type E.

// Returns i if e is the i-th member of E.
static size_t rank(E)(E e)
if (is(E == enum))
{
    static foreach (i, member; EnumMembers!E)
    {
        if (e == member)
            return i;
    }
    assert(0, "Not an enum member");
}

enum Mode
{
    read = 1,
    write = 2,
    map = 4
}
assert(rank(Mode.read) == 0);
assert(rank(Mode.write) == 1);
assert(rank(Mode.map) == 2);

Use EnumMembers to generate a switch statement using static foreach.

static class Foo
{
    string calledMethod;
    void foo() @safe { calledMethod = "foo"; }
    void bar() @safe { calledMethod = "bar"; }
    void baz() @safe { calledMethod = "baz"; }
}

enum FuncName : string { foo = "foo", bar = "bar", baz = "baz" }

auto foo = new Foo;

s: final switch (FuncName.bar)
{
    static foreach (member; EnumMembers!FuncName)
    {
        // Generate a case for each enum value.
        case member:
        {
            // Call foo.{enum value}().
            __traits(getMember, foo, member)();
            break s;
        }
    }
}

// Since we passed FuncName.bar to the switch statement, the bar member
// function was called.
assert(foo.calledMethod == "bar");

Meta