about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIan Wahbe <ian@wahbe.com>2021-07-01 21:08:01 +0200
committerIan Wahbe <ian@wahbe.com>2021-07-01 21:08:01 +0200
commitc4ad273fe168cba92a298e35826b37f7177ce599 (patch)
treee73a6eed41e55a737881944a07d1e61d83459955
parente77acf7d27f7690f6cdb18d2ce68a37cbabd884c (diff)
downloadrust-c4ad273fe168cba92a298e35826b37f7177ce599.tar.gz
rust-c4ad273fe168cba92a298e35826b37f7177ce599.zip
Implement changes suggested by @Amanieu
-rw-r--r--library/alloc/src/collections/linked_list.rs27
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs12
2 files changed, 29 insertions, 10 deletions
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 4eecf5703a4..ea216786ea2 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1247,14 +1247,14 @@ impl<'a, T> Cursor<'a, T> {
     /// Provides a reference to the front element of the cursor's parent list,
     /// or None if the list is empty.
     #[unstable(feature = "linked_list_cursors", issue = "58533")]
-    pub fn front(&self) -> Option<&T> {
+    pub fn front(&self) -> Option<&'a T> {
         self.list.front()
     }
 
     /// Provides a reference to the back element of the cursor's parent list,
     /// or None if the list is empty.
     #[unstable(feature = "linked_list_cursors", issue = "58533")]
-    pub fn back(&self) -> Option<&T> {
+    pub fn back(&self) -> Option<&'a T> {
         self.list.back()
     }
 }
@@ -1546,6 +1546,11 @@ impl<'a, T> CursorMut<'a, T> {
         // memory of other nodes. This ensures that `self.current` remains
         // valid.
         self.list.push_back(elt);
+        if self.current().is_none() {
+            // The index of "ghost" is the length of the list, so we just need
+            // to increment self.index to reflect the new length of the list.
+            self.index += 1;
+        }
     }
 
     /// Removes the first element from the cursor's parent list and returns it,
@@ -1565,13 +1570,12 @@ impl<'a, T> CursorMut<'a, T> {
             // We can't point to the node that we pop. Copying the behavior of
             // `remove_current`, we move on the the next node in the sequence.
             // If the list is of length 1 then we end pointing to the "ghost"
-            // node, which is expected.
+            // node at index 0, which is expected.
             if self.list.head == self.current {
                 self.move_next();
+            } else {
+                self.index -= 1;
             }
-            // We always need to change the index since `head` comes before any
-            // other element.
-            self.index.checked_sub(1).unwrap_or(0);
             self.list.pop_front()
         }
     }
@@ -1579,7 +1583,7 @@ impl<'a, T> CursorMut<'a, T> {
     /// Removes the last element from the cursor's parent list and returns it,
     /// or None if the list is empty. The element the cursor points to remains
     /// unchanged, unless it was pointing to the back element. In that case, it
-    /// points to the new back element.
+    /// points to the "ghost" element.
     ///
     /// This operation should compute in O(1) time.
     #[unstable(feature = "linked_list_cursors", issue = "58533")]
@@ -1588,10 +1592,13 @@ impl<'a, T> CursorMut<'a, T> {
             None
         } else {
             if self.list.tail == self.current {
-                self.move_prev()
+                // The index now reflects the length of the list. It was the
+                // length of the list minus 1, but now the list is 1 smaller. No
+                // change is needed for `index`.
+                self.current = None;
+            } else if self.current.is_none() {
+                self.index = self.list.len - 1;
             }
-            // We don't need to change the index since `current` points to a
-            // node before `tail`.
             self.list.pop_back()
         }
     }
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index 45349a7df12..5a65ed7a962 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -442,6 +442,8 @@ fn test_cursor_push_front_back() {
     assert_eq!(c.index(), Some(1));
     c.push_back(11);
     drop(c);
+    let p = ll.cursor_back().front().unwrap();
+    assert_eq!(p, &0);
     assert_eq!(ll, (0..12).collect());
     check_links(&ll);
 }
@@ -459,7 +461,17 @@ fn test_cursor_pop_front_back() {
     let c = c.as_cursor();
     assert_eq!(c.front(), Some(&2));
     assert_eq!(c.back(), Some(&5));
+    assert_eq!(c.index(), Some(1));
     drop(c);
     assert_eq!(ll, (2..6).collect());
     check_links(&ll);
+    let mut c = ll.cursor_back_mut();
+    assert_eq!(c.current(), Some(&mut 5));
+    assert_eq!(c.index, 3);
+    assert_eq!(c.pop_back(), Some(5));
+    assert_eq!(c.current(), None);
+    assert_eq!(c.index, 3);
+    assert_eq!(c.pop_back(), Some(4));
+    assert_eq!(c.current(), None);
+    assert_eq!(c.index, 2);
 }