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.
12 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
13 #![cfg_attr(stage0, feature(custom_attribute))]
14 #![crate_name = "rustc_bitflags"]
15 #![feature(associated_consts)]
16 #![feature(staged_api)]
18 #![crate_type = "rlib"]
21 #![unstable(feature = "rustc_private")]
22 #![cfg_attr(test, feature(hash))]
24 //! A typesafe bitmask flag generator.
26 #[cfg(test)] #[macro_use] extern crate std;
28 /// The `bitflags!` macro generates a `struct` that holds a set of C-style
29 /// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
31 /// The flags should only be defined for integer types, otherwise unexpected
32 /// type errors may occur at compile time.
37 /// # #![feature(rustc_private)]
38 /// # #![feature(associated_consts)]
39 /// #[macro_use] extern crate rustc_bitflags;
42 /// flags Flags: u32 {
43 /// const FLAG_A = 0b00000001,
44 /// const FLAG_B = 0b00000010,
45 /// const FLAG_C = 0b00000100,
46 /// const FLAG_ABC = Flags::FLAG_A.bits
47 /// | Flags::FLAG_B.bits
48 /// | Flags::FLAG_C.bits,
53 /// let e1 = Flags::FLAG_A | Flags::FLAG_C;
54 /// let e2 = Flags::FLAG_B | Flags::FLAG_C;
55 /// assert!((e1 | e2) == Flags::FLAG_ABC); // union
56 /// assert!((e1 & e2) == Flags::FLAG_C); // intersection
57 /// assert!((e1 - e2) == Flags::FLAG_A); // set difference
58 /// assert!(!e2 == Flags::FLAG_A); // set complement
62 /// The generated `struct`s can also be extended with type and trait implementations:
65 /// # #![feature(rustc_private)]
66 /// #[macro_use] extern crate rustc_bitflags;
71 /// flags Flags: u32 {
72 /// const FLAG_A = 0b00000001,
73 /// const FLAG_B = 0b00000010,
78 /// pub fn clear(&mut self) {
79 /// self.bits = 0; // The `bits` field can be accessed from within the
80 /// // same module where the `bitflags!` macro was invoked.
84 /// impl fmt::Debug for Flags {
85 /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 /// let mut flags = Flags::FLAG_A | Flags::FLAG_B;
93 /// assert!(flags.is_empty());
94 /// assert_eq!(format!("{:?}", flags), "hi!");
100 /// Attributes can be attached to the generated `struct` by placing them
101 /// before the `flags` keyword.
105 /// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
106 /// the `deriving` attribute. Additional traits can be derived by providing an
107 /// explicit `deriving` attribute on `flags`.
111 /// The following operator traits are implemented for the generated `struct`:
114 /// - `BitAnd`: intersection
115 /// - `BitXor`: toggle
116 /// - `Sub`: set difference
117 /// - `Not`: set complement
121 /// The following methods are defined for the generated `struct`:
123 /// - `empty`: an empty set of flags
124 /// - `all`: the set of all flags
125 /// - `bits`: the raw value of the flags currently stored
126 /// - `from_bits`: convert from underlying bit representation, unless that
127 /// representation contains bits that do not correspond to a flag
128 /// - `from_bits_truncate`: convert from underlying bit representation, dropping
129 /// any bits that do not correspond to flags
130 /// - `is_empty`: `true` if no flags are currently stored
131 /// - `is_all`: `true` if all flags are currently set
132 /// - `intersects`: `true` if there are flags common to both `self` and `other`
133 /// - `contains`: `true` all of the flags in `other` are contained within `self`
134 /// - `insert`: inserts the specified flags in-place
135 /// - `remove`: removes the specified flags in-place
136 /// - `toggle`: the specified flags will be inserted if not present, and removed
139 macro_rules
! bitflags
{
140 ($
(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
141 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
143 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
145 pub struct $BitFlags
{
150 $
($
(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
152 /// Returns an empty set of flags.
154 pub fn empty() -> $BitFlags
{
155 $BitFlags { bits: 0 }
158 /// Returns the set containing all flags.
160 pub fn all() -> $BitFlags
{
161 $BitFlags { bits: $($value)|+ }
164 /// Returns the raw value of the flags currently stored.
166 pub fn bits(&self) -> $T
{
170 /// Convert from underlying bit representation, unless that
171 /// representation contains bits that do not correspond to a flag.
173 pub fn from_bits(bits
: $T
) -> ::std
::option
::Option
<$BitFlags
> {
174 if (bits
& !$BitFlags
::all().bits()) != 0 {
175 ::std
::option
::Option
::None
177 ::std
::option
::Option
::Some($BitFlags { bits: bits }
)
181 /// Convert from underlying bit representation, dropping any bits
182 /// that do not correspond to flags.
184 pub fn from_bits_truncate(bits
: $T
) -> $BitFlags
{
185 $BitFlags { bits: bits }
& $BitFlags
::all()
188 /// Returns `true` if no flags are currently stored.
190 pub fn is_empty(&self) -> bool
{
191 *self == $BitFlags
::empty()
194 /// Returns `true` if all flags are currently set.
196 pub fn is_all(&self) -> bool
{
197 *self == $BitFlags
::all()
200 /// Returns `true` if there are flags common to both `self` and `other`.
202 pub fn intersects(&self, other
: $BitFlags
) -> bool
{
203 !(*self & other
).is_empty()
206 /// Returns `true` all of the flags in `other` are contained within `self`.
208 pub fn contains(&self, other
: $BitFlags
) -> bool
{
209 (*self & other
) == other
212 /// Inserts the specified flags in-place.
214 pub fn insert(&mut self, other
: $BitFlags
) {
215 self.bits
|= other
.bits
;
218 /// Removes the specified flags in-place.
220 pub fn remove(&mut self, other
: $BitFlags
) {
221 self.bits
&= !other
.bits
;
224 /// Toggles the specified flags in-place.
226 pub fn toggle(&mut self, other
: $BitFlags
) {
227 self.bits ^
= other
.bits
;
231 impl ::std
::ops
::BitOr
for $BitFlags
{
232 type Output
= $BitFlags
;
234 /// Returns the union of the two sets of flags.
236 fn bitor(self, other
: $BitFlags
) -> $BitFlags
{
237 $BitFlags { bits: self.bits | other.bits }
241 impl ::std
::ops
::BitXor
for $BitFlags
{
242 type Output
= $BitFlags
;
244 /// Returns the left flags, but with all the right flags toggled.
246 fn bitxor(self, other
: $BitFlags
) -> $BitFlags
{
247 $BitFlags { bits: self.bits ^ other.bits }
251 impl ::std
::ops
::BitAnd
for $BitFlags
{
252 type Output
= $BitFlags
;
254 /// Returns the intersection between the two sets of flags.
256 fn bitand(self, other
: $BitFlags
) -> $BitFlags
{
257 $BitFlags { bits: self.bits & other.bits }
261 impl ::std
::ops
::Sub
for $BitFlags
{
262 type Output
= $BitFlags
;
264 /// Returns the set difference of the two sets of flags.
266 fn sub(self, other
: $BitFlags
) -> $BitFlags
{
267 $BitFlags { bits: self.bits & !other.bits }
271 impl ::std
::ops
::Not
for $BitFlags
{
272 type Output
= $BitFlags
;
274 /// Returns the complement of this set of flags.
276 fn not(self) -> $BitFlags
{
277 $BitFlags { bits: !self.bits }
& $BitFlags
::all()
281 ($
(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
282 $
($
(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
286 flags $BitFlags
: $T
{
287 $
($
(#[$Flag_attr])* const $Flag = $value),+
293 // This is a no_std crate. So the test code's invocation of #[derive] etc, via
294 // bitflags!, will use names from the underlying crates.
297 pub use std
::{fmt, hash, clone, cmp, marker, option}
;
301 #[allow(non_upper_case_globals)]
303 use std
::hash
::{self, SipHasher}
;
304 use std
::option
::Option
::{Some, None}
;
307 #[doc = "> The first principle is that you must not fool yourself — and"]
308 #[doc = "> you are the easiest person to fool."]
310 #[doc = "> - Richard Feynman"]
312 const FlagA
= 0b00000001,
313 #[doc = "<pcwalton> macros are way better at generating code than trans is"]
314 const FlagB
= 0b00000010,
315 const FlagC
= 0b00000100,
317 #[doc = "* strcat table"]
318 #[doc = "<strcat> wait what?"]
319 const FlagABC
= Flags
::FlagA
.bits
326 flags AnotherSetOfFlags
: i8 {
327 const AnotherFlag
= -1,
333 assert_eq
!(Flags
::empty().bits(), 0b00000000);
334 assert_eq
!(Flags
::FlagA
.bits(), 0b00000001);
335 assert_eq
!(Flags
::FlagABC
.bits(), 0b00000111);
337 assert_eq
!(AnotherSetOfFlags
::empty().bits(), 0b00);
338 assert_eq
!(AnotherSetOfFlags
::AnotherFlag
.bits(), !0);
342 fn test_from_bits() {
343 assert
!(Flags
::from_bits(0) == Some(Flags
::empty()));
344 assert
!(Flags
::from_bits(0b1) == Some(Flags
::FlagA
));
345 assert
!(Flags
::from_bits(0b10) == Some(Flags
::FlagB
));
346 assert
!(Flags
::from_bits(0b11) == Some(Flags
::FlagA
| Flags
::FlagB
));
347 assert
!(Flags
::from_bits(0b1000) == None
);
349 assert
!(AnotherSetOfFlags
::from_bits(!0) == Some(AnotherSetOfFlags
::AnotherFlag
));
353 fn test_from_bits_truncate() {
354 assert
!(Flags
::from_bits_truncate(0) == Flags
::empty());
355 assert
!(Flags
::from_bits_truncate(0b1) == Flags
::FlagA
);
356 assert
!(Flags
::from_bits_truncate(0b10) == Flags
::FlagB
);
357 assert
!(Flags
::from_bits_truncate(0b11) == (Flags
::FlagA
| Flags
::FlagB
));
358 assert
!(Flags
::from_bits_truncate(0b1000) == Flags
::empty());
359 assert
!(Flags
::from_bits_truncate(0b1001) == Flags
::FlagA
);
361 assert
!(AnotherSetOfFlags
::from_bits_truncate(0) == AnotherSetOfFlags
::empty());
366 assert
!(Flags
::empty().is_empty());
367 assert
!(!Flags
::FlagA
.is_empty());
368 assert
!(!Flags
::FlagABC
.is_empty());
370 assert
!(!AnotherSetOfFlags
::AnotherFlag
.is_empty());
375 assert
!(Flags
::all().is_all());
376 assert
!(!Flags
::FlagA
.is_all());
377 assert
!(Flags
::FlagABC
.is_all());
379 assert
!(AnotherSetOfFlags
::AnotherFlag
.is_all());
383 fn test_two_empties_do_not_intersect() {
384 let e1
= Flags
::empty();
385 let e2
= Flags
::empty();
386 assert
!(!e1
.intersects(e2
));
388 assert
!(AnotherSetOfFlags
::AnotherFlag
.intersects(AnotherSetOfFlags
::AnotherFlag
));
392 fn test_empty_does_not_intersect_with_full() {
393 let e1
= Flags
::empty();
394 let e2
= Flags
::FlagABC
;
395 assert
!(!e1
.intersects(e2
));
399 fn test_disjoint_intersects() {
400 let e1
= Flags
::FlagA
;
401 let e2
= Flags
::FlagB
;
402 assert
!(!e1
.intersects(e2
));
406 fn test_overlapping_intersects() {
407 let e1
= Flags
::FlagA
;
408 let e2
= Flags
::FlagA
| Flags
::FlagB
;
409 assert
!(e1
.intersects(e2
));
414 let e1
= Flags
::FlagA
;
415 let e2
= Flags
::FlagA
| Flags
::FlagB
;
416 assert
!(!e1
.contains(e2
));
417 assert
!(e2
.contains(e1
));
418 assert
!(Flags
::FlagABC
.contains(e2
));
420 assert
!(AnotherSetOfFlags
::AnotherFlag
.contains(AnotherSetOfFlags
::AnotherFlag
));
425 let mut e1
= Flags
::FlagA
;
426 let e2
= Flags
::FlagA
| Flags
::FlagB
;
430 let mut e3
= AnotherSetOfFlags
::empty();
431 e3
.insert(AnotherSetOfFlags
::AnotherFlag
);
432 assert
!(e3
== AnotherSetOfFlags
::AnotherFlag
);
437 let mut e1
= Flags
::FlagA
| Flags
::FlagB
;
438 let e2
= Flags
::FlagA
| Flags
::FlagC
;
440 assert
!(e1
== Flags
::FlagB
);
442 let mut e3
= AnotherSetOfFlags
::AnotherFlag
;
443 e3
.remove(AnotherSetOfFlags
::AnotherFlag
);
444 assert
!(e3
== AnotherSetOfFlags
::empty());
448 fn test_operators() {
449 let e1
= Flags
::FlagA
| Flags
::FlagC
;
450 let e2
= Flags
::FlagB
| Flags
::FlagC
;
451 assert
!((e1
| e2
) == Flags
::FlagABC
); // union
452 assert
!((e1
& e2
) == Flags
::FlagC
); // intersection
453 assert
!((e1
- e2
) == Flags
::FlagA
); // set difference
454 assert
!(!e2
== Flags
::FlagA
); // set complement
455 assert
!(e1 ^ e2
== Flags
::FlagA
| Flags
::FlagB
); // toggle
458 assert
!(e3
== Flags
::FlagA
| Flags
::FlagB
);
460 let mut m4
= AnotherSetOfFlags
::empty();
461 m4
.toggle(AnotherSetOfFlags
::empty());
462 assert
!(m4
== AnotherSetOfFlags
::empty());
467 let mut a
= Flags
::empty();
468 let mut b
= Flags
::empty();
470 assert
!(!(a
< b
) && !(b
< a
));
474 assert
!(!(a
< b
) && b
< a
);
475 b
= Flags
::FlagC
| Flags
::FlagB
;
481 let mut a
= Flags
::empty();
482 let mut b
= Flags
::empty();
484 assert
!(a
<= b
&& a
>= b
);
486 assert
!(a
> b
&& a
>= b
);
487 assert
!(b
< a
&& b
<= a
);
489 assert
!(b
> a
&& b
>= a
);
490 assert
!(a
< b
&& a
<= b
);
495 let mut x
= Flags
::empty();
496 let mut y
= Flags
::empty();
497 assert
!(hash
::hash
::<Flags
, SipHasher
>(&x
) == hash
::hash
::<Flags
, SipHasher
>(&y
));
500 assert
!(hash
::hash
::<Flags
, SipHasher
>(&x
) == hash
::hash
::<Flags
, SipHasher
>(&y
));