From: Ian Jackson Date: Thu, 14 Nov 2024 16:28:24 +0000 (+0000) Subject: wip X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=936a355b8bc29e7d3ab257171d3874edb1f7c97b;p=manually-boxed wip --- diff --git a/src/lib.rs b/src/lib.rs index c7d7b0d..ffd998e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 { 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>, + tail: &mut Option>, + ) -> Option { + 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 Drop for List { 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::::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); } }