foundation: primitive llinked list
This commit is contained in:
parent
ae06f75cc2
commit
fd3f394d6e
70
crates/foundation/src/collections/linked_list.rs
Normal file
70
crates/foundation/src/collections/linked_list.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use core::ptr::NonNull;
|
||||
|
||||
pub unsafe trait LinkedListNode {
|
||||
fn next(this: NonNull<Self>) -> Option<NonNull<Self>>;
|
||||
fn set_next(this: NonNull<Self>, next: Option<NonNull<Self>>);
|
||||
}
|
||||
|
||||
pub struct LinkedList<T: LinkedListNode> {
|
||||
head: Option<NonNull<T>>,
|
||||
}
|
||||
|
||||
impl<T: LinkedListNode> LinkedList<T> {
|
||||
pub const fn new() -> Self {
|
||||
Self { head: None }
|
||||
}
|
||||
|
||||
pub fn push_front(&mut self, node: NonNull<T>) {
|
||||
T::set_next(node, self.head);
|
||||
self.head = Some(node);
|
||||
}
|
||||
|
||||
pub fn pop_front(&mut self) -> Option<NonNull<T>> {
|
||||
let node = self.head?;
|
||||
self.head = T::next(node);
|
||||
Some(node)
|
||||
}
|
||||
|
||||
pub fn remove_if(&mut self, mut predicate: impl FnMut(NonNull<T>) -> bool) {
|
||||
let mut current = self.head;
|
||||
let mut prev: Option<NonNull<T>> = 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<T> {
|
||||
LinkedListIter { current: self.head }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: LinkedListNode> Default for LinkedList<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LinkedListIter<T: LinkedListNode> {
|
||||
current: Option<NonNull<T>>,
|
||||
}
|
||||
impl<T: LinkedListNode> Iterator for LinkedListIter<T> {
|
||||
type Item = NonNull<T>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let node = self.current?;
|
||||
self.current = T::next(node);
|
||||
Some(node)
|
||||
}
|
||||
}
|
||||
1
crates/foundation/src/collections/mod.rs
Normal file
1
crates/foundation/src/collections/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod linked_list;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue