|
|
|
@ -1,8 +1,10 @@
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::ops::RangeBounds;
|
|
|
|
|
|
|
|
|
|
/// Wraps a borrowed reference from a [`VecCell`].
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct VecRef<'a, T: ?Sized> {
|
|
|
|
|
borrows: &'a Cell<usize>,
|
|
|
|
|
borrows: VecRefBorrow<'a>,
|
|
|
|
|
value: &'a T,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -19,10 +21,8 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
|
|
|
|
|
return None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vec.borrows.set(vec.borrows.get().checked_add(1)?);
|
|
|
|
|
|
|
|
|
|
Some(Self {
|
|
|
|
|
borrows: &vec.borrows,
|
|
|
|
|
borrows: VecRefBorrow::new(&vec.borrows)?,
|
|
|
|
|
value: unsafe {
|
|
|
|
|
// SAFETY: there are no mutable borrows of vec.inner[index]
|
|
|
|
|
vec.get_unchecked(index)
|
|
|
|
@ -31,10 +31,8 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn from(value: &'a T, borrows: &'a Cell<usize>) -> Option<Self> {
|
|
|
|
|
borrows.set(borrows.get().checked_add(1)?);
|
|
|
|
|
|
|
|
|
|
Some(Self {
|
|
|
|
|
borrows,
|
|
|
|
|
borrows: VecRefBorrow::new(borrows)?,
|
|
|
|
|
value
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
@ -86,7 +84,7 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
|
|
|
|
|
where
|
|
|
|
|
F: FnOnce(&T) -> &U
|
|
|
|
|
{
|
|
|
|
|
VecRef::from(f(original.value), original.borrows).expect("Error creating a new VecRef: integer overflow")
|
|
|
|
|
VecRef::from(f(original.value), &original.borrows.0).expect("Error creating a new VecRef: integer overflow")
|
|
|
|
|
// original is dropped here
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -99,14 +97,6 @@ impl<'a, T: ?Sized> Deref for VecRef<'a, T> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T: ?Sized> Drop for VecRef<'a, T> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
debug_assert!(self.borrows.get() > 0, "Borrow count was null yet there was still a borrow!");
|
|
|
|
|
self.borrows.set(self.borrows.get() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T: Debug + Sized> Debug for VecRef<'a, T> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
f.debug_tuple("VecRef")
|
|
|
|
@ -127,8 +117,115 @@ impl<'a, T: PartialEq + ?Sized> PartialEq<T> for VecRef<'a, T> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T: ?Sized> Clone for VecRef<'a, T> {
|
|
|
|
|
struct VecRefBorrow<'a>(&'a Cell<usize>);
|
|
|
|
|
|
|
|
|
|
impl<'a> VecRefBorrow<'a> {
|
|
|
|
|
fn new(cell: &'a Cell<usize>) -> Option<Self> {
|
|
|
|
|
cell.set(cell.get().checked_add(1)?);
|
|
|
|
|
Some(Self(cell))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> Clone for VecRefBorrow<'a> {
|
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
Self::from(self.value, self.borrows).expect("Error creating a new VecRef: integer overflow")
|
|
|
|
|
VecRefBorrow::new(&self.0).expect("Error creating a new VecRef: integer overflow")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> Drop for VecRefBorrow<'a> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
debug_assert!(self.0.get() > 0, "Borrow count was null yet there was still a borrow!");
|
|
|
|
|
self.0.set(self.0.get() - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Represents an immutable slice for a [`VecCell`].
|
|
|
|
|
///
|
|
|
|
|
/// # Guarantees
|
|
|
|
|
///
|
|
|
|
|
/// All of the elements of the VecRange are guaranteed to be immutable.
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct VecRange<'a, T> {
|
|
|
|
|
borrows: VecRefBorrow<'a>,
|
|
|
|
|
range: &'a [UnsafeCell<T>],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> VecRange<'a, T> {
|
|
|
|
|
pub(crate) fn new<R: RangeBounds<usize>>(vec: &'a VecCell<T>, range: R) -> Option<VecRange<'a, T>>
|
|
|
|
|
where
|
|
|
|
|
T: Sized
|
|
|
|
|
{
|
|
|
|
|
match vec.mut_borrow() {
|
|
|
|
|
Some(index) => {
|
|
|
|
|
if range.contains(&index) {
|
|
|
|
|
return None; // There is still a mutable borrow to an index within the range
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
None => {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let low = range.start_bound().cloned();
|
|
|
|
|
let high = range.end_bound().cloned();
|
|
|
|
|
|
|
|
|
|
Some(VecRange {
|
|
|
|
|
borrows: VecRefBorrow::new(&vec.borrows)?,
|
|
|
|
|
range: &vec.inner[(low, high)],
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get(&self, index: usize) -> Option<&T> {
|
|
|
|
|
Some(unsafe {
|
|
|
|
|
// SAFETY: immutability is guaranteed by VecRange's type invariants
|
|
|
|
|
self.range.get(index)?.get().as_ref().unwrap()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> From<VecRange<'a, T>> for VecRef<'a, [UnsafeCell<T>]> {
|
|
|
|
|
fn from(range: VecRange<'a, T>) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
borrows: range.borrows,
|
|
|
|
|
value: range.range, // :3
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> std::ops::Index<usize> for VecRange<'a, T> {
|
|
|
|
|
type Output = T;
|
|
|
|
|
|
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
|
|
|
unsafe {
|
|
|
|
|
// SAFETY: immutability is guaranteed by VecRange's type invariants
|
|
|
|
|
self.range[index].get().as_ref().unwrap()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> IntoIterator for VecRange<'a, T> {
|
|
|
|
|
type Item = &'a T;
|
|
|
|
|
type IntoIter = VecRangeIter<'a, T>;
|
|
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
|
VecRangeIter {
|
|
|
|
|
iter: self.range.iter()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct VecRangeIter<'a, T> {
|
|
|
|
|
iter: std::slice::Iter<'a, UnsafeCell<T>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> Iterator for VecRangeIter<'a, T> {
|
|
|
|
|
type Item = &'a T;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
self.iter.next().map(|x| {
|
|
|
|
|
unsafe {
|
|
|
|
|
// SAFETY: immutability is guaranteed by VecRange's type invariants
|
|
|
|
|
x.get().as_ref().unwrap()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|