Skip to content

Commit

Permalink
Update APIs according to RFC change suggestions.
Browse files Browse the repository at this point in the history
  • Loading branch information
crlf0710 committed Jan 14, 2020
1 parent d2c509a commit 06b9a73
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 18 deletions.
43 changes: 33 additions & 10 deletions src/liballoc/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,20 +509,42 @@ impl<T> LinkedList<T> {
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.
Expand Down Expand Up @@ -1146,8 +1168,6 @@ impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> {
/// 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,
Expand Down Expand Up @@ -1474,9 +1494,12 @@ impl<'a, T> CursorMut<'a, T> {
/// 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) }
}

Expand All @@ -1487,9 +1510,9 @@ impl<'a, T> CursorMut<'a, T> {
/// 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) }
}
}
Expand Down
60 changes: 52 additions & 8 deletions src/liballoc/collections/linked_list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ fn drain_to_empty_test() {
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);
Expand All @@ -326,9 +326,26 @@ fn test_cursor_move_peek() {
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);
Expand All @@ -352,24 +369,51 @@ fn test_cursor_move_peek() {
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();
Expand All @@ -383,7 +427,7 @@ fn test_cursor_mut_insert() {
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();
Expand All @@ -395,12 +439,12 @@ fn test_cursor_mut_insert() {
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();
Expand Down

0 comments on commit 06b9a73

Please sign in to comment.