]> git.lizzy.rs Git - rust.git/commitdiff
dlist: Implement DoubleEndedIterator and use for .iter() and .rev_iter()
authorblake2-ppc <blake2-ppc>
Fri, 12 Jul 2013 01:24:59 +0000 (03:24 +0200)
committerblake2-ppc <blake2-ppc>
Sat, 13 Jul 2013 02:31:05 +0000 (04:31 +0200)
src/libextra/dlist.rs

index 61db14316fbe95e6ac1dfcf81cbbed4e6f9a4feb..feafce58e6e9eec7f978327ec518ed44077a344e 100644 (file)
@@ -26,7 +26,7 @@
 use std::cmp;
 use std::ptr;
 use std::util;
-use std::iterator::FromIterator;
+use std::iterator::{FromIterator, InvertIterator};
 
 use container::Deque;
 
@@ -46,17 +46,10 @@ struct Node<T> {
     priv value: T,
 }
 
-/// DList iterator
-pub struct ForwardIterator<'self, T> {
-    priv list: &'self DList<T>,
-    priv next: &'self Link<T>,
-    priv nelem: uint,
-}
-
-/// DList reverse iterator
-pub struct ReverseIterator<'self, T> {
-    priv list: &'self DList<T>,
-    priv next: Rawlink<Node<T>>,
+/// Double-ended DList iterator
+pub struct DListIterator<'self, T> {
+    priv head: &'self Link<T>,
+    priv tail: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
@@ -327,13 +320,13 @@ pub fn merge(&mut self, mut other: DList<T>, f: &fn(&T, &T) -> bool) {
 
 
     /// Provide a forward iterator
-    pub fn iter<'a>(&'a self) -> ForwardIterator<'a, T> {
-        ForwardIterator{nelem: self.len(), list: self, next: &self.list_head}
+    pub fn iter<'a>(&'a self) -> DListIterator<'a, T> {
+        DListIterator{nelem: self.len(), head: &self.list_head, tail: self.list_tail}
     }
 
     /// Provide a reverse iterator
-    pub fn rev_iter<'a>(&'a self) -> ReverseIterator<'a, T> {
-        ReverseIterator{nelem: self.len(), list: self, next: self.list_tail}
+    pub fn rev_iter<'a>(&'a self) -> InvertIterator<&'a T, DListIterator<'a, T>> {
+        self.iter().invert()
     }
 
     /// Provide a forward iterator with mutable references
@@ -367,15 +360,18 @@ pub fn insert_ordered(&mut self, elt: T) {
     }
 }
 
-impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
+impl<'self, A> Iterator<&'self A> for DListIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self A> {
-        match *self.next {
+        if self.nelem == 0 {
+            return None;
+        }
+        match *self.head {
             None => None,
-            Some(ref next) => {
+            Some(ref head) => {
                 self.nelem -= 1;
-                self.next = &next.next;
-                Some(&next.value)
+                self.head = &head.next;
+                Some(&head.value)
             }
         }
     }
@@ -385,6 +381,22 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+impl<'self, A> DoubleEndedIterator<&'self A> for DListIterator<'self, A> {
+    fn next_back(&mut self) -> Option<&'self A> {
+        if self.nelem == 0 {
+            return None;
+        }
+        match self.tail.resolve() {
+            None => None,
+            Some(prev) => {
+                self.nelem -= 1;
+                self.tail = prev.prev;
+                Some(&prev.value)
+            }
+        }
+    }
+}
+
 // MutForwardIterator is different because it implements ListInsertion,
 // and can modify the list during traversal, used in insert_when and merge.
 impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
@@ -419,24 +431,6 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
-    #[inline]
-    fn next(&mut self) -> Option<&'self A> {
-        match self.next.resolve() {
-            None => None,
-            Some(prev) => {
-                self.nelem -= 1;
-                self.next = prev.prev;
-                Some(&prev.value)
-            }
-        }
-    }
-
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        (self.nelem, Some(self.nelem))
-    }
-}
-
 impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self mut A> {