use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use crate::borrow::{Ref, RefMut};
use crate::segment_borrow::{SegmentBorrow, SegmentBorrowRegistry};
pub struct SegmentLease<'a> {
registry: *mut SegmentBorrowRegistry,
borrow: SegmentBorrow,
_lt: PhantomData<&'a mut SegmentBorrowRegistry>,
}
impl<'a> SegmentLease<'a> {
#[doc(hidden)]
#[inline(always)]
pub unsafe fn new(registry: &'a mut SegmentBorrowRegistry, borrow: SegmentBorrow) -> Self {
Self {
registry: registry as *mut _,
borrow,
_lt: PhantomData,
}
}
#[doc(hidden)]
#[inline(always)]
pub unsafe fn from_raw(registry: *mut SegmentBorrowRegistry, borrow: SegmentBorrow) -> Self {
Self {
registry,
borrow,
_lt: PhantomData,
}
}
#[allow(clippy::should_implement_trait)]
#[inline(always)]
pub fn borrow(&self) -> &SegmentBorrow {
&self.borrow
}
}
impl<'a> Drop for SegmentLease<'a> {
#[inline(always)]
fn drop(&mut self) {
unsafe {
(*self.registry).release(&self.borrow);
}
}
}
impl<'a> core::fmt::Debug for SegmentLease<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SegmentLease")
.field("borrow", &self.borrow)
.finish_non_exhaustive()
}
}
pub struct SegRef<'a, T: ?Sized> {
inner: Ref<'a, T>,
lease: SegmentLease<'a>,
}
impl<'a, T: ?Sized> SegRef<'a, T> {
#[doc(hidden)]
#[inline(always)]
pub fn new(inner: Ref<'a, T>, lease: SegmentLease<'a>) -> Self {
Self { inner, lease }
}
#[inline(always)]
pub fn into_parts(self) -> (Ref<'a, T>, SegmentLease<'a>) {
(self.inner, self.lease)
}
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
self.inner.as_ptr()
}
#[inline(always)]
pub fn inner(&self) -> &Ref<'a, T> {
&self.inner
}
}
impl<T: ?Sized> Deref for SegRef<'_, T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.inner
}
}
impl<T: ?Sized> core::fmt::Debug for SegRef<'_, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SegRef")
.field("lease", &self.lease)
.finish_non_exhaustive()
}
}
pub struct SegRefMut<'a, T: ?Sized> {
inner: RefMut<'a, T>,
lease: SegmentLease<'a>,
}
impl<'a, T: ?Sized> SegRefMut<'a, T> {
#[doc(hidden)]
#[inline(always)]
pub fn new(inner: RefMut<'a, T>, lease: SegmentLease<'a>) -> Self {
Self { inner, lease }
}
#[inline(always)]
pub fn into_parts(self) -> (RefMut<'a, T>, SegmentLease<'a>) {
(self.inner, self.lease)
}
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
self.inner.as_ptr()
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.inner.as_mut_ptr()
}
}
impl<T: ?Sized> Deref for SegRefMut<'_, T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.inner
}
}
impl<T: ?Sized> DerefMut for SegRefMut<'_, T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut T {
&mut self.inner
}
}
impl<T: ?Sized> core::fmt::Debug for SegRefMut<'_, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SegRefMut")
.field("lease", &self.lease)
.finish_non_exhaustive()
}
}
pub struct SegmentsMut<'a, T, const N: usize> {
data: RefMut<'a, [u8]>,
offsets: [usize; N],
_leases: [SegmentLease<'a>; N],
_t: PhantomData<fn() -> T>,
}
impl<'a, T: crate::Pod, const N: usize> SegmentsMut<'a, T, N> {
#[doc(hidden)]
#[inline(always)]
pub(crate) fn new(
data: RefMut<'a, [u8]>,
offsets: [usize; N],
leases: [SegmentLease<'a>; N],
) -> Self {
Self {
data,
offsets,
_leases: leases,
_t: PhantomData,
}
}
#[inline(always)]
pub const fn len(&self) -> usize {
N
}
#[inline(always)]
pub const fn is_empty(&self) -> bool {
N == 0
}
#[inline(always)]
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
let off = *self.offsets.get(i)?;
let base = self.data.as_bytes_mut_ptr();
Some(unsafe { &mut *(base.add(off) as *mut T) })
}
#[inline(always)]
pub fn all_mut(&mut self) -> [&mut T; N] {
let base = self.data.as_bytes_mut_ptr();
let offsets = self.offsets;
let mut out: [core::mem::MaybeUninit<&mut T>; N] =
unsafe { core::mem::MaybeUninit::uninit().assume_init() };
let mut i = 0;
while i < N {
let r: &mut T = unsafe { &mut *(base.add(offsets[i]) as *mut T) };
out[i] = core::mem::MaybeUninit::new(r);
i += 1;
}
unsafe {
let init = core::ptr::read(&out as *const _ as *const [&mut T; N]);
#[allow(clippy::forget_non_drop)]
core::mem::forget(out);
init
}
}
}
impl<'a, T, const N: usize> core::fmt::Debug for SegmentsMut<'a, T, N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SegmentsMut")
.field("offsets", &self.offsets)
.finish_non_exhaustive()
}
}