Double linked list
It's almost the same as our single linked lists, except that we need to have another constraint for T
:
#![allow(unused)] fn main() { trait DoubleLinkedIntrusiveListItem { fn prev(&self) -> Option<NonNull<Self>>; fn set_prev(&self, new_prev: Option<NonNull<Self>>); fn next(&self) -> Option<NonNull<Self>>; fn set_next(&self, new_next: Option<NonNull<Self>>); } }
and so to have a list of numbers our supplementary data structure must look like this:
#![allow(unused)] fn main() { struct IntrusiveNumber { n: u64, prev: Cell<Option<NonNull<Self>>>, next: Cell<Option<NonNull<Self>>>, } impl DoubleLinkedIntrusiveListItem for IntrusiveNumber { fn prev(&self) -> Option<NonNull<Self>> { self.prev.get() } fn set_prev(&self, new_prev: Option<NonNull<Self>>) { self.prev.set(new_prev) } fn next(&self) -> Option<NonNull<Self>> { self.next.get() } fn set_next(&self, new_next: Option<NonNull<Self>>) { self.next.set(new_next) } } }
It might sound like it requires too much memory and in the case of a number that's probably true. However I only need it for some internal data structures that are allocated on the scratch arena.
It's possible to slightly reduce memory usage by using relative offsets.