1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A typesafe bitmask flag generator.
13 // Compile the crate with no_std if possible. The "no_std" feature can be
14 // removed once no_std becomes available in 1.6.0 stable. In the meantime no_std
15 // must be disabled by default to allow the crate to work on older rust versions.
16 #![cfg_attr(all(feature = "no_std", not(test)), no_std)]
18 #![cfg_attr(feature = "assignment_operators", feature(augmented_assignments))]
19 #![cfg_attr(all(feature = "assignment_operators", test), feature(op_assign_traits))]
21 #[cfg(all(feature = "no_std", not(test)))]
23 extern crate core
as std
;
25 // Re-export libstd/libcore using an alias so that the macros can work in no_std
26 // crates while remaining compatible with normal crates.
28 pub use std
as __core
;
30 /// The `bitflags!` macro generates a `struct` that holds a set of C-style
31 /// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
33 /// The flags should only be defined for integer types, otherwise unexpected
34 /// type errors may occur at compile time.
39 /// #![cfg_attr(feature = "assignment_operators", feature(augmented_assignments, op_assign_traits))]
41 /// extern crate bitflags;
44 /// flags Flags: u32 {
45 /// const FLAG_A = 0b00000001,
46 /// const FLAG_B = 0b00000010,
47 /// const FLAG_C = 0b00000100,
48 /// const FLAG_ABC = FLAG_A.bits
55 /// let e1 = FLAG_A | FLAG_C;
56 /// let e2 = FLAG_B | FLAG_C;
57 /// assert!((e1 | e2) == FLAG_ABC); // union
58 /// assert!((e1 & e2) == FLAG_C); // intersection
59 /// assert!((e1 - e2) == FLAG_A); // set difference
60 /// assert!(!e2 == FLAG_A); // set complement
64 /// The generated `struct`s can also be extended with type and trait
68 /// #![cfg_attr(feature = "assignment_operators", feature(augmented_assignments, op_assign_traits))]
70 /// extern crate bitflags;
75 /// flags Flags: u32 {
76 /// const FLAG_A = 0b00000001,
77 /// const FLAG_B = 0b00000010,
82 /// pub fn clear(&mut self) {
83 /// self.bits = 0; // The `bits` field can be accessed from within the
84 /// // same module where the `bitflags!` macro was invoked.
88 /// impl fmt::Display for Flags {
89 /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95 /// let mut flags = FLAG_A | FLAG_B;
97 /// assert!(flags.is_empty());
98 /// assert_eq!(format!("{}", flags), "hi!");
99 /// assert_eq!(format!("{:?}", FLAG_A | FLAG_B), "FLAG_A | FLAG_B");
100 /// assert_eq!(format!("{:?}", FLAG_B), "FLAG_B");
106 /// The generated struct and its associated flag constants are not exported
107 /// out of the current module by default. A definition can be exported out of
108 /// the current module by adding `pub` before `flags`:
110 /// ```{.rust},ignore
112 /// extern crate bitflags;
116 /// pub flags Flags1: u32 {
117 /// const FLAG_A = 0b00000001,
121 /// flags Flags2: u32 {
122 /// const FLAG_B = 0b00000010,
128 /// let flag1 = example::FLAG_A;
129 /// let flag2 = example::FLAG_B; // error: const `FLAG_B` is private
135 /// Attributes can be attached to the generated `struct` by placing them
136 /// before the `flags` keyword.
138 /// # Trait implementations
140 /// The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
141 /// traits automatically derived for the `struct` using the `derive` attribute.
142 /// Additional traits can be derived by providing an explicit `derive`
143 /// attribute on `flags`.
145 /// The `FromIterator` trait is implemented for the `struct`, too, calculating
146 /// the union of the instances of the `struct` iterated over.
148 /// The `Debug` trait is also implemented by displaying the bits value of the
153 /// The following operator traits are implemented for the generated `struct`:
155 /// - `BitOr` and `BitOrAssign`: union
156 /// - `BitAnd` and `BitAndAssign`: intersection
157 /// - `BitXor` and `BitXorAssign`: toggle
158 /// - `Sub` and `SubAssign`: set difference
159 /// - `Not`: set complement
161 /// As long as the assignment operators are unstable rust feature they are only
162 /// available with the crate feature `assignment_ops` enabled.
166 /// The following methods are defined for the generated `struct`:
168 /// - `empty`: an empty set of flags
169 /// - `all`: the set of all flags
170 /// - `bits`: the raw value of the flags currently stored
171 /// - `from_bits`: convert from underlying bit representation, unless that
172 /// representation contains bits that do not correspond to a flag
173 /// - `from_bits_truncate`: convert from underlying bit representation, dropping
174 /// any bits that do not correspond to flags
175 /// - `is_empty`: `true` if no flags are currently stored
176 /// - `is_all`: `true` if all flags are currently set
177 /// - `intersects`: `true` if there are flags common to both `self` and `other`
178 /// - `contains`: `true` all of the flags in `other` are contained within `self`
179 /// - `insert`: inserts the specified flags in-place
180 /// - `remove`: removes the specified flags in-place
181 /// - `toggle`: the specified flags will be inserted if not present, and removed
184 macro_rules
! bitflags
{
185 ($
(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
186 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
188 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
190 pub struct $BitFlags
{
194 $
($
(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
197 @_impl flags $BitFlags
: $T
{
198 $
($
(#[$Flag_attr])* const $Flag = $value),+
202 ($
(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
203 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
205 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
211 $
($
(#[$Flag_attr])* const $Flag: $BitFlags = $BitFlags { bits: $value };)+
214 @_impl flags $BitFlags
: $T
{
215 $
($
(#[$Flag_attr])* const $Flag = $value),+
219 (@_impl flags $BitFlags
:ident
: $T
:ty
{
220 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
222 impl $
crate::__core
::fmt
::Debug
for $BitFlags
{
223 fn fmt(&self, f
: &mut $
crate::__core
::fmt
::Formatter
) -> $
crate::__core
::fmt
::Result
{
224 // This convoluted approach is to handle #[cfg]-based flag
225 // omission correctly. Some of the $Flag variants may not be
226 // defined in this module so we create an inner module which
227 // defines *all* flags to the value of 0. We then create a
228 // second inner module that defines all of the flags with #[cfg]
229 // to their real values. Afterwards the glob will import
230 // variants from the second inner module, shadowing all
231 // defined variants, leaving only the undefined ones with the
234 #[allow(unused_assignments)]
236 // We can't use the real $BitFlags struct because it may be
237 // private, which prevents us from using it to define
239 pub struct $BitFlags
{
243 use super::$BitFlags
;
244 $
($
(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
246 // Now we define the "undefined" versions of the flags.
247 // This way, all the names exist, even if some are #[cfg]ed
249 $
(const $Flag
: $BitFlags
= $BitFlags { bits: 0 }
;)+
252 pub fn fmt(self_
: $T
,
253 f
: &mut $
crate::__core
::fmt
::Formatter
)
254 -> $
crate::__core
::fmt
::Result
{
255 // Now we import the real values for the flags.
256 // Only ones that are #[cfg]ed out will be 0.
257 use self::real_flags
::*;
259 let mut first
= true;
261 // $Flag.bits == 0 means that $Flag doesn't exist
262 if $Flag
.bits
!= 0 && self_
& $Flag
.bits
== $Flag
.bits
{
264 try
!(f
.write_str(" | "));
267 try
!(f
.write_str(stringify
!($Flag
)));
273 dummy
::fmt(self.bits
, f
)
279 /// Returns an empty set of flags.
281 pub fn empty() -> $BitFlags
{
282 $BitFlags { bits: 0 }
285 /// Returns the set containing all flags.
287 pub fn all() -> $BitFlags
{
288 // See above `dummy` module for why this approach is taken.
291 pub struct $BitFlags
{
295 use super::$BitFlags
;
296 $
($
(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
298 $
(const $Flag
: $BitFlags
= $BitFlags { bits: 0 }
;)+
302 use self::real_flags
::*;
306 $BitFlags { bits: dummy::all() }
309 /// Returns the raw value of the flags currently stored.
311 pub fn bits(&self) -> $T
{
315 /// Convert from underlying bit representation, unless that
316 /// representation contains bits that do not correspond to a flag.
318 pub fn from_bits(bits
: $T
) -> $
crate::__core
::option
::Option
<$BitFlags
> {
319 if (bits
& !$BitFlags
::all().bits()) != 0 {
320 $
crate::__core
::option
::Option
::None
322 $
crate::__core
::option
::Option
::Some($BitFlags { bits: bits }
)
326 /// Convert from underlying bit representation, dropping any bits
327 /// that do not correspond to flags.
329 pub fn from_bits_truncate(bits
: $T
) -> $BitFlags
{
330 $BitFlags { bits: bits }
& $BitFlags
::all()
333 /// Returns `true` if no flags are currently stored.
335 pub fn is_empty(&self) -> bool
{
336 *self == $BitFlags
::empty()
339 /// Returns `true` if all flags are currently set.
341 pub fn is_all(&self) -> bool
{
342 *self == $BitFlags
::all()
345 /// Returns `true` if there are flags common to both `self` and `other`.
347 pub fn intersects(&self, other
: $BitFlags
) -> bool
{
348 !(*self & other
).is_empty()
351 /// Returns `true` all of the flags in `other` are contained within `self`.
353 pub fn contains(&self, other
: $BitFlags
) -> bool
{
354 (*self & other
) == other
357 /// Inserts the specified flags in-place.
359 pub fn insert(&mut self, other
: $BitFlags
) {
360 self.bits
|= other
.bits
;
363 /// Removes the specified flags in-place.
365 pub fn remove(&mut self, other
: $BitFlags
) {
366 self.bits
&= !other
.bits
;
369 /// Toggles the specified flags in-place.
371 pub fn toggle(&mut self, other
: $BitFlags
) {
372 self.bits ^
= other
.bits
;
376 impl $
crate::__core
::ops
::BitOr
for $BitFlags
{
377 type Output
= $BitFlags
;
379 /// Returns the union of the two sets of flags.
381 fn bitor(self, other
: $BitFlags
) -> $BitFlags
{
382 $BitFlags { bits: self.bits | other.bits }
386 #[cfg(feature="assignment_operators")]
387 impl $
crate::__core
::ops
::BitOrAssign
for $BitFlags
{
389 /// Adds the set of flags.
391 fn bitor_assign(&mut self, other
: $BitFlags
) {
392 self.bits
|= other
.bits
;
396 impl $
crate::__core
::ops
::BitXor
for $BitFlags
{
397 type Output
= $BitFlags
;
399 /// Returns the left flags, but with all the right flags toggled.
401 fn bitxor(self, other
: $BitFlags
) -> $BitFlags
{
402 $BitFlags { bits: self.bits ^ other.bits }
406 #[cfg(feature="assignment_operators")]
407 impl $
crate::__core
::ops
::BitXorAssign
for $BitFlags
{
409 /// Toggles the set of flags.
411 fn bitxor_assign(&mut self, other
: $BitFlags
) {
412 self.bits ^
= other
.bits
;
416 impl $
crate::__core
::ops
::BitAnd
for $BitFlags
{
417 type Output
= $BitFlags
;
419 /// Returns the intersection between the two sets of flags.
421 fn bitand(self, other
: $BitFlags
) -> $BitFlags
{
422 $BitFlags { bits: self.bits & other.bits }
426 #[cfg(feature="assignment_operators")]
427 impl $
crate::__core
::ops
::BitAndAssign
for $BitFlags
{
429 /// Disables all flags disabled in the set.
431 fn bitand_assign(&mut self, other
: $BitFlags
) {
432 self.bits
&= other
.bits
;
436 impl $
crate::__core
::ops
::Sub
for $BitFlags
{
437 type Output
= $BitFlags
;
439 /// Returns the set difference of the two sets of flags.
441 fn sub(self, other
: $BitFlags
) -> $BitFlags
{
442 $BitFlags { bits: self.bits & !other.bits }
446 #[cfg(feature="assignment_operators")]
447 impl $
crate::__core
::ops
::SubAssign
for $BitFlags
{
449 /// Disables all flags enabled in the set.
451 fn sub_assign(&mut self, other
: $BitFlags
) {
452 self.bits
&= !other
.bits
;
456 impl $
crate::__core
::ops
::Not
for $BitFlags
{
457 type Output
= $BitFlags
;
459 /// Returns the complement of this set of flags.
461 fn not(self) -> $BitFlags
{
462 $BitFlags { bits: !self.bits }
& $BitFlags
::all()
466 impl $
crate::__core
::iter
::FromIterator
<$BitFlags
> for $BitFlags
{
467 fn from_iter
<T
: $
crate::__core
::iter
::IntoIterator
<Item
=$BitFlags
>>(iterator
: T
) -> $BitFlags
{
468 let mut result
= Self::empty();
469 for item
in iterator
{
476 ($
(#[$attr:meta])* pub flags $BitFlags:ident: $T:ty {
477 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
481 pub flags $BitFlags
: $T
{
482 $
($
(#[$Flag_attr])* const $Flag = $value),+
486 ($
(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
487 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
491 flags $BitFlags
: $T
{
492 $
($
(#[$Flag_attr])* const $Flag = $value),+
499 #[allow(non_upper_case_globals, dead_code)]
501 use std
::hash
::{SipHasher, Hash, Hasher}
;
504 #[doc = "> The first principle is that you must not fool yourself — and"]
505 #[doc = "> you are the easiest person to fool."]
507 #[doc = "> - Richard Feynman"]
509 const FlagA
= 0b00000001,
510 #[doc = "<pcwalton> macros are way better at generating code than trans is"]
511 const FlagB
= 0b00000010,
512 const FlagC
= 0b00000100,
514 #[doc = "* strcat table"]
515 #[doc = "<strcat> wait what?"]
516 const FlagABC
= FlagA
.bits
523 flags _CfgFlags
: u32 {
529 const _CfgC
= _CfgA
.bits
| 0b10,
534 flags AnotherSetOfFlags
: i8 {
535 const AnotherFlag
= -1_i8,
541 assert_eq
!(Flags
::empty().bits(), 0b00000000);
542 assert_eq
!(FlagA
.bits(), 0b00000001);
543 assert_eq
!(FlagABC
.bits(), 0b00000111);
545 assert_eq
!(AnotherSetOfFlags
::empty().bits(), 0b00);
546 assert_eq
!(AnotherFlag
.bits(), !0_i8);
550 fn test_from_bits() {
551 assert
!(Flags
::from_bits(0) == Some(Flags
::empty()));
552 assert
!(Flags
::from_bits(0b1) == Some(FlagA
));
553 assert
!(Flags
::from_bits(0b10) == Some(FlagB
));
554 assert
!(Flags
::from_bits(0b11) == Some(FlagA
| FlagB
));
555 assert
!(Flags
::from_bits(0b1000) == None
);
557 assert
!(AnotherSetOfFlags
::from_bits(!0_i8) == Some(AnotherFlag
));
561 fn test_from_bits_truncate() {
562 assert
!(Flags
::from_bits_truncate(0) == Flags
::empty());
563 assert
!(Flags
::from_bits_truncate(0b1) == FlagA
);
564 assert
!(Flags
::from_bits_truncate(0b10) == FlagB
);
565 assert
!(Flags
::from_bits_truncate(0b11) == (FlagA
| FlagB
));
566 assert
!(Flags
::from_bits_truncate(0b1000) == Flags
::empty());
567 assert
!(Flags
::from_bits_truncate(0b1001) == FlagA
);
569 assert
!(AnotherSetOfFlags
::from_bits_truncate(0_i8) == AnotherSetOfFlags
::empty());
574 assert
!(Flags
::empty().is_empty());
575 assert
!(!FlagA
.is_empty());
576 assert
!(!FlagABC
.is_empty());
578 assert
!(!AnotherFlag
.is_empty());
583 assert
!(Flags
::all().is_all());
584 assert
!(!FlagA
.is_all());
585 assert
!(FlagABC
.is_all());
587 assert
!(AnotherFlag
.is_all());
591 fn test_two_empties_do_not_intersect() {
592 let e1
= Flags
::empty();
593 let e2
= Flags
::empty();
594 assert
!(!e1
.intersects(e2
));
596 assert
!(AnotherFlag
.intersects(AnotherFlag
));
600 fn test_empty_does_not_intersect_with_full() {
601 let e1
= Flags
::empty();
603 assert
!(!e1
.intersects(e2
));
607 fn test_disjoint_intersects() {
610 assert
!(!e1
.intersects(e2
));
614 fn test_overlapping_intersects() {
616 let e2
= FlagA
| FlagB
;
617 assert
!(e1
.intersects(e2
));
623 let e2
= FlagA
| FlagB
;
624 assert
!(!e1
.contains(e2
));
625 assert
!(e2
.contains(e1
));
626 assert
!(FlagABC
.contains(e2
));
628 assert
!(AnotherFlag
.contains(AnotherFlag
));
634 let e2
= FlagA
| FlagB
;
638 let mut e3
= AnotherSetOfFlags
::empty();
639 e3
.insert(AnotherFlag
);
640 assert
!(e3
== AnotherFlag
);
645 let mut e1
= FlagA
| FlagB
;
646 let e2
= FlagA
| FlagC
;
648 assert
!(e1
== FlagB
);
650 let mut e3
= AnotherFlag
;
651 e3
.remove(AnotherFlag
);
652 assert
!(e3
== AnotherSetOfFlags
::empty());
656 fn test_operators() {
657 let e1
= FlagA
| FlagC
;
658 let e2
= FlagB
| FlagC
;
659 assert
!((e1
| e2
) == FlagABC
); // union
660 assert
!((e1
& e2
) == FlagC
); // intersection
661 assert
!((e1
- e2
) == FlagA
); // set difference
662 assert
!(!e2
== FlagA
); // set complement
663 assert
!(e1 ^ e2
== FlagA
| FlagB
); // toggle
666 assert
!(e3
== FlagA
| FlagB
);
668 let mut m4
= AnotherSetOfFlags
::empty();
669 m4
.toggle(AnotherSetOfFlags
::empty());
670 assert
!(m4
== AnotherSetOfFlags
::empty());
673 #[cfg(feature="assignment_operators")]
675 fn test_assignment_operators() {
676 let mut m1
= Flags
::empty();
677 let e1
= FlagA
| FlagC
;
680 assert
!(m1
== FlagA
);
683 assert
!(m1
== FlagA
);
686 assert
!(m1
== Flags
::empty());
693 fn test_from_iterator() {
694 assert_eq
!([].iter().cloned().collect
::<Flags
>(), Flags
::empty());
695 assert_eq
!([FlagA
, FlagB
].iter().cloned().collect
::<Flags
>(), FlagA
| FlagB
);
696 assert_eq
!([FlagA
, FlagABC
].iter().cloned().collect
::<Flags
>(), FlagABC
);
701 let mut a
= Flags
::empty();
702 let mut b
= Flags
::empty();
704 assert
!(!(a
< b
) && !(b
< a
));
708 assert
!(!(a
< b
) && b
< a
);
715 let mut a
= Flags
::empty();
716 let mut b
= Flags
::empty();
718 assert
!(a
<= b
&& a
>= b
);
720 assert
!(a
> b
&& a
>= b
);
721 assert
!(b
< a
&& b
<= a
);
723 assert
!(b
> a
&& b
>= a
);
724 assert
!(a
< b
&& a
<= b
);
727 fn hash
<T
: Hash
>(t
: &T
) -> u64 {
728 let mut s
= SipHasher
::new_with_keys(0, 0);
735 let mut x
= Flags
::empty();
736 let mut y
= Flags
::empty();
737 assert
!(hash(&x
) == hash(&y
));
740 assert
!(hash(&x
) == hash(&y
));
745 assert_eq
!(format
!("{:?}", FlagA
| FlagB
), "FlagA | FlagB");
746 assert_eq
!(format
!("{:?}", FlagABC
), "FlagA | FlagB | FlagC | FlagABC");
751 pub flags PublicFlags
: i8 {
756 flags PrivateFlags
: i8 {
769 let _
= submodule
::FlagX
;