From 1595885501897a2827d11afa193adda8771a967d Mon Sep 17 00:00:00 2001 From: "J.C. Moyer" Date: Wed, 7 May 2014 01:54:44 -0400 Subject: [PATCH] Implement set complement and universe for bitflags --- src/libstd/bitflags.rs | 32 +++++++++++++++++++++++++++++++- src/libstd/io/mod.rs | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index 5737bc772df02..c970448517331 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -34,6 +34,7 @@ //! assert!((e1 | e2) == FlagABC); // union //! assert!((e1 & e2) == FlagC); // intersection //! assert!((e1 - e2) == FlagA); // set difference +//! assert!(!e2 == FlagA); // set complement //! } //! ~~~ //! @@ -88,14 +89,17 @@ //! - `BitOr`: union //! - `BitAnd`: intersection //! - `Sub`: set difference +//! - `Not`: set complement //! //! # Methods //! //! The following methods are defined for the generated `struct`: //! //! - `empty`: an empty set of flags +//! - `all`: the set of all flags //! - `bits`: the raw value of the flags currently stored //! - `is_empty`: `true` if no flags are currently stored +//! - `is_all`: `true` if all flags are currently set //! - `intersects`: `true` if there are flags common to both `self` and `other` //! - `contains`: `true` all of the flags in `other` are contained within `self` //! - `insert`: inserts the specified flags in-place @@ -122,6 +126,11 @@ macro_rules! bitflags( $BitFlags { bits: 0 } } + /// Returns the set containing all flags. + pub fn all() -> $BitFlags { + $BitFlags { bits: $($value)|+ } + } + /// Returns the raw value of the flags currently stored. pub fn bits(&self) -> $T { self.bits @@ -138,6 +147,11 @@ macro_rules! bitflags( *self == $BitFlags::empty() } + /// Returns `true` if all flags are currently set. + pub fn is_all(&self) -> bool { + *self == $BitFlags::all() + } + /// Returns `true` if there are flags common to both `self` and `other`. pub fn intersects(&self, other: $BitFlags) -> bool { !(self & other).is_empty() @@ -182,12 +196,20 @@ macro_rules! bitflags( $BitFlags { bits: self.bits & !other.bits } } } + + impl Not<$BitFlags> for $BitFlags { + /// Returns the complement of this set of flags. + #[inline] + fn not(&self) -> $BitFlags { + $BitFlags { bits: !self.bits } & $BitFlags::all() + } + } ) ) #[cfg(test)] mod tests { - use ops::{BitOr, BitAnd, Sub}; + use ops::{BitOr, BitAnd, Sub, Not}; bitflags!( flags Flags: u32 { @@ -214,6 +236,13 @@ mod tests { assert!(!FlagABC.is_empty()); } + #[test] + fn test_is_all() { + assert!(Flags::all().is_all()); + assert!(!FlagA.is_all()); + assert!(FlagABC.is_all()); + } + #[test] fn test_two_empties_do_not_intersect() { let e1 = Flags::empty(); @@ -274,5 +303,6 @@ mod tests { assert!((e1 | e2) == FlagABC); // union assert!((e1 & e2) == FlagC); // intersection assert!((e1 - e2) == FlagA); // set difference + assert!(!e2 == FlagA); // set complement } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 0f8e37b4ee011..19eb0100ff714 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -220,7 +220,7 @@ use int; use iter::Iterator; use libc; use mem::transmute; -use ops::{BitOr, BitAnd, Sub}; +use ops::{BitOr, BitAnd, Sub, Not}; use option::{Option, Some, None}; use os; use owned::Box;