mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-12-23 10:11:54 +00:00
parent
11c6413251
commit
b2a90ddc2c
7 changed files with 67 additions and 62 deletions
|
|
@ -1,18 +1,18 @@
|
|||
use std::{
|
||||
marker::PhantomData,
|
||||
mem::MaybeUninit,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
pub trait BorrowStack {
|
||||
type Item;
|
||||
use dyn_any::StaticTypeSized;
|
||||
|
||||
pub trait BorrowStack<T: StaticTypeSized> {
|
||||
/// # Safety
|
||||
unsafe fn push(&self, value: Self::Item);
|
||||
unsafe fn push(&self, value: T);
|
||||
/// # Safety
|
||||
unsafe fn pop(&self);
|
||||
/// # Safety
|
||||
unsafe fn get(&self) -> &'static [Self::Item];
|
||||
unsafe fn get<'a>(&self) -> &'a [<T as StaticTypeSized>::Static];
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -22,11 +22,11 @@ pub struct FixedSizeStack<T: dyn_any::StaticTypeSized> {
|
|||
len: AtomicUsize,
|
||||
}
|
||||
|
||||
impl<'n, T: Unpin + 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
||||
impl<'n, T: 'n + dyn_any::StaticTypeSized> FixedSizeStack<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>]) });
|
||||
let array = Box::into_pin(unsafe { Box::from_raw(std::slice::from_raw_parts_mut(array as *mut MaybeUninit<T>, capacity) as *mut [MaybeUninit<T>]) });
|
||||
|
||||
Self {
|
||||
data: array,
|
||||
|
|
@ -42,19 +42,20 @@ impl<'n, T: Unpin + 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
|||
pub fn is_empty(&self) -> bool {
|
||||
self.len.load(Ordering::SeqCst) == 0
|
||||
}
|
||||
pub fn push_fn(&self, f: impl FnOnce(&'static [T::Static]) -> T) {
|
||||
unsafe { self.push(std::mem::transmute_copy(&f(self.get()))) }
|
||||
pub fn push_fn<'a>(&self, f: impl FnOnce(&'a [T::Static]) -> T) {
|
||||
assert_eq!(std::mem::size_of::<T>(), std::mem::size_of::<T::Static>());
|
||||
unsafe { self.push(f(self.get())) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T: 'n + dyn_any::StaticTypeSized> BorrowStack for FixedSizeStack<T> {
|
||||
type Item = T::Static;
|
||||
|
||||
unsafe fn push(&self, value: Self::Item) {
|
||||
impl<T: dyn_any::StaticTypeSized> BorrowStack<T> for FixedSizeStack<T> {
|
||||
unsafe fn push(&self, value: T) {
|
||||
let len = self.len.load(Ordering::SeqCst);
|
||||
assert!(len < self.capacity);
|
||||
let ptr = self.data[len].as_ptr();
|
||||
(ptr as *mut T::Static).write(value);
|
||||
let static_value = std::mem::transmute_copy(&value);
|
||||
(ptr as *mut T::Static).write(static_value);
|
||||
std::mem::forget(value);
|
||||
self.len.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +65,7 @@ impl<'n, T: 'n + dyn_any::StaticTypeSized> BorrowStack for FixedSizeStack<T> {
|
|||
self.len.fetch_sub(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
unsafe fn get(&self) -> &'static [Self::Item] {
|
||||
unsafe fn get<'a>(&self) -> &'a [T::Static] {
|
||||
std::slice::from_raw_parts(self.data.as_ptr() as *const T::Static, self.len.load(Ordering::SeqCst))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue