From 1dd8f0c631020f3fff78aad6dc85e818ea4b7c71 Mon Sep 17 00:00:00 2001 From: wirelyre Date: Sun, 2 Feb 2020 18:45:14 -0600 Subject: [PATCH] Add `toggle_range` --- src/lib.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 368eccf..46fd017 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -198,7 +198,7 @@ impl FixedBitSet /// Sets every bit in the given range to the given state (`enabled`) /// - /// Use `..` to toggle the whole bitset. + /// Use `..` to set the whole bitset. /// /// **Panics** if the range extends past the end of the bitset. #[inline] @@ -226,6 +226,21 @@ impl FixedBitSet self.set_range(range, true); } + /// Toggles (inverts) every bit in the given range. + /// + /// Use `..` to toggle the whole bitset. + /// + /// **Panics** if the range extends past the end of the bitset. + #[inline] + pub fn toggle_range(&mut self, range: T) + { + for (block, mask) in Masks::new(range, self.length) { + unsafe { + *self.data.get_unchecked_mut(block) ^= mask; + } + } + } + /// View the bitset as a slice of `u32` blocks #[inline] pub fn as_slice(&self) -> &[u32] @@ -885,6 +900,22 @@ fn set_range() { assert!(!fb.contains(64)); } +#[test] +fn toggle_range() { + let mut fb = FixedBitSet::with_capacity(40); + fb.insert_range(..10); + fb.insert_range(34..38); + + fb.toggle_range(5..12); + fb.toggle_range(30..); + + for i in 0..40 { + assert_eq!(fb.contains(i), i<5 || 10<=i&&i<12 || 30<=i&&i<34 || 38<=i); + } + assert!(!fb.contains(40)); + assert!(!fb.contains(64)); +} + #[test] fn bitand_equal_lengths() { let len = 109;