use std::cell::{Cell, UnsafeCell};
use std::fmt::{self, Debug, Display};
use std::ops::{Deref, DerefMut};
mod vecref;
pub use vecref::VecRef;
mod vecrefmut;
pub use vecrefmut::VecRefMut;
pub struct VecCell<T> {
mut_borrow: Cell<Option<usize>>,
borrows: Cell<usize>,
inner: Vec<UnsafeCell<T>>,
}
impl<T> VecCell<T> {
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)
}
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
#[inline]
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional);
}
#[inline]
pub fn remove(&mut self, index: usize) -> T {
self.inner.remove(index).into_inner()
}
#[inline]
pub fn swap_remove(&mut self, index: usize) -> T {
self.inner.swap_remove(index).into_inner()
}
pub fn borrows(&self) -> usize {
self.borrows.get()
}
pub fn mut_borrow(&self) -> Option<usize> {
self.mut_borrow.get()
}
pub fn push(&mut self, value: T) {
self.inner.push(UnsafeCell::new(value));
}
pub fn pop(&mut self) -> Option<T> {
self.inner.pop().map(UnsafeCell::into_inner)
}
pub fn borrow<'b>(&'b self, index: usize) -> Option<VecRef<'b, T>> {
VecRef::new(self, index)
}
pub fn borrow_range<'b, R: std::ops::RangeBounds<usize>>(&'b self, range: R) -> Option<VecRef<'b, [T]>> {
VecRef::from_range(self, range)
}
pub fn borrow_mut<'b>(&'b self, index: usize) -> Option<VecRefMut<'b, T>> {
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 fn iter<'b>(&'b self) -> impl Iterator<Item = VecRef<'b, T>> {
self.into_iter()
}
pub fn iter_mut<'b>(&'b mut self) -> impl Iterator<Item = &'b mut T> {
self.inner.iter_mut().map(UnsafeCell::get_mut)
}
pub fn try_iter<'b>(&'b self) -> impl Iterator<Item = Option<VecRef<'b, T>>> {
(0..self.len()).map(|index| {
self.borrow(index)
})
}
pub fn undo_leak(&mut self) {
self.borrows.set(0);
self.mut_borrow.set(None);
}
#[inline]
pub fn inner(&self) -> &Vec<UnsafeCell<T>> {
&self.inner
}
#[inline]
pub fn inner_mut(&mut self) -> &mut Vec<UnsafeCell<T>> {
&mut self.inner
}
#[inline]
pub fn into_raw_parts(self) -> (Vec<UnsafeCell<T>>, Option<usize>, usize) {
(self.inner, self.mut_borrow.into_inner(), self.borrows.into_inner())
}
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
&*self.inner.get_unchecked(index).get()
}
pub unsafe fn get_mut_unchecked(&self, index: usize) -> &mut T {
&mut *self.inner.get_unchecked(index).get()
}
pub unsafe fn from_raw_parts(inner: Vec<UnsafeCell<T>>, mut_borrow: Option<usize>, borrows: usize) -> Self {
Self {
inner,
borrows: Cell::new(borrows),
mut_borrow: Cell::new(mut_borrow),
}
}
}
impl<T: fmt::Debug> fmt::Debug for VecCell<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
enum BorrowStatus<T> {
Ok(T),
Borrowed,
}
impl<T: Debug> fmt::Debug for BorrowStatus<VecRef<'_, T>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BorrowStatus::Ok(x) => fmt::Debug::fmt(&*x, f),
BorrowStatus::Borrowed => write!(f, "(borrowed)"),
}
}
}
f.debug_struct("VecCell")
.field("borrows", &self.borrows.get())
.field("mut_borrow", &self.mut_borrow.get())
.field("inner", &self.try_iter().map(|x| {
match x {
Some(y) => BorrowStatus::Ok(y),
None => BorrowStatus::Borrowed,
}
}).collect::<Box<[_]>>())
.finish()
}
}
impl<'a, T: 'a> IntoIterator for &'a VecCell<T> {
type Item = VecRef<'a, T>;
type IntoIter = VecCellRefIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
VecCellRefIter {
vec: self,
index: 0
}
}
}
#[derive(Clone)]
pub struct VecCellRefIter<'a, T> {
vec: &'a VecCell<T>,
index: usize
}
impl<'a, T> Iterator for VecCellRefIter<'a, T> {
type Item = VecRef<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.vec.len() {
return None
}
let res = match self.vec.borrow(self.index) {
Some(x) => x,
None => panic!("Error while borrowing immutably element {} of VecCell: already mutably borrowed", self.index),
};
self.index += 1;
Some(res)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.index >= self.vec.len() {
return (0, Some(0));
}
let remaining = self.vec.len() - self.index;
(remaining, Some(remaining))
}
}
impl<'a, T> ExactSizeIterator for VecCellRefIter<'a, T> {
fn len(&self) -> usize {
if self.index >= self.vec.len() {
0
} else {
self.vec.len() - self.index
}
}
}
impl<'a, T> std::iter::FusedIterator for VecCellRefIter<'a, T> {}
impl<T> IntoIterator for VecCell<T> {
type Item = T;
type IntoIter = VecCellIntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
VecCellIntoIter {
iter: self.inner.into_iter()
}
}
}
pub struct VecCellIntoIter<T> {
iter: std::vec::IntoIter<UnsafeCell<T>>,
}
impl<T> Iterator for VecCellIntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|x| x.into_inner())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T> ExactSizeIterator for VecCellIntoIter<T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> std::iter::FusedIterator for VecCellIntoIter<T> {}
impl<T: Clone> Clone for VecCell<T> {
fn clone(&self) -> Self {
VecCell {
inner: self.into_iter().map(|x| UnsafeCell::new((*x).clone())).collect::<Vec<_>>(),
mut_borrow: Cell::new(None),
borrows: Cell::new(0),
}
}
}
impl<T: PartialEq> PartialEq for VecCell<T> {
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false
}
for (s, o) in self.iter().zip(other.iter()) {
if *s != *o {
return false
}
}
true
}
}
impl<T: PartialEq> PartialEq<Vec<T>> for VecCell<T> {
fn eq(&self, other: &Vec<T>) -> bool {
if self.len() != other.len() {
return false
}
for (s, o) in self.iter().zip(other.iter()) {
if *s != *o {
return false
}
}
true
}
}
impl<T> From<Vec<T>> for VecCell<T> {
fn from(vec: Vec<T>) -> Self {
VecCell {
inner: vec.into_iter().map(|x| UnsafeCell::new(x)).collect::<Vec<_>>(),
mut_borrow: Cell::new(None),
borrows: Cell::new(0),
}
}
}
impl<T> From<VecCell<T>> for Vec<T> {
fn from(veccell: VecCell<T>) -> Vec<T> {
veccell.into_iter().collect::<Vec<_>>()
}
}
#[cfg(feature = "serde")]
impl<T: serde::Serialize> serde::Serialize for VecCell<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer
{
let range = self.borrow_range(..).expect("Cannot borrow immutably VecCell: already borrowed mutably.");
(*range).serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for VecCell<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>
{
let vec: Vec<T> = Vec::deserialize(deserializer)?;
Ok(Self::from(vec))
}
}
#[cfg(test)]
mod test;
#[doc = include_str!("../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;