chiark / gitweb /
demo Borrowed
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Nov 2024 18:51:40 +0000 (18:51 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Nov 2024 18:51:40 +0000 (18:51 +0000)
src/test.rs
src/test/demo.rs

index 7eddc91a041516331c7d442ffb9b63684003e3ad..7b1743004204c9087b9092e697fc4c680f61d681 100644 (file)
@@ -38,6 +38,13 @@ fn demo() {
     l.prepend(s("one"));         l.check_consistency();
     assert_eq!(l.head_and_tail_mut(), H::Both(&mut s("one"), &mut s("ho")));
 
+    l.temporarily_prepend(s("t"), |l| {
+        l.check_consistency();
+        assert_eq!(l.front(), Some(&s("t")));
+    });
+    l.check_consistency();
+    assert_eq!(l.head_and_tail_mut(), H::Both(&mut s("one"), &mut s("ho")));
+
     write!(l.front_mut().unwrap(), "!").unwrap();
     assert_eq!(l.pop_front(), Some(s("one!")));   l.check_consistency();
     assert_eq!(l.front(), Some(&s("hi")));        l.check_consistency();
index 1a611161f38e85ec26d57d6d31c92467f6c2b794..da3304d233203acbc07fac7f3f153a2654e1ddbd 100644 (file)
@@ -114,6 +114,33 @@ impl<T: Debug> List<T> {
         Some(deleted.data)
     }
 
+    // This is a bit unnatural, but it demonstrates Borrowed
+    pub fn temporarily_prepend<R>(
+        &mut self,
+        data: T,
+        then: impl FnOnce(&Self) -> R,
+    ) -> R {
+        use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
+
+        let mut tmp_node = Node {
+            data,
+            next: None,
+            back: None,
+        };
+        let tmp_node = unsafe { Borrowed::new(&mut tmp_node) };
+        self.prepend_raw(*tmp_node);
+        let r = catch_unwind(AssertUnwindSafe(|| then(&self)));
+        let mut tok = &mut self.noalias;
+        let removed_again = Self::pop_front_inner(
+            tok.as_mut(),
+            &mut self.head,
+            &mut self.tail,
+        );
+        assert_eq!(removed_again.map(|p| p.as_ptr()), Some(tmp_node.as_ptr()));
+        tmp_node.retained();
+        r.unwrap_or_else(|p| resume_unwind(p))
+    }
+
     pub fn head_and_tail_mut(&mut self) -> HeadAndTail<&mut T> {
         let Some(head) = self.head
         else { return HeadAndTail::None };