From 141be13feb2a33b21a7e415a991b3af46e49a9e1 Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Tue, 28 Jun 2022 12:45:00 +0200 Subject: [PATCH] :sparkles: First commit --- .gitignore | 2 + Cargo.toml | 8 +++ src/lib.rs | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0376e5a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "veccell" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6a676c6 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,189 @@ +use std::cell::{Cell, UnsafeCell}; +use std::fmt::{self, Debug}; + +pub struct VecCell { + mut_borrow: Cell>, + borrows: Cell, + inner: Vec>, +} + +impl VecCell { + pub fn new() -> Self { + Self { + mut_borrow: Cell::new(None), + borrows: Cell::new(0), + inner: Vec::new(), + } + } + + pub fn with_capacity(capacity: usize) -> Self { + Self { + mut_borrow: Cell::new(None), + borrows: Cell::new(0), + inner: Vec::with_capacity(capacity) + } + } + + pub fn into_raw_parts(self) -> (Vec>, Option, usize) { + (self.inner, self.mut_borrow.into_inner(), self.borrows.into_inner()) + } + + pub unsafe fn from_raw_parts(inner: Vec>, mut_borrow: Option, borrows: usize) -> Self { + Self { + inner, + borrows: Cell::new(borrows), + mut_borrow: Cell::new(mut_borrow), + } + } + + #[inline] + pub fn len(&self) -> usize { + self.inner.len() + } + + pub fn borrows(&self) -> usize { + self.borrows.get() + } + + pub fn mut_borrow(&self) -> Option { + self.mut_borrow.get() + } + + pub fn push(&mut self, value: T) { + self.inner.push(UnsafeCell::new(value)); + } + + pub fn pop(&mut self) -> Option { + debug_assert!(self.mut_borrow.get().is_none()); + self.inner.pop().map(UnsafeCell::into_inner) + } + + pub fn get<'b>(&'b self, index: usize) -> Option> { + VecRef::new(self, index) + } + + pub unsafe fn get_unchecked(&self, index: usize) -> &T { + &*self.inner.get_unchecked(index).get() + } + + pub fn borrow_mut<'b>(&'b self, index: usize) -> Option> { + VecRefMut::new(self, index) + } + + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + self.inner.get_mut(index).map(UnsafeCell::get_mut) + } + + pub unsafe fn get_mut_unchecked(&self, index: usize) -> &mut T { + &mut *self.inner.get_unchecked(index).get() + } +} + +pub struct VecRef<'a, T> { + borrows: &'a Cell, + value: &'a T, +} + +impl<'a, T> VecRef<'a, T> { + fn new(vec: &'a VecCell, index: usize) -> Option { + if vec.mut_borrow.get() == Some(index) { + return None + } + + if index >= vec.len() { + return None + } + + vec.borrows.set(vec.borrows.get().checked_add(1)?); + + Some(Self { + borrows: &vec.borrows, + value: unsafe { + // SAFETY: there are no mutable borrows of vec.inner[index] + vec.get_unchecked(index) + } + }) + } +} + +impl<'a, T> std::ops::Deref for VecRef<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.value + } +} + +impl<'a, T> 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> Debug for VecRef<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("VecRef") + .field(self.value) + .finish() + } +} + +pub struct VecRefMut<'a, T> { + mut_borrow: &'a Cell>, + value: &'a mut T, +} + +impl<'a, T> VecRefMut<'a, T> { + fn new(vec: &'a VecCell, index: usize) -> Option { + if vec.borrows.get() > 0 || vec.mut_borrow.get().is_some() { + return None + } + + if index >= vec.len() { + return None + } + + vec.mut_borrow.set(Some(index)); + + Some(Self { + mut_borrow: &vec.mut_borrow, + value: unsafe { + // SAFETY: there are no mutable borrows of ∀x, vec.inner[x], + // and we set vec.mut_borrow to Some(index), guaranteeing no further aliasing + vec.get_mut_unchecked(index) + } + }) + } +} + +impl<'a, T> std::ops::Deref for VecRefMut<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.value + } +} + +impl<'a, T> std::ops::DerefMut for VecRefMut<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.value + } +} + +impl<'a, T> Drop for VecRefMut<'a, T> { + #[inline] + fn drop(&mut self) { + debug_assert!(self.mut_borrow.get().is_some()); + self.mut_borrow.set(None); + } +} + +impl<'a, T: Debug> Debug for VecRefMut<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("VecRefMut") + .field(self.value) + .finish() + } +}