chiark / gitweb /
wip
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 16:28:24 +0000 (16:28 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 21:49:40 +0000 (21:49 +0000)
src/lib.rs

index c7d7b0d6f66a8c9cb47ac851d0ac1494865b5acb..ffd998e34239dcb52fdc98309f1d46bef35944c2 100644 (file)
@@ -10,6 +10,9 @@ pub struct NoAliasSingleton {
 }
 
 impl NoAliasSingleton {
+    pub fn as_ref<'a>(&'a mut self) -> NoAlias<'a> {
+        NoAlias(PhantomData)
+    }
     pub fn as_mut<'a>(&'a mut self) -> NoAlias<'a> {
         NoAlias(PhantomData)
     }
@@ -157,17 +160,42 @@ mod tests {
                 if self.head.is_none() { self.head = Some(node) };
             }
 
+            pub fn front(&self) -> Option<&T> {
+                let noalias = self.noalias.as_ref();
+                let head = self.head?;
+                Some(self.head.borrow(noalias))
+            }
+
+            pub fn front_mut(&mut self) -> Option<&T> {
+                let noalias = self.noalias.as_mut();
+                let head = self.head?;
+                Some(self.head.borrow_mut(noalias))
+            }
+
             pub fn pop_front(&mut self) -> Option<T> {
                 let mut noalias = self.noalias.as_mut();
                 let noalias = &mut noalias;
+                self.pop_front_inner(
+                    noalias,
+                    &mut self.head,
+                    &mut self.tail,
+                )
+            }
 
-                let deleting = self.head?;
+            // We wouldn't do this, since it's daft, but
+            // it lets us demonstrate passing a NoAlias.
+            fn pop_front_inner(
+                noalias: NoAlias,
+                head: &mut Option<Ptr<T>>,
+                tail: &mut Option<Ptr<T>>,
+            ) -> Option<T> {
+                let deleting = *head?;
                 let new_head = deleting.borrow(noalias).next;
-                self.head = new_head;
+                *head = new_head;
                 if let Some(new_head) = new_head {
                     new_head.borrow_mut(noalias).back = None;
                 } else {
-                    self.tail = None;
+                    *tail = None;
                 }
                 let deleted = unsafe { deleting.free_heap(noalias) };
                 Some(deleted.data)
@@ -176,7 +204,11 @@ mod tests {
 
         impl<T> Drop for List<T> {
             fn drop(&mut self) {
-                while let Some(_) = self.pop_front() { }
+                while let Some(_) = Self::pop_front_inner(
+                    self.noalias.as_mut(),
+                    &mut self.head,
+                    &mut self.tail,
+                ) { }
             }
         }
     }
@@ -186,11 +218,13 @@ mod tests {
         use list::List;
 
         let l = List::<String>::new();
+        assert_eq!(l.front(), None);
         drop(l);
 
         let mut l = List::new();
         l.append(format!("hi"));
         l.append(format!("ho"));
+        assert_eq!(l.front(), Some("hi"));
         drop(l);
     }
 }