Implement borrow stack for node graph

This commit is contained in:
Dennis
2022-04-22 19:58:13 +02:00
committed by Keavon Chambers
parent 09deee0c4d
commit 49c171b419
10 changed files with 163 additions and 19 deletions

View File

@@ -1,13 +1,72 @@
trait BorrowStack {
type Item;
unsafe fn push(&mut self, T) -> &Item;
unsafe fn pop(&mut self) -> T;
unsafe fn get(&self) -> &T;
use std::{
marker::PhantomData,
mem::MaybeUninit,
pin::Pin,
sync::atomic::{AtomicUsize, Ordering},
};
pub trait BorrowStack<'n> {
type Item;
unsafe fn push(&'n self, value: Self::Item);
unsafe fn pop(&'n self);
unsafe fn get(&'n self) -> &'n [Self::Item];
}
struct BorrowStack<S> {
data: S,
#[derive(Debug)]
pub struct FixedSizeStack<'n, T> {
data: Pin<Box<[MaybeUninit<T>]>>,
capacity: usize,
len: AtomicUsize,
_phantom: PhantomData<&'n ()>,
}
impl<'n, T: Unpin> FixedSizeStack<'n, T> {
pub fn new(capacity: usize) -> Self {
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
let array = unsafe { std::alloc::alloc(layout) };
let array = Pin::new(unsafe {
Box::from_raw(
std::slice::from_raw_parts_mut(array as *mut MaybeUninit<T>, capacity)
as *mut [MaybeUninit<T>],
)
});
Self {
data: array,
capacity,
len: AtomicUsize::new(0),
_phantom: PhantomData,
}
}
pub fn len(&self) -> usize {
self.len.load(Ordering::SeqCst)
}
}
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
type Item = T;
unsafe fn push(&'n self, value: Self::Item) {
let len = self.len.load(Ordering::SeqCst);
assert!(len < self.capacity);
let ptr = self.data[len].as_ptr();
(ptr as *mut T).write(value);
self.len.fetch_add(1, Ordering::SeqCst);
}
unsafe fn pop(&'n self) {
let ptr = self.data[self.len.load(Ordering::SeqCst)].as_ptr();
Box::from_raw(ptr as *mut T);
self.len.fetch_sub(1, Ordering::SeqCst);
}
unsafe fn get(&'n self) -> &'n [Self::Item] {
std::slice::from_raw_parts(
self.data.as_ptr() as *const T,
self.len.load(Ordering::SeqCst),
)
}
}
#[cfg(test)]