@@ -1243,6 +1243,20 @@ impl<'a, T> Cursor<'a, T> {
12431243 prev. map ( |prev| & ( * prev. as_ptr ( ) ) . element )
12441244 }
12451245 }
1246+
1247+ /// Provides a reference to the front element of the cursor's parent list,
1248+ /// or None if the list is empty.
1249+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1250+ pub fn front ( & self ) -> Option < & ' a T > {
1251+ self . list . front ( )
1252+ }
1253+
1254+ /// Provides a reference to the back element of the cursor's parent list,
1255+ /// or None if the list is empty.
1256+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1257+ pub fn back ( & self ) -> Option < & ' a T > {
1258+ self . list . back ( )
1259+ }
12461260}
12471261
12481262impl < ' a , T > CursorMut < ' a , T > {
@@ -1506,6 +1520,135 @@ impl<'a, T> CursorMut<'a, T> {
15061520 self . index = 0 ;
15071521 unsafe { self . list . split_off_before_node ( self . current , split_off_idx) }
15081522 }
1523+
1524+ /// Appends an element to the front of the cursor's parent list. The node
1525+ /// that the cursor points to is unchanged, even if it is the "ghost" node.
1526+ ///
1527+ /// This operation should compute in O(1) time.
1528+ // `push_front` continues to point to "ghost" when it addes a node to mimic
1529+ // the behavior of `insert_before` on an empty list.
1530+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1531+ pub fn push_front ( & mut self , elt : T ) {
1532+ // Safety: We know that `push_front` does not change the position in
1533+ // memory of other nodes. This ensures that `self.current` remains
1534+ // valid.
1535+ self . list . push_front ( elt) ;
1536+ self . index += 1 ;
1537+ }
1538+
1539+ /// Appends an element to the back of the cursor's parent list. The node
1540+ /// that the cursor points to is unchanged, even if it is the "ghost" node.
1541+ ///
1542+ /// This operation should compute in O(1) time.
1543+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1544+ pub fn push_back ( & mut self , elt : T ) {
1545+ // Safety: We know that `push_back` does not change the position in
1546+ // memory of other nodes. This ensures that `self.current` remains
1547+ // valid.
1548+ 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+ }
1554+ }
1555+
1556+ /// Removes the first element from the cursor's parent list and returns it,
1557+ /// or None if the list is empty. The element the cursor points to remains
1558+ /// unchanged, unless it was pointing to the front element. In that case, it
1559+ /// points to the new front element.
1560+ ///
1561+ /// This operation should compute in O(1) time.
1562+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1563+ pub fn pop_front ( & mut self ) -> Option < T > {
1564+ // We can't check if current is empty, we must check the list directly.
1565+ // It is possible for `self.current == None` and the list to be
1566+ // non-empty.
1567+ if self . list . is_empty ( ) {
1568+ None
1569+ } else {
1570+ // We can't point to the node that we pop. Copying the behavior of
1571+ // `remove_current`, we move on the the next node in the sequence.
1572+ // If the list is of length 1 then we end pointing to the "ghost"
1573+ // node at index 0, which is expected.
1574+ if self . list . head == self . current {
1575+ self . move_next ( ) ;
1576+ } else {
1577+ self . index -= 1 ;
1578+ }
1579+ self . list . pop_front ( )
1580+ }
1581+ }
1582+
1583+ /// Removes the last element from the cursor's parent list and returns it,
1584+ /// or None if the list is empty. The element the cursor points to remains
1585+ /// unchanged, unless it was pointing to the back element. In that case, it
1586+ /// points to the "ghost" element.
1587+ ///
1588+ /// This operation should compute in O(1) time.
1589+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1590+ pub fn pop_back ( & mut self ) -> Option < T > {
1591+ if self . list . is_empty ( ) {
1592+ None
1593+ } else {
1594+ if self . list . tail == self . current {
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 ;
1601+ }
1602+ self . list . pop_back ( )
1603+ }
1604+ }
1605+
1606+ /// Provides a reference to the front element of the cursor's parent list,
1607+ /// or None if the list is empty.
1608+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1609+ pub fn front ( & self ) -> Option < & T > {
1610+ self . list . front ( )
1611+ }
1612+
1613+ /// Provides a mutable reference to the front element of the cursor's
1614+ /// parent list, or None if the list is empty.
1615+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1616+ pub fn front_mut ( & mut self ) -> Option < & mut T > {
1617+ self . list . front_mut ( )
1618+ }
1619+
1620+ /// Provides a reference to the back element of the cursor's parent list,
1621+ /// or None if the list is empty.
1622+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1623+ pub fn back ( & self ) -> Option < & T > {
1624+ self . list . back ( )
1625+ }
1626+
1627+ /// Provides a mutable reference to back element of the cursor's parent
1628+ /// list, or `None` if the list is empty.
1629+ ///
1630+ /// # Examples
1631+ /// Building and mutating a list with a cursor, then getting the back element:
1632+ /// ```
1633+ /// #![feature(linked_list_cursors)]
1634+ /// use std::collections::LinkedList;
1635+ /// let mut dl = LinkedList::new();
1636+ /// dl.push_front(3);
1637+ /// dl.push_front(2);
1638+ /// dl.push_front(1);
1639+ /// let mut cursor = dl.cursor_front_mut();
1640+ /// *cursor.current().unwrap() = 99;
1641+ /// *cursor.back_mut().unwrap() = 0;
1642+ /// let mut contents = dl.into_iter();
1643+ /// assert_eq!(contents.next(), Some(99));
1644+ /// assert_eq!(contents.next(), Some(2));
1645+ /// assert_eq!(contents.next(), Some(0));
1646+ /// assert_eq!(contents.next(), None);
1647+ /// ```
1648+ #[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
1649+ pub fn back_mut ( & mut self ) -> Option < & mut T > {
1650+ self . list . back_mut ( )
1651+ }
15091652}
15101653
15111654/// An iterator produced by calling `drain_filter` on LinkedList.
0 commit comments