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