about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-08-04 04:49:44 +0200
committerblake2-ppc <blake2-ppc>2013-08-06 04:05:08 +0200
commit08d0b70213df7e112409eeea85bcfcc630f5dda4 (patch)
tree606b4c6264d3ed8fad803f3f593188d755b6eb2f /src
parentb5cd81d0e54fb2310ce0de6f746957501130ce5f (diff)
downloadrust-08d0b70213df7e112409eeea85bcfcc630f5dda4.tar.gz
rust-08d0b70213df7e112409eeea85bcfcc630f5dda4.zip
extra: Simplify the bitv iterators using Repeat
Diffstat (limited to 'src')
-rw-r--r--src/libextra/bitv.rs63
1 files changed, 19 insertions, 44 deletions
diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs
index bf618d7bd3a..f32170a3a6d 100644
--- a/src/libextra/bitv.rs
+++ b/src/libextra/bitv.rs
@@ -13,7 +13,7 @@
 
 use std::cmp;
 use std::iterator::RandomAccessIterator;
-use std::iterator::{Invert, Enumerate};
+use std::iterator::{Invert, Enumerate, Repeat, Map, Zip};
 use std::num;
 use std::ops;
 use std::uint;
@@ -864,13 +864,12 @@ impl BitvSet {
     /// w1, w2) where the bit location is the number of bits offset so far,
     /// and w1/w2 are the words coming from the two vectors self, other.
     fn common_iter<'a>(&'a self, other: &'a BitvSet)
-        -> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate<vec::VecIterator<'a,uint>>> {
-        let min = num::min(self.bitv.storage.len(),
-                            other.bitv.storage.len());
-        MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(),
-             env: &other.bitv.storage,
-             f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i])
-        }
+        -> Map<'static, ((uint, &'a uint), &'a ~[uint]), (uint, uint, uint),
+               Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<&'a ~[uint]>>> {
+        let min = num::min(self.bitv.storage.len(), other.bitv.storage.len());
+        self.bitv.storage.slice(0, min).iter().enumerate()
+            .zip(Repeat::new(&other.bitv.storage))
+            .transform(|((i, &w), o_store)| (i * uint::bits, w, o_store[i]))
     }
 
     /// Visits each word in self or other that extends beyond the other. This
@@ -881,45 +880,21 @@ impl BitvSet {
     /// is true if the word comes from 'self', and false if it comes from
     /// 'other'.
     fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
-        -> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate<vec::VecIterator<'a, uint>>> {
-        let len1 = self.bitv.storage.len();
-        let len2 = other.bitv.storage.len();
-        let min = num::min(len1, len2);
-
-        if min < len1 {
-            MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(),
-                 env: min,
-                 f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w)
-            }
+        -> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
+               Zip<Enumerate<vec::VecIterator<'a, uint>>, Repeat<uint>>> {
+        let slen = self.bitv.storage.len();
+        let olen = other.bitv.storage.len();
+
+        if olen < slen {
+            self.bitv.storage.slice_from(olen).iter().enumerate()
+                .zip(Repeat::new(olen))
+                .transform(|((i, &w), min)| (true, (i + min) * uint::bits, w))
         } else {
-            MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(),
-                 env: min,
-                 f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w)
-            }
-        }
-    }
-}
-
-/// Like iterator::Map with explicit env capture
-struct MapE<A, B, Env, I> {
-    priv env: Env,
-    priv f: &'static fn(A, Env) -> B,
-    priv iter: I,
-}
-
-impl<'self, A, B, Env: Clone, I: Iterator<A>> Iterator<B> for MapE<A, B, Env, I> {
-    #[inline]
-    fn next(&mut self) -> Option<B> {
-        match self.iter.next() {
-            Some(elt) => Some((self.f)(elt, self.env.clone())),
-            None => None
+            other.bitv.storage.slice_from(slen).iter().enumerate()
+                .zip(Repeat::new(slen))
+                .transform(|((i, &w), min)| (false, (i + min) * uint::bits, w))
         }
     }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        self.iter.size_hint()
-    }
 }
 
 pub struct BitvSetIterator<'self> {