use std::marker;
use crate::{
depot,
depot::{
array::copy,
index,
index::{bitmap::entry::Row, set},
},
};
#[repr(transparent)]
pub struct Proof<S, P: depot::Predicate> {
value: S,
invariant: Domain<S, P>,
}
unsafe impl<'a, T: Copy, const N: usize> depot::raw::Project<usize> for &'a copy::Vec<T, N> {
type Output = &'a T;
unsafe fn project(self, index: usize) -> Self::Output {
unsafe { self.as_slice().get_unchecked(index) }
}
}
unsafe impl<Tag, Raw: depot::raw::Word, const N: usize>
depot::raw::Project<index::Ordinal<Tag, Raw>> for &set::State<Tag, Raw, N>
{
type Output = set::Entry<Self, Tag, Raw, N>;
unsafe fn project(self, index: index::Ordinal<Tag, Raw>) -> Self::Output {
let row = unsafe { Row::new(set::View::new(self), index.offset()) };
set::Entry { row }
}
}
impl<S, P: depot::Predicate> Proof<S, P> {
pub const unsafe fn new(value: S) -> Self {
Self {
value,
invariant: marker::PhantomData,
}
}
pub unsafe fn map<T>(self, project: impl FnOnce(S) -> T) -> Proof<T, P> {
Proof {
value: project(self.value),
invariant: marker::PhantomData,
}
}
pub fn into_inner(self) -> S {
self.value
}
}
impl<S, K, P> Proof<(S, K), index::Initialized<P>> {
pub const fn source(&self) -> &S {
&self.value.0
}
pub const fn key(&self) -> &K {
&self.value.1
}
pub unsafe fn as_ref(&self) -> Proof<(&S, K), index::Initialized<P>>
where
K: Copy,
{
Proof {
value: (&self.value.0, self.value.1),
invariant: marker::PhantomData,
}
}
pub unsafe fn as_mut(&mut self) -> Proof<(&mut S, K), index::Initialized<P>>
where
K: Copy,
{
Proof {
value: (&mut self.value.0, self.value.1),
invariant: marker::PhantomData,
}
}
pub fn into(self) -> S::Output
where
S: depot::raw::Project<K, P>,
{
unsafe { self.value.0.project(self.value.1) }
}
}
impl<'a, T> depot::raw::Admit for Proof<(&'a mut Vec<T>, usize), index::Initialized<()>> {
type Output = (T, Option<&'a T>);
fn admit(self) -> Self::Output {
let (values, index) = self.into_inner();
unsafe { crate::alloc::raw::VecExt::swap_remove(values, index) }
}
}
const _: () = {
assert!(
std::mem::size_of::<Proof<(&'static (), usize), index::Initialized<()>>>()
== 2 * std::mem::size_of::<usize>()
);
assert!(
std::mem::size_of::<Option<Proof<(&'static (), usize), index::Initialized<()>>>>()
== 2 * std::mem::size_of::<usize>()
);
};
mod phases;
pub(in crate::depot) use phases::{Numeric, Sealed};
mod slot;
mod values;
pub(in crate::depot) use drain::Drain;
pub(crate) use slot::{Present, Slot};
mod count;
pub(in crate::depot) use count::ChainCount;
mod drain;
type Domain<S, P> = marker::PhantomData<fn(S, P) -> (S, P)>;