-// Rust-101, Part 16: Unsafe, Drop (WIP)
-// ===============================
+// Rust-101, Part 16: Unsafe Rust, Drop
+// ====================================
use std::ptr;
use std::mem;
prev: NodePtr<T>,
data: T,
}
-// A node pointer is a *mutable raw point* to a node.
+// A node pointer is a *mutable raw pointer* to a node.
type NodePtr<T> = *mut Node<T>;
// The linked list itself stores pointers to the first and the last node. In addition, we tell Rust that this type
LinkedList { first: ptr::null_mut(), last: ptr::null_mut(), _marker: PhantomData }
}
- // Add a new node to the end of the list.
+ // This function adds a new node to the end of the list.
pub fn push_back(&mut self, t: T) {
// Create the new node, and make it a raw pointer.
let new = Box::new( Node { data: t, next: ptr::null_mut(), prev: self.last } );
let new = box_into_raw(new);
- // Update other points to this node.
+ // Update other pointers to this node.
if self.last.is_null() {
debug_assert!(self.first.is_null());
// The list is currently empty, so we have to update the head pointer.
// Add testcases for `push_back` and all of your functions. The `pop` functions should take `&mut self`
// and return `Option<T>`.
- // Of course, we will also want to provide an iterator.
- pub fn iter_mut(&self) -> IterMut<T> {
+ // Next, we are going to provide an iterator.
+ pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut { next: self.first, _marker: PhantomData }
}
}
+
pub struct IterMut<'a, T> where T: 'a {
next: NodePtr<T>,
_marker: PhantomData<&'a mut LinkedList<T>>,
fn next(&mut self) -> Option<Self::Item> {
// The actual iteration is straight-forward: Once we reached a null pointer, we are done.
if self.next.is_null() {
- None
+ None
} else {
- // Otherwise, we can convert the next pointer to a borrow, get a borrow to the data
+ // Otherwise, we can convert the next pointer to a reference, get a reference to the data
// and update the iterator.
let next = unsafe { &mut *self.next };
let ret = &mut next.data;
- self.next = next.next;
- Some(ret)
+ unimplemented!()
}
}
}
-// **Exercise 16.2**: Add a method `iter` and a type `Iter` providing iteration for shared borrows.
+// **Exercise 16.2**: Add a method `iter` and a type `Iter` providing iteration for shared references.
// Add testcases for both kinds of iterators.
// ## `Drop`
+
impl<T> Drop for LinkedList<T> {
// The destructor itself is a method which takes `self` in mutably borrowed form. It cannot own `self`, because then
- // the destructor of `self` would be called at the end pf the function, resulting in endless recursion...
+ // the destructor of `self` would be called at the end of the function, resulting in endless recursion.
fn drop(&mut self) {
let mut cur_ptr = self.first;
while !cur_ptr.is_null() {
}
}
+// ## The End