Fix snipped -> snippet typo
[rust-101.git] / workspace / src / part16.rs
index a804f8e3ef309fc793add29d34c917475985bae3..fa5b1845f595632b7bf5ce506e5d365881c1db46 100644 (file)
@@ -1,5 +1,5 @@
-// Rust-101, Part 16: Unsafe, Drop (WIP)
-// ===============================
+// Rust-101, Part 16: Unsafe Rust, Drop
+// ====================================
 
 use std::ptr;
 use std::mem;
 
 use std::ptr;
 use std::mem;
@@ -12,7 +12,7 @@ struct Node<T> {
     prev: NodePtr<T>,
     data: T,
 }
     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
 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
@@ -37,12 +37,12 @@ impl<T> LinkedList<T> {
         LinkedList { first: ptr::null_mut(), last: ptr::null_mut(), _marker: PhantomData }
     }
 
         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);
     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.
         if self.last.is_null() {
             debug_assert!(self.first.is_null());
             // The list is currently empty, so we have to update the head pointer.
@@ -60,12 +60,13 @@ impl<T> LinkedList<T> {
     // Add testcases for `push_back` and all of your functions. The `pop` functions should take `&mut self`
     // and return `Option<T>`.
 
     // 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  }
     }
 }
 
         IterMut { next: self.first, _marker: PhantomData  }
     }
 }
 
+
 pub struct IterMut<'a, T> where T: 'a {
     next: NodePtr<T>,
     _marker: PhantomData<&'a mut LinkedList<T>>,
 pub struct IterMut<'a, T> where T: 'a {
     next: NodePtr<T>,
     _marker: PhantomData<&'a mut LinkedList<T>>,
@@ -77,26 +78,26 @@ impl<'a, T> Iterator for IterMut<'a, 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() {
     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 {
         } 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;
             // 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`
 // 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
 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() {
     fn drop(&mut self) {
         let mut cur_ptr = self.first;
         while !cur_ptr.is_null() {
@@ -110,4 +111,5 @@ impl<T> Drop for LinkedList<T> {
     }
 }
 
     }
 }
 
+// ## The End