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;
|
extern crate std;
|
||||||
|
|
||||||
pub mod alloc;
|
pub mod alloc;
|
||||||
|
pub mod collections;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod mem {
|
pub mod mem {
|
||||||
use num_traits::PrimInt;
|
use num_traits::PrimInt;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue