IterMut { head: self.head, tail: self.tail, len: self.len, list: self }
}
- /// Provides a cursor.
+ /// Provides a cursor at the front element.
+ ///
+ /// The cursor is pointing to the "ghost" non-element if the list is empty.
#[inline]
#[unstable(feature = "linked_list_cursors", issue = "58533")]
- pub fn cursor(&self) -> Cursor<'_, T> {
+ pub fn cursor_front(&self) -> Cursor<'_, T> {
Cursor { index: 0, current: self.head, list: self }
}
- /// Provides a cursor with editing operations.
+ /// Provides a cursor with editing operations at the front element.
+ ///
+ /// The cursor is pointing to the "ghost" non-element if the list is empty.
#[inline]
#[unstable(feature = "linked_list_cursors", issue = "58533")]
- pub fn cursor_mut(&mut self) -> CursorMut<'_, T> {
+ pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> {
CursorMut { index: 0, current: self.head, list: self }
}
+ /// Provides a cursor at the back element.
+ ///
+ /// The cursor is pointing to the "ghost" non-element if the list is empty.
+ #[inline]
+ #[unstable(feature = "linked_list_cursors", issue = "58533")]
+ pub fn cursor_back(&self) -> Cursor<'_, T> {
+ Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self }
+ }
+
+ /// Provides a cursor with editing operations at the back element.
+ ///
+ /// The cursor is pointing to the "ghost" non-element if the list is empty.
+ #[inline]
+ #[unstable(feature = "linked_list_cursors", issue = "58533")]
+ pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> {
+ CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self }
+ }
+
/// Returns `true` if the `LinkedList` is empty.
///
/// This operation should compute in O(1) time.
/// Cursors always rest between two elements in the list, and index in a logically circular way.
/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and
/// tail of the list.
-///
-/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub struct CursorMut<'a, T: 'a> {
index: usize,
/// If the cursor is pointing at the "ghost" non-element then the entire contents
/// of the `LinkedList` are moved.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
- pub fn split_after(self) -> LinkedList<T> {
+ pub fn split_after(&mut self) -> LinkedList<T> {
let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 };
- // no need to update `self.index` because the cursor is consumed.
+ if self.index == self.list.len {
+ // The "ghost" non-element's index has changed to 0.
+ self.index = 0;
+ }
unsafe { self.list.split_off_after_node(self.current, split_off_idx) }
}
/// If the cursor is pointing at the "ghost" non-element then the entire contents
/// of the `LinkedList` are moved.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
- pub fn split_before(self) -> LinkedList<T> {
+ pub fn split_before(&mut self) -> LinkedList<T> {
let split_off_idx = self.index;
- // no need to update `self.index` because the cursor is consumed.
+ self.index = 0;
unsafe { self.list.split_off_before_node(self.current, split_off_idx) }
}
}
fn test_cursor_move_peek() {
let mut m: LinkedList<u32> = LinkedList::new();
m.extend(&[1, 2, 3, 4, 5, 6]);
- let mut cursor = m.cursor();
+ let mut cursor = m.cursor_front();
assert_eq!(cursor.current(), Some(&1));
assert_eq!(cursor.peek_next(), Some(&2));
assert_eq!(cursor.peek_prev(), None);
assert_eq!(cursor.peek_prev(), Some(&1));
assert_eq!(cursor.index(), Some(1));
+ let mut cursor = m.cursor_back();
+ assert_eq!(cursor.current(), Some(&6));
+ assert_eq!(cursor.peek_next(), None);
+ assert_eq!(cursor.peek_prev(), Some(&5));
+ assert_eq!(cursor.index(), Some(5));
+ cursor.move_next();
+ assert_eq!(cursor.current(), None);
+ assert_eq!(cursor.peek_next(), Some(&1));
+ assert_eq!(cursor.peek_prev(), Some(&6));
+ assert_eq!(cursor.index(), None);
+ cursor.move_prev();
+ cursor.move_prev();
+ assert_eq!(cursor.current(), Some(&5));
+ assert_eq!(cursor.peek_next(), Some(&6));
+ assert_eq!(cursor.peek_prev(), Some(&4));
+ assert_eq!(cursor.index(), Some(4));
+
let mut m: LinkedList<u32> = LinkedList::new();
m.extend(&[1, 2, 3, 4, 5, 6]);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
assert_eq!(cursor.current(), Some(&mut 1));
assert_eq!(cursor.peek_next(), Some(&mut 2));
assert_eq!(cursor.peek_prev(), None);
assert_eq!(cursor2.index(), Some(2));
assert_eq!(cursor.current(), Some(&mut 2));
assert_eq!(cursor.index(), Some(1));
+
+ let mut m: LinkedList<u32> = LinkedList::new();
+ m.extend(&[1, 2, 3, 4, 5, 6]);
+ let mut cursor = m.cursor_back_mut();
+ assert_eq!(cursor.current(), Some(&mut 6));
+ assert_eq!(cursor.peek_next(), None);
+ assert_eq!(cursor.peek_prev(), Some(&mut 5));
+ assert_eq!(cursor.index(), Some(5));
+ cursor.move_next();
+ assert_eq!(cursor.current(), None);
+ assert_eq!(cursor.peek_next(), Some(&mut 1));
+ assert_eq!(cursor.peek_prev(), Some(&mut 6));
+ assert_eq!(cursor.index(), None);
+ cursor.move_prev();
+ cursor.move_prev();
+ assert_eq!(cursor.current(), Some(&mut 5));
+ assert_eq!(cursor.peek_next(), Some(&mut 6));
+ assert_eq!(cursor.peek_prev(), Some(&mut 4));
+ assert_eq!(cursor.index(), Some(4));
+ let mut cursor2 = cursor.as_cursor();
+ assert_eq!(cursor2.current(), Some(&5));
+ assert_eq!(cursor2.index(), Some(4));
+ cursor2.move_prev();
+ assert_eq!(cursor2.current(), Some(&4));
+ assert_eq!(cursor2.index(), Some(3));
+ assert_eq!(cursor.current(), Some(&mut 5));
+ assert_eq!(cursor.index(), Some(4));
}
#[test]
fn test_cursor_mut_insert() {
let mut m: LinkedList<u32> = LinkedList::new();
m.extend(&[1, 2, 3, 4, 5, 6]);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
cursor.insert_before(7);
cursor.insert_after(8);
check_links(&m);
assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[7, 1, 8, 2, 3, 4, 5, 6]);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
cursor.move_prev();
cursor.insert_before(9);
cursor.insert_after(10);
check_links(&m);
assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
cursor.move_prev();
assert_eq!(cursor.remove_current(), None);
cursor.move_next();
assert_eq!(cursor.remove_current(), Some(10));
check_links(&m);
assert_eq!(m.iter().cloned().collect::<Vec<_>>(), &[1, 8, 2, 3, 4, 5, 6]);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
let mut p: LinkedList<u32> = LinkedList::new();
p.extend(&[100, 101, 102, 103]);
let mut q: LinkedList<u32> = LinkedList::new();
m.iter().cloned().collect::<Vec<_>>(),
&[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6]
);
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
cursor.move_prev();
let tmp = cursor.split_before();
assert_eq!(m.into_iter().collect::<Vec<_>>(), &[]);
m = tmp;
- let mut cursor = m.cursor_mut();
+ let mut cursor = m.cursor_front_mut();
cursor.move_next();
cursor.move_next();
cursor.move_next();