use core::mem::{align_of, size_of};
use core::ptr::NonNull;
#[derive(Clone, Copy)]
pub struct Region {
base: NonNull<u8>,
len: usize,
}
impl Region {
pub unsafe fn from_raw(base: *mut u8, len: usize) -> Self {
let base = NonNull::new(base).expect("region base must be non-null");
Self { base, len }
}
#[inline]
pub fn as_ptr(&self) -> *mut u8 {
self.base.as_ptr()
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn offset(&self, off: usize) -> *mut u8 {
assert!(
off < self.len,
"offset {off} out of bounds (len={})",
self.len
);
unsafe { self.as_ptr().add(off) }
}
#[inline]
pub unsafe fn get<T>(&self, off: usize) -> &T {
debug_assert!(off + size_of::<T>() <= self.len);
debug_assert!(off.is_multiple_of(align_of::<T>()));
unsafe { &*(self.offset(off) as *const T) }
}
#[inline]
#[allow(clippy::mut_from_ref)]
pub unsafe fn get_mut<T>(&self, off: usize) -> &mut T {
debug_assert!(off + size_of::<T>() <= self.len);
debug_assert!(off.is_multiple_of(align_of::<T>()));
unsafe { &mut *(self.offset(off) as *mut T) }
}
}
unsafe impl Send for Region {}
unsafe impl Sync for Region {}
mod heap {
use super::Region;
use core::ptr::NonNull;
use std::alloc::{Layout, alloc_zeroed, dealloc};
pub struct HeapRegion {
base: NonNull<u8>,
len: usize,
layout: Layout,
}
impl HeapRegion {
pub fn new_zeroed(size: usize) -> Self {
let layout =
Layout::from_size_align(size.max(1), 64).expect("invalid heap region layout");
let ptr = unsafe { alloc_zeroed(layout) };
let base = NonNull::new(ptr).expect("heap region allocation failed");
Self {
base,
len: size,
layout,
}
}
#[inline]
pub fn region(&self) -> Region {
unsafe { Region::from_raw(self.base.as_ptr(), self.len) }
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
}
impl Drop for HeapRegion {
fn drop(&mut self) {
unsafe { dealloc(self.base.as_ptr(), self.layout) };
}
}
unsafe impl Send for HeapRegion {}
unsafe impl Sync for HeapRegion {}
}
pub use heap::HeapRegion;