///
/// To mutably access the data of more than one node at once,
/// use
-/// [`IsMutToken::multi_static`],
-/// [`IsMutToken::multi_dynamic`],
+/// [`IsTokenMut::multi_static`],
+/// [`IsTokenMut::multi_dynamic`],
/// or for manual aliasing checks,
/// [`.borrow_mut()`](Ptr::borrow_mut()) with
-/// [`MutToken::new_unchecked()`].
+/// [`TokenMut::new_unchecked()`].
///
/// This type is `Copy`. Copying it (or, indeed, cloning it)
/// does not copy the underlying data.
///
/// * Always points to a valid T on the heap: was `Box<T>`.
/// * All references given out are compatible with the borrow
- /// of the `NoAliasSingleton` (possibly via `IsRefToken`
- /// or `IsMutToken`.
+ /// of the `NoAliasSingleton` (possibly via `IsTokenRef`
+ /// or `IsTokenMut`.
//
// Variance: covariant, which is right according to the rules (see
// docs for NonNull) since we *do* provide the usual shared XOR
///
/// Typically, instead of passing `&mut NoAliasSingleton`
/// to your own sub-functions,
-/// you'll pass [`MutToken`] (or [`RefToken`],
+/// you'll pass [`TokenMut`] (or [`TokenRef`],
/// which can be obtained (and copied)
/// with
-/// [`IsRefToken::ref_token`]
+/// [`IsTokenRef::token_ref`]
/// and
-/// [`IsMutToken::mut_token`].
+/// [`IsTokenMut::token_mut`].
///
/// Those token types are zero-sized types,
/// so they incur no runtime cost,
/// We don't actually ever need to look at the data for the singleton.
/// So the actual pointer is redundant, and, here, absent.
#[derive(Debug, Clone, Copy)]
-pub struct RefToken<'a>(
+pub struct TokenRef<'a>(
PhantomData<&'a NoAliasSingleton>,
);
/// `&mut` [`NoAliasSingleton`], but a zero-sized
///
-/// See [`RefToken`]
+/// See [`TokenRef`]
#[derive(Debug)]
-pub struct MutToken<'a>(
+pub struct TokenMut<'a>(
PhantomData<&'a mut NoAliasSingleton>,
);
-impl<'a> MutToken<'a> {
+impl<'a> TokenMut<'a> {
/// Allows borrowing on the caller's recognisance
///
/// This will let you call
/// and they must be distinct from your `borrow`s.
/// Violating this rule is instant undefined behaviour,
/// even if you never read or write the resulting reference(s).
- pub unsafe fn new_unchecked() -> Self { MutToken(PhantomData) }
+ pub unsafe fn new_unchecked() -> Self { TokenMut(PhantomData) }
}
-//---------- IsRefToken and IsMutToken traits ----------
+//---------- IsTokenRef and IsTokenMut traits ----------
/// Token-like: `&self` implies `&NoAliasSingleton`
///
/// Implemented for `NoAliasSingleton` and the ZST reference tokens,
/// and `&`-references to them.
-pub unsafe trait IsRefToken<'a>: Sized + Sealed {
+pub unsafe trait IsTokenRef<'a>: Sized + Sealed {
/// Obtains a new ZST token from something that might be a real object.
#[inline]
- fn ref_token(self) -> RefToken<'a> {
- RefToken(PhantomData)
+ fn token_ref(self) -> TokenRef<'a> {
+ TokenRef(PhantomData)
}
}
/// Token-like: `&mut self` implies `&mut NoAliasSingleton`
///
-/// Implemented for `NoAliasSingleton` and `MutToken`,
+/// Implemented for `NoAliasSingleton` and `TokenMut`,
/// and `&mut`-references to them.
-pub unsafe trait IsMutToken<'a>: IsRefToken<'a> + Sized + Sealed {
+pub unsafe trait IsTokenMut<'a>: IsTokenRef<'a> + Sized + Sealed {
/// Obtains a new ZST token from something that might be a real object.
#[inline]
- fn mut_token<'r>(self) -> MutToken<'r> where 'a: 'r {
- MutToken(PhantomData)
+ fn token_mut<'r>(self) -> TokenMut<'r> where 'a: 'r {
+ TokenMut(PhantomData)
}
/// Borrows from a small, fixed, number of multiple `Ptr`
/// O(n^2) time and O(n) space in the number of borrows.
fn multi_static<'r>(self) -> MultiStatic<'r, ()> where 'a: 'r {
MultiStatic {
- tok: self.mut_token(),
+ tok: self.token_mut(),
l: (),
}
}
/// Borrowing uses O(n) space, on the heap, and O(n) time.
fn multi_dynamic<'r>(self) -> MultiDynamic<'r> where 'a: 'r {
MultiDynamic {
- _tok: self.mut_token(),
+ _tok: self.token_mut(),
ref_given: HashSet::new(),
mut_given: HashSet::new(),
}
mod sealed { pub trait Sealed {} }
use sealed::Sealed;
-unsafe impl<'a> IsRefToken<'a> for &'a NoAliasSingleton {}
-unsafe impl<'a> IsRefToken<'a> for &'a mut NoAliasSingleton {}
-unsafe impl<'a> IsMutToken<'a> for &'a mut NoAliasSingleton {}
-unsafe impl<'a> IsRefToken<'a> for RefToken<'a> {}
-unsafe impl<'a> IsRefToken<'a> for MutToken<'a> {}
-unsafe impl<'a> IsMutToken<'a> for MutToken<'a> {}
-unsafe impl<'a, A: IsRefToken<'a>> IsRefToken<'a> for &'a A {}
+unsafe impl<'a> IsTokenRef<'a> for &'a NoAliasSingleton {}
+unsafe impl<'a> IsTokenRef<'a> for &'a mut NoAliasSingleton {}
+unsafe impl<'a> IsTokenMut<'a> for &'a mut NoAliasSingleton {}
+unsafe impl<'a> IsTokenRef<'a> for TokenRef<'a> {}
+unsafe impl<'a> IsTokenRef<'a> for TokenMut<'a> {}
+unsafe impl<'a> IsTokenMut<'a> for TokenMut<'a> {}
+unsafe impl<'a, A: IsTokenRef<'a>> IsTokenRef<'a> for &'a A {}
-unsafe impl<'r, 'a, 'aa, A> IsRefToken<'r> for &'aa mut A
-where A: IsMutToken<'a>, 'a: 'r, 'aa: 'r {}
+unsafe impl<'r, 'a, 'aa, A> IsTokenRef<'r> for &'aa mut A
+where A: IsTokenMut<'a>, 'a: 'r, 'aa: 'r {}
-unsafe impl<'r, 'a, 'aa, A> IsMutToken<'r> for &'aa mut A
-where A: IsMutToken<'a>, 'a: 'r, 'aa: 'r {}
+unsafe impl<'r, 'a, 'aa, A> IsTokenMut<'r> for &'aa mut A
+where A: IsTokenMut<'a>, 'a: 'r, 'aa: 'r {}
-impl Sealed for RefToken<'_> {}
-impl Sealed for MutToken<'_> {}
+impl Sealed for TokenRef<'_> {}
+impl Sealed for TokenMut<'_> {}
impl Sealed for NoAliasSingleton {}
impl<T: Sealed> Sealed for & T {}
impl<T: Sealed> Sealed for &mut T {}
/// Borrows the contained data, immutably
#[inline]
- pub fn borrow<'a>(self, tok: impl IsRefToken<'a>) -> &'a T {
+ pub fn borrow<'a>(self, tok: impl IsTokenRef<'a>) -> &'a T {
let _ = tok;
unsafe {
// SAFETY
/// Borrows the contained data, mutably
#[inline]
- pub fn borrow_mut<'a>(mut self, tok: impl IsMutToken<'a>) -> &'a mut T {
+ pub fn borrow_mut<'a>(mut self, tok: impl IsTokenMut<'a>) -> &'a mut T {
let _ = tok;
unsafe {
// SAFETY
///
/// The compiler will check that no borrows are live.
#[inline]
- pub unsafe fn free_heap<'a>(self, tok: impl IsMutToken<'a>) {
+ pub unsafe fn free_heap<'a>(self, tok: impl IsTokenMut<'a>) {
let _t: Box<T> = unsafe { self.into_box(tok) };
}
///
/// The same rules as [`free_heap`](Ptr::free_heap) apply.
#[inline]
- pub unsafe fn free_heap_return<'a>(self, tok: impl IsMutToken<'a>) -> T
+ pub unsafe fn free_heap_return<'a>(self, tok: impl IsTokenMut<'a>) -> T
where T: Sized
{
let t: Box<T> = unsafe { self.into_box(tok) };
///
/// The same rules as [`free_heap`](Ptr::free_heap) apply.
#[inline]
- pub unsafe fn into_box<'a>(self, tok: impl IsMutToken<'a>) -> Box<T> {
+ pub unsafe fn into_box<'a>(self, tok: impl IsTokenMut<'a>) -> Box<T> {
let _ = tok;
let t: Box<T> = unsafe {
// SAFETY
/// There must be only one `NoAliasSingleton` used with each `Ptr`.
///
/// That is, it is unsound to use the same `Ptr` (or any copy of it)
- /// with `MutToken`es derived from
+ /// with `TokenMut`es derived from
/// two (or more) different `NoAliasSingleton`s.
///
/// The easiest way to do this is to have only one `NoAliasSingleton`.
/// Tracker for multiple borrows (dynamic)
///
-/// Returned from [`IsMutToken::multi_dynamic`].
+/// Returned from [`IsTokenMut::multi_dynamic`].
pub struct MultiDynamic<'a> {
- _tok: MutToken<'a>,
+ _tok: TokenMut<'a>,
ref_given: HashSet<NonNull<()>>,
mut_given: HashSet<NonNull<()>>,
}
/// Tracker for multiple borrows (static)
///
-/// Returned from [`IsMutToken::multi_static`].
+/// Returned from [`IsTokenMut::multi_static`].
pub struct MultiStatic<'a, L> {
- tok: MutToken<'a>,
+ tok: TokenMut<'a>,
l: L,
}
pub fn check_consistency(&self) {
dbg!(self);
- let tok = self.noalias.ref_token();
+ let tok = self.noalias.token_ref();
let mut last: Option<P<T>> = None;
let mut node = self.head;
while let Some(node_) = node {
}
pub fn front(&self) -> Option<&T> {
- let tok = self.noalias.ref_token();
+ let tok = self.noalias.token_ref();
let head = self.head?;
Some(&head.borrow(tok).data)
}
pub fn front_mut(&mut self) -> Option<&mut T> {
- let tok = self.noalias.mut_token();
+ let tok = self.noalias.token_mut();
let head = self.head?;
Some(&mut head.borrow_mut(tok).data)
}
pub fn pop_front(&mut self) -> Option<T> {
- let tok = self.noalias.mut_token();
+ let tok = self.noalias.token_mut();
Self::pop_front_inner(
tok,
&mut self.head,
let Some(head) = self.head
else { return HeadAndTail::None };
- let multi = self.noalias.mut_token().multi_static();
+ let multi = self.noalias.token_mut().multi_static();
let Ok((head, multi)) = multi.borrow_mut(head)
else { unsafe { unreachable_unchecked() } };
}
pub fn all(&self) -> impl Iterator<Item = &T> {
- let tok = self.noalias.ref_token();
+ let tok = self.noalias.token_ref();
Self::iter_ptrs(self.head, move |node| {
let node = node.borrow(tok);
(&node.data, node.next)
pub fn all_mut_fast(&mut self) -> impl Iterator<Item = &mut T> {
Self::iter_ptrs(self.head, |node| {
- let tok = unsafe { MutToken::new_unchecked() };
+ let tok = unsafe { TokenMut::new_unchecked() };
let node = node.borrow_mut(tok);
(&mut node.data, node.next)
})
// We wouldn't do this, since it's daft, but
// it lets us demonstrate passing a token.
fn pop_front_inner<'a>(
- mut tok: MutToken<'a>,
+ mut tok: TokenMut<'a>,
head: &mut Option<P<T>>,
tail: &mut Option<P<T>>,
) -> Option<T> {
impl<T: Debug> Drop for List<T> {
fn drop(&mut self) {
while let Some(_) = Self::pop_front_inner(
- self.noalias.mut_token(),
+ self.noalias.token_mut(),
&mut self.head,
&mut self.tail,
) { }