-#![allow(unused)]
-
use std::collections::HashSet;
use std::fmt::{self, Debug};
-use std::hint::unreachable_unchecked;
use std::marker::PhantomData;
use std::ptr::NonNull;
pub unsafe trait IsMutToken<'a>: IsRefToken<'a> + Sized {
/// Obtain a new ZST token from something that might be a real object.
#[inline]
- fn mut_token<'r>(mut self) -> MutToken<'r>
+ fn mut_token<'r>(self) -> MutToken<'r>
where 'a: 'r,
{
MutToken(PhantomData)
}
- fn multi_static<'r>(mut self) -> MultiStatic<'r, ()>
+ fn multi_static<'r>(self) -> MultiStatic<'r, ()>
where 'a: 'r,
{
MultiStatic {
}
}
- fn multi_runtime<'r>(mut self) -> MultiRuntime<'r>
+ fn multi_runtime<'r>(self) -> MultiRuntime<'r>
where 'a: 'r,
{
MultiRuntime {
- tok: self.mut_token(),
+ _tok: self.mut_token(),
ref_given: HashSet::new(),
mut_given: HashSet::new(),
}
///
/// SAFETY
///
- fn new_unchecked() -> Self { MutToken(PhantomData) }
+ pub unsafe fn new_unchecked() -> Self { MutToken(PhantomData) }
}
pub struct Ptr<T> {
#[inline]
pub fn borrow<'a>(self, tok: impl IsRefToken<'a>) -> &'a T {
+ let _ = tok;
unsafe {
// SAFETY
//
#[inline]
pub fn borrow_mut<'a>(mut self, tok: impl IsMutToken<'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>) -> T {
+ let _ = tok;
let t: Box<T> = unsafe {
// SAFETY
//
pub unsafe fn init() -> Self { NoAliasSingleton {} }
}
+#[derive(Debug)]
pub struct BorrowConflict;
pub struct MultiStatic<'a, L> {
fn alias_check_mut(&self, p: NonNull<()>) -> Result<(), BorrowConflict>;
}
unsafe impl MultiStaticList for () {
- fn alias_check_ref(&self, p: NonNull<()>) -> Result<(), BorrowConflict> {
+ fn alias_check_ref(&self, _: NonNull<()>) -> Result<(), BorrowConflict> {
Ok(())
}
- fn alias_check_mut(&self, p: NonNull<()>) -> Result<(), BorrowConflict> {
+ fn alias_check_mut(&self, _: NonNull<()>) -> Result<(), BorrowConflict> {
Ok(())
}
}
where 'a: 'r
{
match self.l.alias_check_ref(p.ptr.cast()) {
- Err(e) => Err(self),
+ Err(BorrowConflict) => Err(self),
Ok(()) => Ok(MultiStatic {
tok: self.tok,
l: (self.l, unsafe { p.ptr.as_ref() }),
where 'a: 'r
{
match self.l.alias_check_mut(p.ptr.cast()) {
- Err(e) => Err(self),
+ Err(BorrowConflict) => Err(self),
Ok(()) => Ok(MultiStatic {
tok: self.tok,
l: (self.l, unsafe { p.ptr.as_mut() }),
}
pub struct MultiRuntime<'a> {
- tok: MutToken<'a>,
+ _tok: MutToken<'a>,
ref_given: HashSet<NonNull<()>>,
mut_given: HashSet<NonNull<()>>,
}
mod list {
use super::*;
+ use std::hint::unreachable_unchecked;
+ use std::iter;
#[derive(Debug)]
pub struct Node<T> {
Both(T, T),
}
+ type P<T> = Ptr<Node<T>>;
+
impl<T: Debug> List<T> {
pub fn new() -> Self {
let noalias = unsafe { NoAliasSingleton::init() };
pub fn check_consistency(&self) {
dbg!(self);
let tok = self.noalias.ref_token();
- let mut last: Option<Ptr<Node<T>>> = None;
+ let mut last: Option<P<T>> = None;
let mut node = self.head;
while let Some(node_) = node {
dbg!(node_);
}
}
+ pub fn all(&self) -> impl Iterator<Item = &T> {
+ let tok = self.noalias.ref_token();
+ Self::iter_ptrs(self.head, move |node| {
+ let node = node.borrow(tok);
+ (&node.data, node.next)
+ })
+ }
+
+ pub fn all_mut_safe(&mut self) -> impl Iterator<Item = &mut T> {
+ let mut multi = self.noalias.multi_runtime();
+ Self::iter_ptrs(self.head, move |node| {
+ let node = multi.borrow_mut(node).expect("untangled!");
+ (&mut 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 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>,
- head: &mut Option<Ptr<Node<T>>>,
- tail: &mut Option<Ptr<Node<T>>>,
+ head: &mut Option<P<T>>,
+ tail: &mut Option<P<T>>,
) -> Option<T> {
let deleting = (*head)?;
let new_head = deleting.borrow(&tok).next;
let deleted = unsafe { deleting.free_heap(&mut tok) };
Some(deleted.data)
}
+
+ fn iter_ptrs<'i, I: 'i>(
+ head: Option<P<T>>,
+ mut node_map: impl FnMut(P<T>) -> (I, Option<P<T>>) + 'i,
+ ) -> impl Iterator<Item = I> + 'i
+ where T: 'i
+ {
+ let mut next = head;
+ iter::from_fn(move || {
+ let node = next?;
+ let item;
+ (item, next) = node_map(node);
+ Some(item)
+ })
+ }
}
impl<T: Debug> Drop for List<T> {