twizzler/collections/
list.rs

1use twizzler_rt_abi::object::ObjectHandle;
2
3use crate::{
4    alloc::{invbox::InvBox, Allocator, OwnedGlobalPtr},
5    marker::{BaseType, Invariant},
6    Result,
7};
8
9#[allow(dead_code)]
10pub struct ListNode<T: Invariant, A: Allocator> {
11    value: T,
12    next: Option<InvBox<Self, A>>,
13    alloc: A,
14}
15
16impl<T: Invariant, A: Allocator> BaseType for ListNode<T, A> {}
17unsafe impl<T: Invariant, A: Allocator> Invariant for ListNode<T, A> {}
18
19impl<T: Invariant, A: Allocator + Clone> ListNode<T, A> {
20    pub fn new(
21        tx: impl AsRef<ObjectHandle>,
22        value: T,
23        next: Option<OwnedGlobalPtr<Self, A>>,
24        alloc: A,
25    ) -> Result<Self> {
26        Ok(Self {
27            value,
28            next: next.map(|n| InvBox::from_in(tx, n).unwrap()),
29            alloc,
30        })
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37    use crate::{
38        alloc::arena::{ArenaAllocator, ArenaObject},
39        object::ObjectBuilder,
40    };
41
42    #[test]
43    fn simple() {
44        let arena = ArenaObject::new(ObjectBuilder::default()).unwrap();
45        let alloc = arena.allocator();
46        let mut tx = arena.into_tx().unwrap();
47        let node0 = tx
48            .alloc(ListNode::new(&tx, 3, None, alloc).unwrap())
49            .unwrap();
50        let node1_val = ListNode::new(&tx, 2, Some(node0), alloc).unwrap();
51        let node1 = tx.alloc(node1_val).unwrap();
52        let node2_val = ListNode::new(&tx, 1, Some(node1), alloc).unwrap();
53        let node2 = tx.alloc(node2_val).unwrap();
54
55        let rnode2 = node2.resolve();
56        let rnode1 = rnode2.next.as_ref().unwrap().resolve();
57        let rnode0 = rnode1.next.as_ref().unwrap().resolve();
58
59        assert_eq!(rnode2.value, 1);
60        assert_eq!(rnode1.value, 2);
61        assert_eq!(rnode0.value, 3);
62    }
63
64    #[test]
65    fn with_boxes() {
66        struct Node {
67            data: InvBox<u32, ArenaAllocator>,
68        }
69
70        impl Node {
71            fn new(tx: impl AsRef<ObjectHandle>, val: u32, alloc: ArenaAllocator) -> Result<Self> {
72                Ok(Self {
73                    data: InvBox::new_in(tx, val, alloc).unwrap(),
74                })
75            }
76        }
77        // This would come from derive(Invariant)
78        unsafe impl Invariant for Node {}
79
80        let arena = ArenaObject::new(ObjectBuilder::default()).unwrap();
81        let alloc = arena.allocator();
82        let _data0 = arena.alloc(3);
83        let mut tx = arena.into_tx().unwrap();
84        let node0 = ListNode::new(&tx, Node::new(&tx, 3, alloc).unwrap(), None, alloc).unwrap();
85        let node0 = tx.alloc(node0).unwrap();
86        let node1 = tx
87            .alloc(
88                ListNode::new(&tx, Node::new(&tx, 2, alloc).unwrap(), Some(node0), alloc).unwrap(),
89            )
90            .unwrap();
91        let node2 = tx
92            .alloc(
93                ListNode::new(&tx, Node::new(&tx, 1, alloc).unwrap(), Some(node1), alloc).unwrap(),
94            )
95            .unwrap();
96
97        let rnode2 = node2.resolve();
98        let rnode1 = rnode2.next.as_ref().unwrap().resolve();
99        let rnode0 = rnode1.next.as_ref().unwrap().resolve();
100
101        assert_eq!(*rnode2.value.data.resolve(), 1);
102        assert_eq!(*rnode1.value.data.resolve(), 2);
103        assert_eq!(*rnode0.value.data.resolve(), 3);
104    }
105}