54 lines
1.5 KiB
Rust
54 lines
1.5 KiB
Rust
use core::mem::MaybeUninit;
|
|
use core::ops::{Deref, DerefMut};
|
|
|
|
/// Plain Old data type
|
|
pub trait Pod: Copy + 'static {
|
|
fn uninit() -> Self { unsafe { MaybeUninit::uninit().assume_init() } }
|
|
fn zeroed() -> Self { unsafe { MaybeUninit::zeroed().assume_init() } }
|
|
}
|
|
|
|
macro_rules! primitive {
|
|
($($p:ty),*) => {
|
|
$(impl Pod for $p {})*
|
|
}
|
|
}
|
|
|
|
primitive!(u8, u16, u32, u64, u128);
|
|
primitive!(i8, i16, i32, i64, i128);
|
|
primitive!(f32, f64, usize, isize);
|
|
primitive!(());
|
|
|
|
impl<const LEN: usize, T: Pod> Pod for [T;LEN] {}
|
|
|
|
|
|
/// Type with unsafe interior mutability
|
|
/// but also with Send+Sync
|
|
///
|
|
/// internally just wraps UnsafeCell
|
|
#[repr(transparent)]
|
|
pub struct Mut<T>(core::cell::UnsafeCell<T>);
|
|
unsafe impl<T> Sync for Mut<T> {}
|
|
unsafe impl<T> Send for Mut<T> {}
|
|
|
|
impl<T: Sized> Mut<T> {
|
|
pub const fn new(value: T) -> Self {
|
|
Self(core::cell::UnsafeCell::new(value))
|
|
}
|
|
pub const fn as_ptr(&self) -> *mut T {
|
|
self.0.get()
|
|
}
|
|
}
|
|
|
|
impl<T: Pod> Mut<T> {
|
|
pub fn set(&self, value: T) { unsafe { core::ptr::write(self.as_ptr(), value) } }
|
|
pub fn get(&self) -> T { unsafe { core::ptr::read(self.as_ptr()) } }
|
|
}
|
|
impl<T> Mut<MaybeUninit<T>> {
|
|
pub const fn zeroed() -> Self { Self(core::cell::UnsafeCell::new(MaybeUninit::zeroed())) }
|
|
pub const fn uninit() -> Self { Self(core::cell::UnsafeCell::new(MaybeUninit::uninit())) }
|
|
}
|
|
|
|
impl<T> Deref for Mut<T> {
|
|
type Target = core::cell::UnsafeCell<T>;
|
|
fn deref(&self) -> &Self::Target { &self.0 }
|
|
} |