about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexis Beingessner <a.beingessner@gmail.com>2014-08-18 11:53:07 -0400
committerAlexis Beingessner <a.beingessner@gmail.com>2014-08-18 14:23:27 -0400
commit40c45169b7b280bbe27380fc5f1c350d25946ec2 (patch)
treead645c7cbb0a3a814368cfe5f03439ad1ca723a0
parent8c9bdda89b93bcb4c3b0ffb1b91b9c73318c5304 (diff)
downloadrust-40c45169b7b280bbe27380fc5f1c350d25946ec2.tar.gz
rust-40c45169b7b280bbe27380fc5f1c350d25946ec2.zip
Refactor BitV internals to not use macro, reduce duplication
-rw-r--r--src/libcollections/bitv.rs47
1 files changed, 22 insertions, 25 deletions
diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs
index 864ae5b5352..800f9832226 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::ops::Index;
 use core::slice;
@@ -76,25 +76,22 @@ use std::hash;
 use {Collection, 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;
@@ -1015,7 +1012,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)
     }
 }
@@ -1023,7 +1020,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)
     }
 }
@@ -1031,7 +1028,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)
     }
 }
@@ -1192,10 +1189,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 {