about summary refs log tree commit diff
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-07-06 05:42:45 +0200
committerblake2-ppc <blake2-ppc>2013-07-06 07:26:04 +0200
commit75015c36f9fa6d0958874c1a448d6d67056145ae (patch)
tree6a1f20a7e3d57d526fb453687828226290bcf4e3
parentf88d532734dbddecf81bc1d0ce51d30cb9fc9731 (diff)
downloadrust-75015c36f9fa6d0958874c1a448d6d67056145ae.tar.gz
rust-75015c36f9fa6d0958874c1a448d6d67056145ae.zip
deque: Change iterators to use the same index calculation as Deque
The previous implementation of reverse iterators used modulus (%) of
negative indices, which did work but was fragile due to dependency on
the divisor.
-rw-r--r--src/libextra/deque.rs78
1 files changed, 39 insertions, 39 deletions
diff --git a/src/libextra/deque.rs b/src/libextra/deque.rs
index bd7b9d5b51d..e8f8a31d7be 100644
--- a/src/libextra/deque.rs
+++ b/src/libextra/deque.rs
@@ -12,7 +12,6 @@
 
 use std::uint;
 use std::vec;
-use std::cast::transmute;
 use std::iterator::FromIterator;
 
 static INITIAL_CAPACITY: uint = 32u; // 2^5
@@ -92,13 +91,9 @@ impl<T> Deque<T> {
         result
     }
 
-    /// Return index in underlying vec for element index
+    /// Return index in underlying vec for a given logical element index
     fn raw_index(&self, idx: uint) -> uint {
-        if self.lo >= self.elts.len() - idx {
-            (self.lo + idx) - self.elts.len()
-        } else {
-            (self.lo + idx)
-        }
+        raw_index(self.lo, self.elts.len(), idx)
     }
 
     /// Remove and return the last element in the deque
@@ -159,42 +154,39 @@ impl<T> Deque<T> {
 
     /// Front-to-back iterator.
     pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> {
-    DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
+        DequeIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
     }
 
     /// Front-to-back iterator which returns mutable values.
     pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> {
-    DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
+        DequeMutIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
     }
 
     /// Back-to-front iterator.
     pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> {
-    DequeRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts }
+        DequeRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
+                         lo: self.lo}
     }
 
     /// Back-to-front iterator which returns mutable values.
     pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> {
-    DequeMutRevIterator { idx: self.raw_index(self.nelts-1), nelts: self.nelts, used: 0, vec: self.elts }
+        DequeMutRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
+                            lo: self.lo}
     }
 }
 
 macro_rules! iterator {
-    (impl $name:ident -> $elem:ty, $step:expr) => {
+    (impl $name:ident -> $elem:ty, $getter:ident, $step:expr) => {
         impl<'self, T> Iterator<$elem> for $name<'self, T> {
             #[inline]
             fn next(&mut self) -> Option<$elem> {
-                if self.used >= self.nelts {
+                if self.nelts == 0 {
                     return None;
                 }
-                let ret = unsafe {
-                    match self.vec[self.idx % self.vec.len()] {
-                        Some(ref e) => Some(transmute(e)),
-                        None => None
-                    }
-                };
-                self.idx += $step;
-                self.used += 1;
-                ret
+                let raw_index = raw_index(self.lo, self.elts.len(), self.index);
+                self.index += $step;
+                self.nelts -= 1;
+                Some(self.elts[raw_index]. $getter ())
             }
         }
     }
@@ -202,40 +194,39 @@ macro_rules! iterator {
 
 /// Deque iterator
 pub struct DequeIterator<'self, T> {
-    priv idx: uint,
+    priv lo: uint,
     priv nelts: uint,
-    priv used: uint,
-    priv vec: &'self [Option<T>]
+    priv index: uint,
+    priv elts: &'self [Option<T>],
 }
-iterator!{impl DequeIterator -> &'self T, 1}
+iterator!{impl DequeIterator -> &'self T, get_ref, 1}
 
 /// Deque reverse iterator
 pub struct DequeRevIterator<'self, T> {
-    priv idx: uint,
+    priv lo: uint,
     priv nelts: uint,
-    priv used: uint,
-    priv vec: &'self [Option<T>]
+    priv index: uint,
+    priv elts: &'self [Option<T>],
 }
-iterator!{impl DequeRevIterator -> &'self T, -1}
+iterator!{impl DequeRevIterator -> &'self T, get_ref, -1}
 
 /// Deque mutable iterator
 pub struct DequeMutIterator<'self, T> {
-    priv idx: uint,
+    priv lo: uint,
     priv nelts: uint,
-    priv used: uint,
-    priv vec: &'self mut [Option<T>]
-
+    priv index: uint,
+    priv elts: &'self mut [Option<T>],
 }
-iterator!{impl DequeMutIterator -> &'self mut T, 1}
+iterator!{impl DequeMutIterator -> &'self mut T, get_mut_ref, 1}
 
 /// Deque mutable reverse iterator
 pub struct DequeMutRevIterator<'self, T> {
-    priv idx: uint,
+    priv lo: uint,
     priv nelts: uint,
-    priv used: uint,
-    priv vec: &'self mut [Option<T>]
+    priv index: uint,
+    priv elts: &'self mut [Option<T>],
 }
-iterator!{impl DequeMutRevIterator -> &'self mut T, -1}
+iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1}
 
 /// Grow is only called on full elts, so nelts is also len(elts), unlike
 /// elsewhere.
@@ -258,6 +249,15 @@ fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
     match elts[i] { Some(ref t) => t, _ => fail!() }
 }
 
+/// Return index in underlying vec for a given logical element index
+fn raw_index(lo: uint, len: uint, index: uint) -> uint {
+    if lo >= len - index {
+        lo + index - len
+    } else {
+        lo + index
+    }
+}
+
 impl<A, T: Iterator<A>> FromIterator<A, T> for Deque<A> {
     fn from_iterator(iterator: &mut T) -> Deque<A> {
         let mut deq = Deque::new();