blob: 7b01db01cdd4b4f6822f9f7fcf53fd48e171737a [file] [log] [blame]
Jason Macnakefaa0952019-12-12 22:33:33 +00001// 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
Matthew Maurer541fa022020-07-06 13:12:51 -0700256// ANDROID: Unconditionally use std to allow building as a dylib
Jason Macnakefaa0952019-12-12 22:33:33 +0000257#[macro_use]
258extern 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)]
263pub 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)]
333macro_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)]
395macro_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)]
425macro_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))]
452macro_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)]
478macro_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)]
923macro_rules! __bitflags_stringify {
924 ($s:ident) => {
925 stringify!($s)
926 };
927}
928
929#[cfg(feature = "example_generated")]
930pub mod example_generated;
931
932#[cfg(test)]
933mod 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]
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]
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]
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]
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]
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]
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]
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]
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]
1062 fn test_disjoint_intersects() {
1063 let e1 = Flags::A;
1064 let e2 = Flags::B;
1065 assert!(!e1.intersects(e2));
1066 }
1067
1068 #[test]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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
1246 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]
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]
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]
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]
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]
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]
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]
1322 fn test_private() {
1323 let _ = PrivateFlags::Y;
1324 }
1325 }
1326
1327 #[test]
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]
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]
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]
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]
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]
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}