View source code Display the source code in std/typecons.d from which this page was generated on github. Improve this page Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone. Page wiki View or edit the community-maintained wiki page associated with this page.

Struct std.typecons.BitFlags

A typesafe structure for storing combination of enum values.

This template defines a simple struct to represent bitwise OR combinations of enum values. It can be used if all the enum values are integral constants with a bit count of at most 1, or if the unsafe parameter is explicitly set to Yes. This is much safer than using the enum itself to store the OR combination, which can produce surprising effects like this:

enum E
{
    A = 1<<0,
    B = 1<<1
}
E e = E.A | E.B;
// will throw SwitchError
final switch(e)
{
    case E.A:
        return;
    case E.B:
        return;
}

Example

BitFlags can be manipulated with the usual operators

// You can use such an enum with BitFlags straight away
enum Enum
{
    None,
    A = 1<<0,
    B = 1<<1,
    C = 1<<2
}
static assert(__traits(compiles, BitFlags!Enum));

// You need to specify the unsafe parameter for enum with custom values
enum UnsafeEnum
{
    A,
    B,
    C,
    D = B|C
}
static assert(!__traits(compiles, BitFlags!UnsafeEnum));
static assert(__traits(compiles, BitFlags!(UnsafeEnum, Yes.unsafe)));

immutable BitFlags!Enum flags_empty;
// A default constructed BitFlags has no value set
assert(!(flags_empty & Enum.A) && !(flags_empty & Enum.B) && !(flags_empty & Enum.C));

// Value can be set with the | operator
immutable BitFlags!Enum flags_A = flags_empty | Enum.A;

// And tested with the & operator
assert(flags_A & Enum.A);

// Which commutes
assert(Enum.A & flags_A);

// BitFlags can be variadically initialized
immutable BitFlags!Enum flags_AB = BitFlags!Enum(Enum.A, Enum.B);
assert((flags_AB & Enum.A) && (flags_AB & Enum.B) && !(flags_AB & Enum.C));

// Use the ~ operator for subtracting flags
immutable BitFlags!Enum flags_B = flags_AB & ~BitFlags!Enum(Enum.A);
assert(!(flags_B & Enum.A) && (flags_B & Enum.B) && !(flags_B & Enum.C));

// You can use the EnumMembers template to set all flags
immutable BitFlags!Enum flags_all = EnumMembers!Enum;

// use & between BitFlags for intersection
immutable BitFlags!Enum flags_BC = BitFlags!Enum(Enum.B, Enum.C);
assert (flags_B == (flags_BC & flags_AB));

// All the binary operators work in their assignment version
BitFlags!Enum temp = flags_empty;
temp |= flags_AB;
assert(temp == (flags_empty | flags_AB));
temp = flags_empty;
temp |= Enum.B;
assert(temp == (flags_empty | Enum.B));
temp = flags_empty;
temp &= flags_AB;
assert(temp == (flags_empty & flags_AB));
temp = flags_empty;
temp &= Enum.A;
assert(temp == (flags_empty & Enum.A));

// BitFlags with no value set evaluate to false
assert(!flags_empty);

// BitFlags with at least one value set evaluate to true
assert(flags_A);

// This can be useful to check intersection between BitFlags
assert(flags_A & flags_AB);
assert(flags_AB & Enum.A);

// Finally, you can of course get you raw value out of flags
auto value = cast(int)flags_A;
assert(value == Enum.A);

Authors

Andrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara

License

Boost License 1.0.

Comments