Skip to content

Commit c4ad273

Browse files
committed
Implement changes suggested by @Amanieu
1 parent e77acf7 commit c4ad273

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

library/alloc/src/collections/linked_list.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -1247,14 +1247,14 @@ impl<'a, T> Cursor<'a, T> {
12471247
/// Provides a reference to the front element of the cursor's parent list,
12481248
/// or None if the list is empty.
12491249
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1250-
pub fn front(&self) -> Option<&T> {
1250+
pub fn front(&self) -> Option<&'a T> {
12511251
self.list.front()
12521252
}
12531253

12541254
/// Provides a reference to the back element of the cursor's parent list,
12551255
/// or None if the list is empty.
12561256
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1257-
pub fn back(&self) -> Option<&T> {
1257+
pub fn back(&self) -> Option<&'a T> {
12581258
self.list.back()
12591259
}
12601260
}
@@ -1546,6 +1546,11 @@ impl<'a, T> CursorMut<'a, T> {
15461546
// memory of other nodes. This ensures that `self.current` remains
15471547
// valid.
15481548
self.list.push_back(elt);
1549+
if self.current().is_none() {
1550+
// The index of "ghost" is the length of the list, so we just need
1551+
// to increment self.index to reflect the new length of the list.
1552+
self.index += 1;
1553+
}
15491554
}
15501555

15511556
/// Removes the first element from the cursor's parent list and returns it,
@@ -1565,21 +1570,20 @@ impl<'a, T> CursorMut<'a, T> {
15651570
// We can't point to the node that we pop. Copying the behavior of
15661571
// `remove_current`, we move on the the next node in the sequence.
15671572
// If the list is of length 1 then we end pointing to the "ghost"
1568-
// node, which is expected.
1573+
// node at index 0, which is expected.
15691574
if self.list.head == self.current {
15701575
self.move_next();
1576+
} else {
1577+
self.index -= 1;
15711578
}
1572-
// We always need to change the index since `head` comes before any
1573-
// other element.
1574-
self.index.checked_sub(1).unwrap_or(0);
15751579
self.list.pop_front()
15761580
}
15771581
}
15781582

15791583
/// Removes the last element from the cursor's parent list and returns it,
15801584
/// or None if the list is empty. The element the cursor points to remains
15811585
/// unchanged, unless it was pointing to the back element. In that case, it
1582-
/// points to the new back element.
1586+
/// points to the "ghost" element.
15831587
///
15841588
/// This operation should compute in O(1) time.
15851589
#[unstable(feature = "linked_list_cursors", issue = "58533")]
@@ -1588,10 +1592,13 @@ impl<'a, T> CursorMut<'a, T> {
15881592
None
15891593
} else {
15901594
if self.list.tail == self.current {
1591-
self.move_prev()
1595+
// The index now reflects the length of the list. It was the
1596+
// length of the list minus 1, but now the list is 1 smaller. No
1597+
// change is needed for `index`.
1598+
self.current = None;
1599+
} else if self.current.is_none() {
1600+
self.index = self.list.len - 1;
15921601
}
1593-
// We don't need to change the index since `current` points to a
1594-
// node before `tail`.
15951602
self.list.pop_back()
15961603
}
15971604
}

library/alloc/src/collections/linked_list/tests.rs

+12
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ fn test_cursor_push_front_back() {
442442
assert_eq!(c.index(), Some(1));
443443
c.push_back(11);
444444
drop(c);
445+
let p = ll.cursor_back().front().unwrap();
446+
assert_eq!(p, &0);
445447
assert_eq!(ll, (0..12).collect());
446448
check_links(&ll);
447449
}
@@ -459,7 +461,17 @@ fn test_cursor_pop_front_back() {
459461
let c = c.as_cursor();
460462
assert_eq!(c.front(), Some(&2));
461463
assert_eq!(c.back(), Some(&5));
464+
assert_eq!(c.index(), Some(1));
462465
drop(c);
463466
assert_eq!(ll, (2..6).collect());
464467
check_links(&ll);
468+
let mut c = ll.cursor_back_mut();
469+
assert_eq!(c.current(), Some(&mut 5));
470+
assert_eq!(c.index, 3);
471+
assert_eq!(c.pop_back(), Some(5));
472+
assert_eq!(c.current(), None);
473+
assert_eq!(c.index, 3);
474+
assert_eq!(c.pop_back(), Some(4));
475+
assert_eq!(c.current(), None);
476+
assert_eq!(c.index, 2);
465477
}

0 commit comments

Comments
 (0)