]> git.lizzy.rs Git - rust.git/commitdiff
dlist: Fix bug in DList::merge
authorblake2-ppc <blake2-ppc>
Fri, 12 Jul 2013 00:31:08 +0000 (02:31 +0200)
committerblake2-ppc <blake2-ppc>
Sat, 13 Jul 2013 02:30:15 +0000 (04:30 +0200)
Did not properly allow runs from the `other` list to be merged in. The
test case was using a wrong expected value.

Edited docs for merge so they explain more clearly what it does.

Also make sure insert_ordered is marked pub.

src/libextra/dlist.rs

index fc6d05fcb589acdc997f49da53979c9b05a16f94..61db14316fbe95e6ac1dfcf81cbbed4e6f9a4feb 100644 (file)
@@ -300,19 +300,26 @@ pub fn insert_when(&mut self, elt: T, f: &fn(&T, &T) -> bool) {
         self.push_back(elt);
     }
 
-    /// Merge, using the function `f`; take `a` if `f(a, b)` is true, else `b`.
+    /// Merge DList `other` into this DList, using the function `f`.
+    /// Iterate the both DList with `a` from self and `b` from `other`, and
+    /// put `a` in the result if `f(a, b)` is true, else `b`.
     ///
     /// O(max(N, M))
     pub fn merge(&mut self, mut other: DList<T>, f: &fn(&T, &T) -> bool) {
         {
             let mut it = self.mut_iter();
+            let mut elt = it.next();
             loop {
-                match (it.next(), other.front()) {
-                    (None   , _      ) => break,
-                    (_      , None   ) => return,
-                    (Some(x), Some(y)) => if f(x, y) { loop }
+                let take_a = match (&mut elt, other.front()) {
+                    (_    , None) => return,
+                    (&None, _   ) => break,
+                    (&Some(ref mut x), Some(y)) => f(*x, y),
+                };
+                if take_a {
+                    elt = it.next()
+                } else {
+                    it.insert_before(other.pop_front().unwrap());
                 }
-                it.insert_before(other.pop_front().unwrap());
             }
         }
         self.append(other);
@@ -351,11 +358,11 @@ pub fn consume_rev_iter(self) -> ConsumeRevIterator<T> {
     }
 }
 
-/// Insert sorted in ascending order
-///
-/// O(N)
 impl<T: cmp::TotalOrd> DList<T> {
-    fn insert_ordered(&mut self, elt: T) {
+    /// Insert `elt` sorted in ascending order
+    ///
+    /// O(N)
+    pub fn insert_ordered(&mut self, elt: T) {
         self.insert_when(elt, |a, b| a.cmp(b) != cmp::Less);
     }
 }
@@ -758,7 +765,7 @@ fn test_merge() {
         assert_eq!(m.len(), len);
         check_links(&m);
         let res = m.consume_iter().collect::<~[int]>();
-        assert_eq!(res, ~[-1, 0, 0, 1, 0, 3, 5, 6, 7, 2, 7, 7, 9]);
+        assert_eq!(res, ~[-1, 0, 0, 0, 1, 3, 5, 6, 7, 2, 7, 7, 9]);
     }
 
     #[test]