pub(in crate::buffer) use input::{Input, Measured};
use crate::buffer::{pool::owners, storage::regions};
mod input;
use std::{marker, mem, ptr};
use crate::{buffer, buffer::pool, mem::rc};
#[derive(Debug)]
#[repr(transparent)]
pub struct Edge<K: crate::buffer::raw::Backing = owners::Plain, M = pool::Owned> {
ptr: Option<ptr::NonNull<regions::Prefix>>,
mode: marker::PhantomData<(K, M)>,
}
impl<K: crate::buffer::raw::Backing, M> Edge<K, M> {
pub(in crate::buffer) const NONE: Self = Self {
ptr: None,
mode: marker::PhantomData,
};
pub(in crate::buffer::pool) const fn new(ptr: ptr::NonNull<regions::Prefix>) -> Self {
Self {
ptr: Some(ptr),
mode: marker::PhantomData,
}
}
pub(in crate::buffer) fn into_raw(self) -> Option<ptr::NonNull<regions::Prefix>> {
let this = mem::ManuallyDrop::new(self);
this.ptr
}
pub(in crate::buffer) unsafe fn release_raw(ptr: ptr::NonNull<()>) {
use crate::mem::raw::Edge;
if unsafe { ptr.cast::<regions::Prefix>().as_ref().release() } != rc::Release::Last {
return;
}
unsafe { owners::Retired::<K, owners::Any>::from_owner(ptr) }.finish();
}
}
impl<L> Edge<owners::Plain<L>, pool::Borrowed<'_>> {
pub(in crate::buffer) fn into_owned(self) -> Edge<owners::Plain<L>, pool::Owned> {
let this = mem::ManuallyDrop::new(self);
Edge {
ptr: this.ptr,
mode: marker::PhantomData,
}
}
}
impl<K: crate::buffer::raw::Backing, M> Drop for Edge<K, M> {
fn drop(&mut self) {
if let Some(ptr) = self.ptr {
unsafe { Self::release_raw(ptr.cast()) };
}
}
}
unsafe impl<K: crate::buffer::raw::Backing, M> buffer::raw::Retain for Edge<K, M> {
fn try_retain(&self) -> Result<Self, rc::Error> {
use crate::mem::raw::Edge;
let pointer = self.ptr;
if let Some(ptr) = pointer {
unsafe { ptr.as_ref().try_retain() }?;
}
Ok(Self {
ptr: pointer,
mode: marker::PhantomData,
})
}
}
const _: () = {
assert!(size_of::<Edge>() == size_of::<usize>());
assert!(size_of::<Edge<owners::Plain, pool::Borrowed<'static>>>() == size_of::<usize>());
assert!(size_of::<Edge<owners::Resident<'static>>>() == size_of::<usize>());
};
impl<K: crate::buffer::raw::Backing, M> regions::End for Edge<K, M> {
const EMPTY: Option<Self> = Some(Self::NONE);
}
impl<K: crate::buffer::raw::Backing, M> buffer::Residency for owners::Edge<K, M> {
fn resident(&self) -> usize {
self.ptr.map_or(0, |ptr| {
unsafe { owners::capacity_of(ptr.cast()) }.get() as usize
})
}
}