diff options
| author | bors <bors@rust-lang.org> | 2014-08-19 08:35:55 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-08-19 08:35:55 +0000 |
| commit | 9af4e325af28f6859bff1c1dd52c68a321dd337d (patch) | |
| tree | 1d61655ef6d09d130888b208d0508395da68cf9f | |
| parent | d16a5cd7c4d37c947faf4661b22e994409197809 (diff) | |
| parent | dcccf824b1096cc596671724ebf42b8d3ed35705 (diff) | |
| download | rust-9af4e325af28f6859bff1c1dd52c68a321dd337d.tar.gz rust-9af4e325af28f6859bff1c1dd52c68a321dd337d.zip | |
auto merge of #16582 : Gankro/rust/bitv, r=alexcrichton
This was bothering me (and some other people). The macro was necessary in a transient step of my development, but I converged on a design where it was unnecessary, but it didn't really click that that had happened. This fixes it up.
| -rw-r--r-- | src/libcollections/bitv.rs | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index 1b3c6e148cd..e89d66578b0 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -66,7 +66,7 @@ use core::prelude::*; use core::cmp; use core::default::Default; use core::fmt; -use core::iter::Take; +use core::iter::{Chain, Enumerate, Repeat, Skip, Take}; use core::iter; use core::slice; use core::uint; @@ -75,25 +75,22 @@ use std::hash; use {Mutable, Set, MutableSet, MutableSeq}; use vec::Vec; +type MatchWords<'a> = Chain<MaskWords<'a>, Skip<Take<Enumerate<Repeat<uint>>>>>; // Take two BitV's, and return iterators of their words, where the shorter one // has been padded with 0's -macro_rules! match_words( - ($a_expr:expr, $b_expr:expr) => ({ - let a = $a_expr; - let b = $b_expr; - let a_len = a.storage.len(); - let b_len = b.storage.len(); - - // have to uselessly pretend to pad the longer one for type matching - if a_len < b_len { - (a.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(b_len).skip(a_len)), - b.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(0).skip(0))) - } else { - (a.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(0).skip(0)), - b.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(a_len).skip(b_len))) - } - }) -) +fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) { + let a_len = a.storage.len(); + let b_len = b.storage.len(); + + // have to uselessly pretend to pad the longer one for type matching + if a_len < b_len { + (a.mask_words(0).chain(Repeat::new(0u).enumerate().take(b_len).skip(a_len)), + b.mask_words(0).chain(Repeat::new(0u).enumerate().take(0).skip(0))) + } else { + (a.mask_words(0).chain(Repeat::new(0u).enumerate().take(0).skip(0)), + b.mask_words(0).chain(Repeat::new(0u).enumerate().take(a_len).skip(b_len))) + } +} static TRUE: bool = true; static FALSE: bool = false; @@ -1014,7 +1011,7 @@ impl Extendable<bool> for BitvSet { impl PartialOrd for BitvSet { #[inline] fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> { - let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref()); + let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::partial_cmp(a_iter, b_iter) } } @@ -1022,7 +1019,7 @@ impl PartialOrd for BitvSet { impl Ord for BitvSet { #[inline] fn cmp(&self, other: &BitvSet) -> Ordering { - let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref()); + let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::cmp(a_iter, b_iter) } } @@ -1030,7 +1027,7 @@ impl Ord for BitvSet { impl cmp::PartialEq for BitvSet { #[inline] fn eq(&self, other: &BitvSet) -> bool { - let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref()); + let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref()); iter::order::eq(a_iter, b_iter) } } @@ -1191,10 +1188,10 @@ impl BitvSet { self_bitv.reserve(other_bitv.capacity()); // virtually pad other with 0's for equal lengths - let self_len = self_bitv.storage.len(); - let other_len = other_bitv.storage.len(); - let mut other_words = other_bitv.mask_words(0) - .chain(iter::Repeat::new(0u).enumerate().take(self_len).skip(other_len)); + let mut other_words = { + let (_, result) = match_words(self_bitv, other_bitv); + result + }; // Apply values found in other for (i, w) in other_words { @@ -1524,7 +1521,7 @@ impl Set<uint> for BitvSet { #[inline] fn is_disjoint(&self, other: &BitvSet) -> bool { - self.intersection(other).count() > 0 + self.intersection(other).next().is_none() } #[inline] @@ -2267,6 +2264,24 @@ mod tests { } #[test] + fn test_bitv_set_is_disjoint() { + let a = BitvSet::from_bitv(from_bytes([0b10100010])); + let b = BitvSet::from_bitv(from_bytes([0b01000000])); + let c = BitvSet::new(); + let d = BitvSet::from_bitv(from_bytes([0b00110000])); + + assert!(!a.is_disjoint(&d)); + assert!(!d.is_disjoint(&a)); + + assert!(a.is_disjoint(&b)) + assert!(a.is_disjoint(&c)) + assert!(b.is_disjoint(&a)) + assert!(b.is_disjoint(&c)) + assert!(c.is_disjoint(&a)) + assert!(c.is_disjoint(&b)) + } + + #[test] fn test_bitv_set_intersect_with() { // Explicitly 0'ed bits let mut a = BitvSet::from_bitv(from_bytes([0b10100010])); |
