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. 4 // 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. 10 11 //! A typesafe bitmask flag generator useful for sets of C-style bitmask flags. 12 //! It can be used for creating typesafe wrappers around C APIs. 13 //! 14 //! The `bitflags!` macro generates a `struct` that manages a set of flags. The 15 //! flags should only be defined for integer types, otherwise unexpected type 16 //! errors may occur at compile time. 17 //! 18 //! # Example 19 //! 20 //! ``` 21 //! #[macro_use] 22 //! extern crate bitflags; 23 //! 24 //! bitflags! { 25 //! struct Flags: u32 { 26 //! const A = 0b00000001; 27 //! const B = 0b00000010; 28 //! const C = 0b00000100; 29 //! const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 30 //! } 31 //! } 32 //! 33 //! fn main() { 34 //! let e1 = Flags::A | Flags::C; 35 //! let e2 = Flags::B | Flags::C; 36 //! assert_eq!((e1 | e2), Flags::ABC); // union 37 //! assert_eq!((e1 & e2), Flags::C); // intersection 38 //! assert_eq!((e1 - e2), Flags::A); // set difference 39 //! assert_eq!(!e2, Flags::A); // set complement 40 //! } 41 //! ``` 42 //! 43 //! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code 44 //! generated by the above `bitflags!` expansion. 45 //! 46 //! The generated `struct`s can also be extended with type and trait 47 //! implementations: 48 //! 49 //! ``` 50 //! #[macro_use] 51 //! extern crate bitflags; 52 //! 53 //! use std::fmt; 54 //! 55 //! bitflags! { 56 //! struct Flags: u32 { 57 //! const A = 0b00000001; 58 //! const B = 0b00000010; 59 //! } 60 //! } 61 //! 62 //! impl Flags { 63 //! pub fn clear(&mut self) { 64 //! self.bits = 0; // The `bits` field can be accessed from within the 65 //! // same module where the `bitflags!` macro was invoked. 66 //! } 67 //! } 68 //! 69 //! impl fmt::Display for Flags { 70 //! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 71 //! write!(f, "hi!") 72 //! } 73 //! } 74 //! 75 //! fn main() { 76 //! let mut flags = Flags::A | Flags::B; 77 //! flags.clear(); 78 //! assert!(flags.is_empty()); 79 //! assert_eq!(format!("{}", flags), "hi!"); 80 //! assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 81 //! assert_eq!(format!("{:?}", Flags::B), "B"); 82 //! } 83 //! ``` 84 //! 85 //! # Visibility 86 //! 87 //! The generated struct and its associated flag constants are not exported 88 //! out of the current module by default. A definition can be exported out of 89 //! the current module by adding `pub` before `flags`: 90 //! 91 //! ``` 92 //! #[macro_use] 93 //! extern crate bitflags; 94 //! 95 //! mod example { 96 //! bitflags! { 97 //! pub struct Flags1: u32 { 98 //! const A = 0b00000001; 99 //! } 100 //! } 101 //! bitflags! { 102 //! # pub 103 //! struct Flags2: u32 { 104 //! const B = 0b00000010; 105 //! } 106 //! } 107 //! } 108 //! 109 //! fn main() { 110 //! let flag1 = example::Flags1::A; 111 //! let flag2 = example::Flags2::B; // error: const `B` is private 112 //! } 113 //! ``` 114 //! 115 //! # Attributes 116 //! 117 //! Attributes can be attached to the generated `struct` by placing them 118 //! before the `flags` keyword. 119 //! 120 //! # Trait implementations 121 //! 122 //! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash` 123 //! traits automatically derived for the `struct` using the `derive` attribute. 124 //! Additional traits can be derived by providing an explicit `derive` 125 //! attribute on `flags`. 126 //! 127 //! The `Extend` and `FromIterator` traits are implemented for the `struct`, 128 //! too: `Extend` adds the union of the instances of the `struct` iterated over, 129 //! while `FromIterator` calculates the union. 130 //! 131 //! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also 132 //! implemented by displaying the bits value of the internal struct. 133 //! 134 //! ## Operators 135 //! 136 //! The following operator traits are implemented for the generated `struct`: 137 //! 138 //! - `BitOr` and `BitOrAssign`: union 139 //! - `BitAnd` and `BitAndAssign`: intersection 140 //! - `BitXor` and `BitXorAssign`: toggle 141 //! - `Sub` and `SubAssign`: set difference 142 //! - `Not`: set complement 143 //! 144 //! # Methods 145 //! 146 //! The following methods are defined for the generated `struct`: 147 //! 148 //! - `empty`: an empty set of flags 149 //! - `all`: the set of all defined flags 150 //! - `bits`: the raw value of the flags currently stored 151 //! - `from_bits`: convert from underlying bit representation, unless that 152 //! representation contains bits that do not correspond to a 153 //! defined flag 154 //! - `from_bits_truncate`: convert from underlying bit representation, dropping 155 //! any bits that do not correspond to defined flags 156 //! - `from_bits_unchecked`: convert from underlying bit representation, keeping 157 //! all bits (even those not corresponding to defined 158 //! flags) 159 //! - `is_empty`: `true` if no flags are currently stored 160 //! - `is_all`: `true` if currently set flags exactly equal all defined flags 161 //! - `intersects`: `true` if there are flags common to both `self` and `other` 162 //! - `contains`: `true` all of the flags in `other` are contained within `self` 163 //! - `insert`: inserts the specified flags in-place 164 //! - `remove`: removes the specified flags in-place 165 //! - `toggle`: the specified flags will be inserted if not present, and removed 166 //! if they are. 167 //! - `set`: inserts or removes the specified flags depending on the passed value 168 //! 169 //! ## Default 170 //! 171 //! The `Default` trait is not automatically implemented for the generated struct. 172 //! 173 //! If your default value is equal to `0` (which is the same value as calling `empty()` 174 //! on the generated struct), you can simply derive `Default`: 175 //! 176 //! ``` 177 //! #[macro_use] 178 //! extern crate bitflags; 179 //! 180 //! bitflags! { 181 //! // Results in default value with bits: 0 182 //! #[derive(Default)] 183 //! struct Flags: u32 { 184 //! const A = 0b00000001; 185 //! const B = 0b00000010; 186 //! const C = 0b00000100; 187 //! } 188 //! } 189 //! 190 //! fn main() { 191 //! let derived_default: Flags = Default::default(); 192 //! assert_eq!(derived_default.bits(), 0); 193 //! } 194 //! ``` 195 //! 196 //! If your default value is not equal to `0` you need to implement `Default` yourself: 197 //! 198 //! ``` 199 //! #[macro_use] 200 //! extern crate bitflags; 201 //! 202 //! bitflags! { 203 //! struct Flags: u32 { 204 //! const A = 0b00000001; 205 //! const B = 0b00000010; 206 //! const C = 0b00000100; 207 //! } 208 //! } 209 //! 210 //! // explicit `Default` implementation 211 //! impl Default for Flags { 212 //! fn default() -> Flags { 213 //! Flags::A | Flags::C 214 //! } 215 //! } 216 //! 217 //! fn main() { 218 //! let implemented_default: Flags = Default::default(); 219 //! assert_eq!(implemented_default, (Flags::A | Flags::C)); 220 //! } 221 //! ``` 222 //! 223 //! # Zero Flags 224 //! 225 //! Flags with a value equal to zero will have some strange behavior that one should be aware of. 226 //! 227 //! ``` 228 //! #[macro_use] 229 //! extern crate bitflags; 230 //! 231 //! bitflags! { 232 //! struct Flags: u32 { 233 //! const NONE = 0b00000000; 234 //! const SOME = 0b00000001; 235 //! } 236 //! } 237 //! 238 //! fn main() { 239 //! let empty = Flags::empty(); 240 //! let none = Flags::NONE; 241 //! let some = Flags::SOME; 242 //! 243 //! // Zero flags are treated as always present 244 //! assert!(empty.contains(Flags::NONE)); 245 //! assert!(none.contains(Flags::NONE)); 246 //! assert!(some.contains(Flags::NONE)); 247 //! 248 //! // Zero flags will be ignored when testing for emptiness 249 //! assert!(none.is_empty()); 250 //! } 251 //! ``` 252 253 #![no_std] 254 #![doc(html_root_url = "https://docs.rs/bitflags/1.2.1")] 255 256 #[cfg(test)] 257 #[macro_use] 258 extern crate std; 259 260 // Re-export libcore using an alias so that the macros can work without 261 // requiring `extern crate core` downstream. 262 #[doc(hidden)] 263 pub extern crate core as _core; 264 265 /// The macro used to generate the flag structure. 266 /// 267 /// See the [crate level docs](../bitflags/index.html) for complete documentation. 268 /// 269 /// # Example 270 /// 271 /// ``` 272 /// #[macro_use] 273 /// extern crate bitflags; 274 /// 275 /// bitflags! { 276 /// struct Flags: u32 { 277 /// const A = 0b00000001; 278 /// const B = 0b00000010; 279 /// const C = 0b00000100; 280 /// const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 281 /// } 282 /// } 283 /// 284 /// fn main() { 285 /// let e1 = Flags::A | Flags::C; 286 /// let e2 = Flags::B | Flags::C; 287 /// assert_eq!((e1 | e2), Flags::ABC); // union 288 /// assert_eq!((e1 & e2), Flags::C); // intersection 289 /// assert_eq!((e1 - e2), Flags::A); // set difference 290 /// assert_eq!(!e2, Flags::A); // set complement 291 /// } 292 /// ``` 293 /// 294 /// The generated `struct`s can also be extended with type and trait 295 /// implementations: 296 /// 297 /// ``` 298 /// #[macro_use] 299 /// extern crate bitflags; 300 /// 301 /// use std::fmt; 302 /// 303 /// bitflags! { 304 /// struct Flags: u32 { 305 /// const A = 0b00000001; 306 /// const B = 0b00000010; 307 /// } 308 /// } 309 /// 310 /// impl Flags { 311 /// pub fn clear(&mut self) { 312 /// self.bits = 0; // The `bits` field can be accessed from within the 313 /// // same module where the `bitflags!` macro was invoked. 314 /// } 315 /// } 316 /// 317 /// impl fmt::Display for Flags { 318 /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 319 /// write!(f, "hi!") 320 /// } 321 /// } 322 /// 323 /// fn main() { 324 /// let mut flags = Flags::A | Flags::B; 325 /// flags.clear(); 326 /// assert!(flags.is_empty()); 327 /// assert_eq!(format!("{}", flags), "hi!"); 328 /// assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 329 /// assert_eq!(format!("{:?}", Flags::B), "B"); 330 /// } 331 /// ``` 332 #[macro_export(local_inner_macros)] 333 macro_rules! bitflags { 334 ( 335 $(#[$outer:meta])* 336 pub struct $BitFlags:ident: $T:ty { 337 $( 338 $(#[$inner:ident $($args:tt)*])* 339 const $Flag:ident = $value:expr; 340 )+ 341 } 342 ) => { 343 __bitflags! { 344 $(#[$outer])* 345 (pub) $BitFlags: $T { 346 $( 347 $(#[$inner $($args)*])* 348 $Flag = $value; 349 )+ 350 } 351 } 352 }; 353 ( 354 $(#[$outer:meta])* 355 struct $BitFlags:ident: $T:ty { 356 $( 357 $(#[$inner:ident $($args:tt)*])* 358 const $Flag:ident = $value:expr; 359 )+ 360 } 361 ) => { 362 __bitflags! { 363 $(#[$outer])* 364 () $BitFlags: $T { 365 $( 366 $(#[$inner $($args)*])* 367 $Flag = $value; 368 )+ 369 } 370 } 371 }; 372 ( 373 $(#[$outer:meta])* 374 pub ($($vis:tt)+) struct $BitFlags:ident: $T:ty { 375 $( 376 $(#[$inner:ident $($args:tt)*])* 377 const $Flag:ident = $value:expr; 378 )+ 379 } 380 ) => { 381 __bitflags! { 382 $(#[$outer])* 383 (pub ($($vis)+)) $BitFlags: $T { 384 $( 385 $(#[$inner $($args)*])* 386 $Flag = $value; 387 )+ 388 } 389 } 390 }; 391 } 392 393 #[macro_export(local_inner_macros)] 394 #[doc(hidden)] 395 macro_rules! __bitflags { 396 ( 397 $(#[$outer:meta])* 398 ($($vis:tt)*) $BitFlags:ident: $T:ty { 399 $( 400 $(#[$inner:ident $($args:tt)*])* 401 $Flag:ident = $value:expr; 402 )+ 403 } 404 ) => { 405 $(#[$outer])* 406 #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] 407 $($vis)* struct $BitFlags { 408 bits: $T, 409 } 410 411 __impl_bitflags! { 412 $BitFlags: $T { 413 $( 414 $(#[$inner $($args)*])* 415 $Flag = $value; 416 )+ 417 } 418 } 419 }; 420 } 421 422 #[macro_export(local_inner_macros)] 423 #[doc(hidden)] 424 #[cfg(bitflags_const_fn)] 425 macro_rules! __fn_bitflags { 426 ( 427 $(# $attr_args:tt)* 428 const fn $($item:tt)* 429 ) => { 430 $(# $attr_args)* 431 const fn $($item)* 432 }; 433 ( 434 $(# $attr_args:tt)* 435 pub const fn $($item:tt)* 436 ) => { 437 $(# $attr_args)* 438 pub const fn $($item)* 439 }; 440 ( 441 $(# $attr_args:tt)* 442 pub const unsafe fn $($item:tt)* 443 ) => { 444 $(# $attr_args)* 445 pub const unsafe fn $($item)* 446 }; 447 } 448 449 #[macro_export(local_inner_macros)] 450 #[doc(hidden)] 451 #[cfg(not(bitflags_const_fn))] 452 macro_rules! __fn_bitflags { 453 ( 454 $(# $attr_args:tt)* 455 const fn $($item:tt)* 456 ) => { 457 $(# $attr_args)* 458 fn $($item)* 459 }; 460 ( 461 $(# $attr_args:tt)* 462 pub const fn $($item:tt)* 463 ) => { 464 $(# $attr_args)* 465 pub fn $($item)* 466 }; 467 ( 468 $(# $attr_args:tt)* 469 pub const unsafe fn $($item:tt)* 470 ) => { 471 $(# $attr_args)* 472 pub unsafe fn $($item)* 473 }; 474 } 475 476 #[macro_export(local_inner_macros)] 477 #[doc(hidden)] 478 macro_rules! __impl_bitflags { 479 ( 480 $BitFlags:ident: $T:ty { 481 $( 482 $(#[$attr:ident $($args:tt)*])* 483 $Flag:ident = $value:expr; 484 )+ 485 } 486 ) => { 487 impl $crate::_core::fmt::Debug for $BitFlags { 488 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 489 // This convoluted approach is to handle #[cfg]-based flag 490 // omission correctly. For example it needs to support: 491 // 492 // #[cfg(unix)] const A: Flag = /* ... */; 493 // #[cfg(windows)] const B: Flag = /* ... */; 494 495 // Unconditionally define a check for every flag, even disabled 496 // ones. 497 #[allow(non_snake_case)] 498 trait __BitFlags { 499 $( 500 #[inline] 501 fn $Flag(&self) -> bool { false } 502 )+ 503 } 504 505 // Conditionally override the check for just those flags that 506 // are not #[cfg]ed away. 507 impl __BitFlags for $BitFlags { 508 $( 509 __impl_bitflags! { 510 #[allow(deprecated)] 511 #[inline] 512 $(? #[$attr $($args)*])* 513 fn $Flag(&self) -> bool { 514 if Self::$Flag.bits == 0 && self.bits != 0 { 515 false 516 } else { 517 self.bits & Self::$Flag.bits == Self::$Flag.bits 518 } 519 } 520 } 521 )+ 522 } 523 524 let mut first = true; 525 $( 526 if <$BitFlags as __BitFlags>::$Flag(self) { 527 if !first { 528 f.write_str(" | ")?; 529 } 530 first = false; 531 f.write_str(__bitflags_stringify!($Flag))?; 532 } 533 )+ 534 let extra_bits = self.bits & !$BitFlags::all().bits(); 535 if extra_bits != 0 { 536 if !first { 537 f.write_str(" | ")?; 538 } 539 first = false; 540 f.write_str("0x")?; 541 $crate::_core::fmt::LowerHex::fmt(&extra_bits, f)?; 542 } 543 if first { 544 f.write_str("(empty)")?; 545 } 546 Ok(()) 547 } 548 } 549 impl $crate::_core::fmt::Binary for $BitFlags { 550 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 551 $crate::_core::fmt::Binary::fmt(&self.bits, f) 552 } 553 } 554 impl $crate::_core::fmt::Octal for $BitFlags { 555 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 556 $crate::_core::fmt::Octal::fmt(&self.bits, f) 557 } 558 } 559 impl $crate::_core::fmt::LowerHex for $BitFlags { 560 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 561 $crate::_core::fmt::LowerHex::fmt(&self.bits, f) 562 } 563 } 564 impl $crate::_core::fmt::UpperHex for $BitFlags { 565 fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result { 566 $crate::_core::fmt::UpperHex::fmt(&self.bits, f) 567 } 568 } 569 570 #[allow(dead_code)] 571 impl $BitFlags { 572 $( 573 $(#[$attr $($args)*])* 574 pub const $Flag: $BitFlags = $BitFlags { bits: $value }; 575 )+ 576 577 __fn_bitflags! { 578 /// Returns an empty set of flags 579 #[inline] 580 pub const fn empty() -> $BitFlags { 581 $BitFlags { bits: 0 } 582 } 583 } 584 585 __fn_bitflags! { 586 /// Returns the set containing all flags. 587 #[inline] 588 pub const fn all() -> $BitFlags { 589 // See `Debug::fmt` for why this approach is taken. 590 #[allow(non_snake_case)] 591 trait __BitFlags { 592 $( 593 const $Flag: $T = 0; 594 )+ 595 } 596 impl __BitFlags for $BitFlags { 597 $( 598 __impl_bitflags! { 599 #[allow(deprecated)] 600 $(? #[$attr $($args)*])* 601 const $Flag: $T = Self::$Flag.bits; 602 } 603 )+ 604 } 605 $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ } 606 } 607 } 608 609 __fn_bitflags! { 610 /// Returns the raw value of the flags currently stored. 611 #[inline] 612 pub const fn bits(&self) -> $T { 613 self.bits 614 } 615 } 616 617 /// Convert from underlying bit representation, unless that 618 /// representation contains bits that do not correspond to a flag. 619 #[inline] 620 pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> { 621 if (bits & !$BitFlags::all().bits()) == 0 { 622 $crate::_core::option::Option::Some($BitFlags { bits }) 623 } else { 624 $crate::_core::option::Option::None 625 } 626 } 627 628 __fn_bitflags! { 629 /// Convert from underlying bit representation, dropping any bits 630 /// that do not correspond to flags. 631 #[inline] 632 pub const fn from_bits_truncate(bits: $T) -> $BitFlags { 633 $BitFlags { bits: bits & $BitFlags::all().bits } 634 } 635 } 636 637 __fn_bitflags! { 638 /// Convert from underlying bit representation, preserving all 639 /// bits (even those not corresponding to a defined flag). 640 #[inline] 641 pub const unsafe fn from_bits_unchecked(bits: $T) -> $BitFlags { 642 $BitFlags { bits } 643 } 644 } 645 646 __fn_bitflags! { 647 /// Returns `true` if no flags are currently stored. 648 #[inline] 649 pub const fn is_empty(&self) -> bool { 650 self.bits() == $BitFlags::empty().bits() 651 } 652 } 653 654 __fn_bitflags! { 655 /// Returns `true` if all flags are currently set. 656 #[inline] 657 pub const fn is_all(&self) -> bool { 658 self.bits == $BitFlags::all().bits 659 } 660 } 661 662 __fn_bitflags! { 663 /// Returns `true` if there are flags common to both `self` and `other`. 664 #[inline] 665 pub const fn intersects(&self, other: $BitFlags) -> bool { 666 !$BitFlags{ bits: self.bits & other.bits}.is_empty() 667 } 668 } 669 670 __fn_bitflags! { 671 /// Returns `true` all of the flags in `other` are contained within `self`. 672 #[inline] 673 pub const fn contains(&self, other: $BitFlags) -> bool { 674 (self.bits & other.bits) == other.bits 675 } 676 } 677 678 /// Inserts the specified flags in-place. 679 #[inline] 680 pub fn insert(&mut self, other: $BitFlags) { 681 self.bits |= other.bits; 682 } 683 684 /// Removes the specified flags in-place. 685 #[inline] 686 pub fn remove(&mut self, other: $BitFlags) { 687 self.bits &= !other.bits; 688 } 689 690 /// Toggles the specified flags in-place. 691 #[inline] 692 pub fn toggle(&mut self, other: $BitFlags) { 693 self.bits ^= other.bits; 694 } 695 696 /// Inserts or removes the specified flags depending on the passed value. 697 #[inline] 698 pub fn set(&mut self, other: $BitFlags, value: bool) { 699 if value { 700 self.insert(other); 701 } else { 702 self.remove(other); 703 } 704 } 705 } 706 707 impl $crate::_core::ops::BitOr for $BitFlags { 708 type Output = $BitFlags; 709 710 /// Returns the union of the two sets of flags. 711 #[inline] 712 fn bitor(self, other: $BitFlags) -> $BitFlags { 713 $BitFlags { bits: self.bits | other.bits } 714 } 715 } 716 717 impl $crate::_core::ops::BitOrAssign for $BitFlags { 718 719 /// Adds the set of flags. 720 #[inline] 721 fn bitor_assign(&mut self, other: $BitFlags) { 722 self.bits |= other.bits; 723 } 724 } 725 726 impl $crate::_core::ops::BitXor for $BitFlags { 727 type Output = $BitFlags; 728 729 /// Returns the left flags, but with all the right flags toggled. 730 #[inline] 731 fn bitxor(self, other: $BitFlags) -> $BitFlags { 732 $BitFlags { bits: self.bits ^ other.bits } 733 } 734 } 735 736 impl $crate::_core::ops::BitXorAssign for $BitFlags { 737 738 /// Toggles the set of flags. 739 #[inline] 740 fn bitxor_assign(&mut self, other: $BitFlags) { 741 self.bits ^= other.bits; 742 } 743 } 744 745 impl $crate::_core::ops::BitAnd for $BitFlags { 746 type Output = $BitFlags; 747 748 /// Returns the intersection between the two sets of flags. 749 #[inline] 750 fn bitand(self, other: $BitFlags) -> $BitFlags { 751 $BitFlags { bits: self.bits & other.bits } 752 } 753 } 754 755 impl $crate::_core::ops::BitAndAssign for $BitFlags { 756 757 /// Disables all flags disabled in the set. 758 #[inline] 759 fn bitand_assign(&mut self, other: $BitFlags) { 760 self.bits &= other.bits; 761 } 762 } 763 764 impl $crate::_core::ops::Sub for $BitFlags { 765 type Output = $BitFlags; 766 767 /// Returns the set difference of the two sets of flags. 768 #[inline] 769 fn sub(self, other: $BitFlags) -> $BitFlags { 770 $BitFlags { bits: self.bits & !other.bits } 771 } 772 } 773 774 impl $crate::_core::ops::SubAssign for $BitFlags { 775 776 /// Disables all flags enabled in the set. 777 #[inline] 778 fn sub_assign(&mut self, other: $BitFlags) { 779 self.bits &= !other.bits; 780 } 781 } 782 783 impl $crate::_core::ops::Not for $BitFlags { 784 type Output = $BitFlags; 785 786 /// Returns the complement of this set of flags. 787 #[inline] 788 fn not(self) -> $BitFlags { 789 $BitFlags { bits: !self.bits } & $BitFlags::all() 790 } 791 } 792 793 impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags { 794 fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) { 795 for item in iterator { 796 self.insert(item) 797 } 798 } 799 } 800 801 impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags { 802 fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags { 803 let mut result = Self::empty(); 804 result.extend(iterator); 805 result 806 } 807 } 808 }; 809 810 // Every attribute that the user writes on a const is applied to the 811 // corresponding const that we generate, but within the implementation of 812 // Debug and all() we want to ignore everything but #[cfg] attributes. In 813 // particular, including a #[deprecated] attribute on those items would fail 814 // to compile. 815 // https://github.com/bitflags/bitflags/issues/109 816 // 817 // Input: 818 // 819 // ? #[cfg(feature = "advanced")] 820 // ? #[deprecated(note = "Use somthing else.")] 821 // ? #[doc = r"High quality documentation."] 822 // fn f() -> i32 { /* ... */ } 823 // 824 // Output: 825 // 826 // #[cfg(feature = "advanced")] 827 // fn f() -> i32 { /* ... */ } 828 ( 829 $(#[$filtered:meta])* 830 ? #[cfg $($cfgargs:tt)*] 831 $(? #[$rest:ident $($restargs:tt)*])* 832 fn $($item:tt)* 833 ) => { 834 __impl_bitflags! { 835 $(#[$filtered])* 836 #[cfg $($cfgargs)*] 837 $(? #[$rest $($restargs)*])* 838 fn $($item)* 839 } 840 }; 841 ( 842 $(#[$filtered:meta])* 843 // $next != `cfg` 844 ? #[$next:ident $($nextargs:tt)*] 845 $(? #[$rest:ident $($restargs:tt)*])* 846 fn $($item:tt)* 847 ) => { 848 __impl_bitflags! { 849 $(#[$filtered])* 850 // $next filtered out 851 $(? #[$rest $($restargs)*])* 852 fn $($item)* 853 } 854 }; 855 ( 856 $(#[$filtered:meta])* 857 fn $($item:tt)* 858 ) => { 859 $(#[$filtered])* 860 fn $($item)* 861 }; 862 863 // Every attribute that the user writes on a const is applied to the 864 // corresponding const that we generate, but within the implementation of 865 // Debug and all() we want to ignore everything but #[cfg] attributes. In 866 // particular, including a #[deprecated] attribute on those items would fail 867 // to compile. 868 // https://github.com/bitflags/bitflags/issues/109 869 // 870 // const version 871 // 872 // Input: 873 // 874 // ? #[cfg(feature = "advanced")] 875 // ? #[deprecated(note = "Use somthing else.")] 876 // ? #[doc = r"High quality documentation."] 877 // const f: i32 { /* ... */ } 878 // 879 // Output: 880 // 881 // #[cfg(feature = "advanced")] 882 // const f: i32 { /* ... */ } 883 ( 884 $(#[$filtered:meta])* 885 ? #[cfg $($cfgargs:tt)*] 886 $(? #[$rest:ident $($restargs:tt)*])* 887 const $($item:tt)* 888 ) => { 889 __impl_bitflags! { 890 $(#[$filtered])* 891 #[cfg $($cfgargs)*] 892 $(? #[$rest $($restargs)*])* 893 const $($item)* 894 } 895 }; 896 ( 897 $(#[$filtered:meta])* 898 // $next != `cfg` 899 ? #[$next:ident $($nextargs:tt)*] 900 $(? #[$rest:ident $($restargs:tt)*])* 901 const $($item:tt)* 902 ) => { 903 __impl_bitflags! { 904 $(#[$filtered])* 905 // $next filtered out 906 $(? #[$rest $($restargs)*])* 907 const $($item)* 908 } 909 }; 910 ( 911 $(#[$filtered:meta])* 912 const $($item:tt)* 913 ) => { 914 $(#[$filtered])* 915 const $($item)* 916 }; 917 } 918 919 // Same as std::stringify but callable from __impl_bitflags, which needs to use 920 // local_inner_macros so can only directly call macros from this crate. 921 #[macro_export] 922 #[doc(hidden)] 923 macro_rules! __bitflags_stringify { 924 ($s:ident) => { 925 stringify!($s) 926 }; 927 } 928 929 #[cfg(feature = "example_generated")] 930 pub mod example_generated; 931 932 #[cfg(test)] 933 mod tests { 934 use std::collections::hash_map::DefaultHasher; 935 use std::hash::{Hash, Hasher}; 936 937 bitflags! { 938 #[doc = "> The first principle is that you must not fool yourself — and"] 939 #[doc = "> you are the easiest person to fool."] 940 #[doc = "> "] 941 #[doc = "> - Richard Feynman"] 942 struct Flags: u32 { 943 const A = 0b00000001; 944 #[doc = "<pcwalton> macros are way better at generating code than trans is"] 945 const B = 0b00000010; 946 const C = 0b00000100; 947 #[doc = "* cmr bed"] 948 #[doc = "* strcat table"] 949 #[doc = "<strcat> wait what?"] 950 const ABC = Self::A.bits | Self::B.bits | Self::C.bits; 951 } 952 } 953 954 bitflags! { 955 struct _CfgFlags: u32 { 956 #[cfg(unix)] 957 const _CFG_A = 0b01; 958 #[cfg(windows)] 959 const _CFG_B = 0b01; 960 #[cfg(unix)] 961 const _CFG_C = Self::_CFG_A.bits | 0b10; 962 } 963 } 964 965 bitflags! { 966 struct AnotherSetOfFlags: i8 { 967 const ANOTHER_FLAG = -1_i8; 968 } 969 } 970 971 bitflags! { 972 struct LongFlags: u32 { 973 const LONG_A = 0b1111111111111111; 974 } 975 } 976 977 #[test] test_bits()978 fn test_bits() { 979 assert_eq!(Flags::empty().bits(), 0b00000000); 980 assert_eq!(Flags::A.bits(), 0b00000001); 981 assert_eq!(Flags::ABC.bits(), 0b00000111); 982 983 assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00); 984 assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8); 985 } 986 987 #[test] test_from_bits()988 fn test_from_bits() { 989 assert_eq!(Flags::from_bits(0), Some(Flags::empty())); 990 assert_eq!(Flags::from_bits(0b1), Some(Flags::A)); 991 assert_eq!(Flags::from_bits(0b10), Some(Flags::B)); 992 assert_eq!(Flags::from_bits(0b11), Some(Flags::A | Flags::B)); 993 assert_eq!(Flags::from_bits(0b1000), None); 994 995 assert_eq!( 996 AnotherSetOfFlags::from_bits(!0_i8), 997 Some(AnotherSetOfFlags::ANOTHER_FLAG) 998 ); 999 } 1000 1001 #[test] test_from_bits_truncate()1002 fn test_from_bits_truncate() { 1003 assert_eq!(Flags::from_bits_truncate(0), Flags::empty()); 1004 assert_eq!(Flags::from_bits_truncate(0b1), Flags::A); 1005 assert_eq!(Flags::from_bits_truncate(0b10), Flags::B); 1006 assert_eq!(Flags::from_bits_truncate(0b11), (Flags::A | Flags::B)); 1007 assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty()); 1008 assert_eq!(Flags::from_bits_truncate(0b1001), Flags::A); 1009 1010 assert_eq!( 1011 AnotherSetOfFlags::from_bits_truncate(0_i8), 1012 AnotherSetOfFlags::empty() 1013 ); 1014 } 1015 1016 #[test] test_from_bits_unchecked()1017 fn test_from_bits_unchecked() { 1018 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1019 assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty()); 1020 assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A); 1021 assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B); 1022 assert_eq!(unsafe { Flags::from_bits_unchecked(0b11) }, (Flags::A | Flags::B)); 1023 assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty())); 1024 assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A)); 1025 } 1026 1027 #[test] test_is_empty()1028 fn test_is_empty() { 1029 assert!(Flags::empty().is_empty()); 1030 assert!(!Flags::A.is_empty()); 1031 assert!(!Flags::ABC.is_empty()); 1032 1033 assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty()); 1034 } 1035 1036 #[test] test_is_all()1037 fn test_is_all() { 1038 assert!(Flags::all().is_all()); 1039 assert!(!Flags::A.is_all()); 1040 assert!(Flags::ABC.is_all()); 1041 1042 assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all()); 1043 } 1044 1045 #[test] test_two_empties_do_not_intersect()1046 fn test_two_empties_do_not_intersect() { 1047 let e1 = Flags::empty(); 1048 let e2 = Flags::empty(); 1049 assert!(!e1.intersects(e2)); 1050 1051 assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG)); 1052 } 1053 1054 #[test] test_empty_does_not_intersect_with_full()1055 fn test_empty_does_not_intersect_with_full() { 1056 let e1 = Flags::empty(); 1057 let e2 = Flags::ABC; 1058 assert!(!e1.intersects(e2)); 1059 } 1060 1061 #[test] test_disjoint_intersects()1062 fn test_disjoint_intersects() { 1063 let e1 = Flags::A; 1064 let e2 = Flags::B; 1065 assert!(!e1.intersects(e2)); 1066 } 1067 1068 #[test] test_overlapping_intersects()1069 fn test_overlapping_intersects() { 1070 let e1 = Flags::A; 1071 let e2 = Flags::A | Flags::B; 1072 assert!(e1.intersects(e2)); 1073 } 1074 1075 #[test] test_contains()1076 fn test_contains() { 1077 let e1 = Flags::A; 1078 let e2 = Flags::A | Flags::B; 1079 assert!(!e1.contains(e2)); 1080 assert!(e2.contains(e1)); 1081 assert!(Flags::ABC.contains(e2)); 1082 1083 assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG)); 1084 } 1085 1086 #[test] test_insert()1087 fn test_insert() { 1088 let mut e1 = Flags::A; 1089 let e2 = Flags::A | Flags::B; 1090 e1.insert(e2); 1091 assert_eq!(e1, e2); 1092 1093 let mut e3 = AnotherSetOfFlags::empty(); 1094 e3.insert(AnotherSetOfFlags::ANOTHER_FLAG); 1095 assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG); 1096 } 1097 1098 #[test] test_remove()1099 fn test_remove() { 1100 let mut e1 = Flags::A | Flags::B; 1101 let e2 = Flags::A | Flags::C; 1102 e1.remove(e2); 1103 assert_eq!(e1, Flags::B); 1104 1105 let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG; 1106 e3.remove(AnotherSetOfFlags::ANOTHER_FLAG); 1107 assert_eq!(e3, AnotherSetOfFlags::empty()); 1108 } 1109 1110 #[test] test_operators()1111 fn test_operators() { 1112 let e1 = Flags::A | Flags::C; 1113 let e2 = Flags::B | Flags::C; 1114 assert_eq!((e1 | e2), Flags::ABC); // union 1115 assert_eq!((e1 & e2), Flags::C); // intersection 1116 assert_eq!((e1 - e2), Flags::A); // set difference 1117 assert_eq!(!e2, Flags::A); // set complement 1118 assert_eq!(e1 ^ e2, Flags::A | Flags::B); // toggle 1119 let mut e3 = e1; 1120 e3.toggle(e2); 1121 assert_eq!(e3, Flags::A | Flags::B); 1122 1123 let mut m4 = AnotherSetOfFlags::empty(); 1124 m4.toggle(AnotherSetOfFlags::empty()); 1125 assert_eq!(m4, AnotherSetOfFlags::empty()); 1126 } 1127 1128 #[test] test_operators_unchecked()1129 fn test_operators_unchecked() { 1130 let extra = unsafe { Flags::from_bits_unchecked(0b1000) }; 1131 let e1 = Flags::A | Flags::C | extra; 1132 let e2 = Flags::B | Flags::C; 1133 assert_eq!((e1 | e2), (Flags::ABC | extra)); // union 1134 assert_eq!((e1 & e2), Flags::C); // intersection 1135 assert_eq!((e1 - e2), (Flags::A | extra)); // set difference 1136 assert_eq!(!e2, Flags::A); // set complement 1137 assert_eq!(!e1, Flags::B); // set complement 1138 assert_eq!(e1 ^ e2, Flags::A | Flags::B | extra); // toggle 1139 let mut e3 = e1; 1140 e3.toggle(e2); 1141 assert_eq!(e3, Flags::A | Flags::B | extra); 1142 } 1143 1144 #[test] test_set()1145 fn test_set() { 1146 let mut e1 = Flags::A | Flags::C; 1147 e1.set(Flags::B, true); 1148 e1.set(Flags::C, false); 1149 1150 assert_eq!(e1, Flags::A | Flags::B); 1151 } 1152 1153 #[test] test_assignment_operators()1154 fn test_assignment_operators() { 1155 let mut m1 = Flags::empty(); 1156 let e1 = Flags::A | Flags::C; 1157 // union 1158 m1 |= Flags::A; 1159 assert_eq!(m1, Flags::A); 1160 // intersection 1161 m1 &= e1; 1162 assert_eq!(m1, Flags::A); 1163 // set difference 1164 m1 -= m1; 1165 assert_eq!(m1, Flags::empty()); 1166 // toggle 1167 m1 ^= e1; 1168 assert_eq!(m1, e1); 1169 } 1170 1171 1172 #[cfg(bitflags_const_fn)] 1173 #[test] test_const_fn()1174 fn test_const_fn() { 1175 const _M1: Flags = Flags::empty(); 1176 1177 const M2: Flags = Flags::A; 1178 assert_eq!(M2, Flags::A); 1179 1180 const M3: Flags = Flags::C; 1181 assert_eq!(M3, Flags::C); 1182 } 1183 1184 #[test] test_extend()1185 fn test_extend() { 1186 let mut flags; 1187 1188 flags = Flags::empty(); 1189 flags.extend([].iter().cloned()); 1190 assert_eq!(flags, Flags::empty()); 1191 1192 flags = Flags::empty(); 1193 flags.extend([Flags::A, Flags::B].iter().cloned()); 1194 assert_eq!(flags, Flags::A | Flags::B); 1195 1196 flags = Flags::A; 1197 flags.extend([Flags::A, Flags::B].iter().cloned()); 1198 assert_eq!(flags, Flags::A | Flags::B); 1199 1200 flags = Flags::B; 1201 flags.extend([Flags::A, Flags::ABC].iter().cloned()); 1202 assert_eq!(flags, Flags::ABC); 1203 } 1204 1205 #[test] test_from_iterator()1206 fn test_from_iterator() { 1207 assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty()); 1208 assert_eq!( 1209 [Flags::A, Flags::B].iter().cloned().collect::<Flags>(), 1210 Flags::A | Flags::B 1211 ); 1212 assert_eq!( 1213 [Flags::A, Flags::ABC].iter().cloned().collect::<Flags>(), 1214 Flags::ABC 1215 ); 1216 } 1217 1218 #[test] test_lt()1219 fn test_lt() { 1220 let mut a = Flags::empty(); 1221 let mut b = Flags::empty(); 1222 1223 assert!(!(a < b) && !(b < a)); 1224 b = Flags::B; 1225 assert!(a < b); 1226 a = Flags::C; 1227 assert!(!(a < b) && b < a); 1228 b = Flags::C | Flags::B; 1229 assert!(a < b); 1230 } 1231 1232 #[test] test_ord()1233 fn test_ord() { 1234 let mut a = Flags::empty(); 1235 let mut b = Flags::empty(); 1236 1237 assert!(a <= b && a >= b); 1238 a = Flags::A; 1239 assert!(a > b && a >= b); 1240 assert!(b < a && b <= a); 1241 b = Flags::B; 1242 assert!(b > a && b >= a); 1243 assert!(a < b && a <= b); 1244 } 1245 hash<T: Hash>(t: &T) -> u641246 fn hash<T: Hash>(t: &T) -> u64 { 1247 let mut s = DefaultHasher::new(); 1248 t.hash(&mut s); 1249 s.finish() 1250 } 1251 1252 #[test] test_hash()1253 fn test_hash() { 1254 let mut x = Flags::empty(); 1255 let mut y = Flags::empty(); 1256 assert_eq!(hash(&x), hash(&y)); 1257 x = Flags::all(); 1258 y = Flags::ABC; 1259 assert_eq!(hash(&x), hash(&y)); 1260 } 1261 1262 #[test] test_debug()1263 fn test_debug() { 1264 assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B"); 1265 assert_eq!(format!("{:?}", Flags::empty()), "(empty)"); 1266 assert_eq!(format!("{:?}", Flags::ABC), "A | B | C | ABC"); 1267 let extra = unsafe { Flags::from_bits_unchecked(0xb8) }; 1268 assert_eq!(format!("{:?}", extra), "0xb8"); 1269 assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8"); 1270 assert_eq!(format!("{:?}", Flags::ABC | extra), "A | B | C | ABC | 0xb8"); 1271 } 1272 1273 #[test] test_binary()1274 fn test_binary() { 1275 assert_eq!(format!("{:b}", Flags::ABC), "111"); 1276 assert_eq!(format!("{:#b}", Flags::ABC), "0b111"); 1277 let extra = unsafe { Flags::from_bits_unchecked(0b1010000) }; 1278 assert_eq!(format!("{:b}", Flags::ABC | extra), "1010111"); 1279 assert_eq!(format!("{:#b}", Flags::ABC | extra), "0b1010111"); 1280 } 1281 1282 #[test] test_octal()1283 fn test_octal() { 1284 assert_eq!(format!("{:o}", LongFlags::LONG_A), "177777"); 1285 assert_eq!(format!("{:#o}", LongFlags::LONG_A), "0o177777"); 1286 let extra = unsafe { LongFlags::from_bits_unchecked(0o5000000) }; 1287 assert_eq!(format!("{:o}", LongFlags::LONG_A | extra), "5177777"); 1288 assert_eq!(format!("{:#o}", LongFlags::LONG_A | extra), "0o5177777"); 1289 } 1290 1291 #[test] test_lowerhex()1292 fn test_lowerhex() { 1293 assert_eq!(format!("{:x}", LongFlags::LONG_A), "ffff"); 1294 assert_eq!(format!("{:#x}", LongFlags::LONG_A), "0xffff"); 1295 let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; 1296 assert_eq!(format!("{:x}", LongFlags::LONG_A | extra), "e0ffff"); 1297 assert_eq!(format!("{:#x}", LongFlags::LONG_A | extra), "0xe0ffff"); 1298 } 1299 1300 #[test] test_upperhex()1301 fn test_upperhex() { 1302 assert_eq!(format!("{:X}", LongFlags::LONG_A), "FFFF"); 1303 assert_eq!(format!("{:#X}", LongFlags::LONG_A), "0xFFFF"); 1304 let extra = unsafe { LongFlags::from_bits_unchecked(0xe00000) }; 1305 assert_eq!(format!("{:X}", LongFlags::LONG_A | extra), "E0FFFF"); 1306 assert_eq!(format!("{:#X}", LongFlags::LONG_A | extra), "0xE0FFFF"); 1307 } 1308 1309 mod submodule { 1310 bitflags! { 1311 pub struct PublicFlags: i8 { 1312 const X = 0; 1313 } 1314 } 1315 bitflags! { 1316 struct PrivateFlags: i8 { 1317 const Y = 0; 1318 } 1319 } 1320 1321 #[test] test_private()1322 fn test_private() { 1323 let _ = PrivateFlags::Y; 1324 } 1325 } 1326 1327 #[test] test_public()1328 fn test_public() { 1329 let _ = submodule::PublicFlags::X; 1330 } 1331 1332 mod t1 { 1333 mod foo { 1334 pub type Bar = i32; 1335 } 1336 1337 bitflags! { 1338 /// baz 1339 struct Flags: foo::Bar { 1340 const A = 0b00000001; 1341 #[cfg(foo)] 1342 const B = 0b00000010; 1343 #[cfg(foo)] 1344 const C = 0b00000010; 1345 } 1346 } 1347 } 1348 1349 #[test] test_in_function()1350 fn test_in_function() { 1351 bitflags! { 1352 struct Flags: u8 { 1353 const A = 1; 1354 #[cfg(any())] // false 1355 const B = 2; 1356 } 1357 } 1358 assert_eq!(Flags::all(), Flags::A); 1359 assert_eq!(format!("{:?}", Flags::A), "A"); 1360 } 1361 1362 #[test] test_deprecated()1363 fn test_deprecated() { 1364 bitflags! { 1365 pub struct TestFlags: u32 { 1366 #[deprecated(note = "Use something else.")] 1367 const ONE = 1; 1368 } 1369 } 1370 } 1371 1372 #[test] test_pub_crate()1373 fn test_pub_crate() { 1374 mod module { 1375 bitflags! { 1376 pub (crate) struct Test: u8 { 1377 const FOO = 1; 1378 } 1379 } 1380 } 1381 1382 assert_eq!(module::Test::FOO.bits(), 1); 1383 } 1384 1385 #[test] test_pub_in_module()1386 fn test_pub_in_module() { 1387 mod module { 1388 mod submodule { 1389 bitflags! { 1390 // `pub (in super)` means only the module `module` will 1391 // be able to access this. 1392 pub (in super) struct Test: u8 { 1393 const FOO = 1; 1394 } 1395 } 1396 } 1397 1398 mod test { 1399 // Note: due to `pub (in super)`, 1400 // this cannot be accessed directly by the testing code. 1401 pub(super) fn value() -> u8 { 1402 super::submodule::Test::FOO.bits() 1403 } 1404 } 1405 1406 pub fn value() -> u8 { 1407 test::value() 1408 } 1409 } 1410 1411 assert_eq!(module::value(), 1) 1412 } 1413 1414 #[test] test_zero_value_flags()1415 fn test_zero_value_flags() { 1416 bitflags! { 1417 struct Flags: u32 { 1418 const NONE = 0b0; 1419 const SOME = 0b1; 1420 } 1421 } 1422 1423 assert!(Flags::empty().contains(Flags::NONE)); 1424 assert!(Flags::SOME.contains(Flags::NONE)); 1425 assert!(Flags::NONE.is_empty()); 1426 1427 assert_eq!(format!("{:?}", Flags::empty()), "NONE"); 1428 assert_eq!(format!("{:?}", Flags::SOME), "SOME"); 1429 } 1430 } 1431