From fd3f394d6ebd1326594227ccd767e715782f3b46 Mon Sep 17 00:00:00 2001 From: janis Date: Sat, 8 Aug 2026 16:24:42 +0200 Subject: [PATCH] foundation: primitive llinked list --- .../foundation/src/collections/linked_list.rs | 70 +++++++++++++++++++ crates/foundation/src/collections/mod.rs | 1 + crates/foundation/src/lib.rs | 1 + 3 files changed, 72 insertions(+) create mode 100644 crates/foundation/src/collections/linked_list.rs create mode 100644 crates/foundation/src/collections/mod.rs diff --git a/crates/foundation/src/collections/linked_list.rs b/crates/foundation/src/collections/linked_list.rs new file mode 100644 index 0000000..c1a3cbf --- /dev/null +++ b/crates/foundation/src/collections/linked_list.rs @@ -0,0 +1,70 @@ +use core::ptr::NonNull; + +pub unsafe trait LinkedListNode { + fn next(this: NonNull) -> Option>; + fn set_next(this: NonNull, next: Option>); +} + +pub struct LinkedList { + head: Option>, +} + +impl LinkedList { + pub const fn new() -> Self { + Self { head: None } + } + + pub fn push_front(&mut self, node: NonNull) { + T::set_next(node, self.head); + self.head = Some(node); + } + + pub fn pop_front(&mut self) -> Option> { + let node = self.head?; + self.head = T::next(node); + Some(node) + } + + pub fn remove_if(&mut self, mut predicate: impl FnMut(NonNull) -> bool) { + let mut current = self.head; + let mut prev: Option> = None; + + while let Some(node) = current { + if predicate(node) { + let next = T::next(node); + if let Some(prev_node) = prev { + T::set_next(prev_node, next); + } else { + self.head = next; + } + current = next; + } else { + prev = current; + current = T::next(node); + } + } + } + + pub fn iter(&self) -> LinkedListIter { + LinkedListIter { current: self.head } + } +} + +impl Default for LinkedList { + fn default() -> Self { + Self::new() + } +} + +pub struct LinkedListIter { + current: Option>, +} +impl Iterator for LinkedListIter { + type Item = NonNull; + + fn next(&mut self) -> Option { + let node = self.current?; + self.current = T::next(node); + Some(node) + } +} diff --git a/crates/foundation/src/collections/mod.rs b/crates/foundation/src/collections/mod.rs new file mode 100644 index 0000000..acb82e2 --- /dev/null +++ b/crates/foundation/src/collections/mod.rs @@ -0,0 +1 @@ +pub mod linked_list; diff --git a/crates/foundation/src/lib.rs b/crates/foundation/src/lib.rs index 5c005aa..9ff0893 100644 --- a/crates/foundation/src/lib.rs +++ b/crates/foundation/src/lib.rs @@ -15,6 +15,7 @@ extern crate alloc as liballoc; extern crate std; pub mod alloc; +pub mod collections; pub mod sync; pub mod mem { use num_traits::PrimInt;