|
|
|
@ -16,6 +16,7 @@
|
|
|
|
|
//! - You need to share the array across multiple threads *(you may use `Vec<Mutex<T>>` or `Arc<Vec<Mutex<T>>>` instead)*
|
|
|
|
|
|
|
|
|
|
use std::cell::{Cell, UnsafeCell};
|
|
|
|
|
use std::cmp::Ordering;
|
|
|
|
|
use std::fmt::{self, Debug, Display};
|
|
|
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
|
|
|
|
|
@ -102,7 +103,7 @@ impl<T> VecCell<T> {
|
|
|
|
|
Self {
|
|
|
|
|
mut_borrow: Cell::new(None),
|
|
|
|
|
borrows: Cell::new(0),
|
|
|
|
|
inner: Vec::with_capacity(capacity)
|
|
|
|
|
inner: Vec::with_capacity(capacity),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -356,7 +357,10 @@ impl<T> VecCell<T> {
|
|
|
|
|
/// assert_eq!(s[1], 2);
|
|
|
|
|
/// assert!(s.get(2).is_none());
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn borrow_range<'b, R: std::ops::RangeBounds<usize>>(&'b self, range: R) -> Option<VecRef<'b, [T]>> {
|
|
|
|
|
pub fn borrow_range<'b, R: std::ops::RangeBounds<usize>>(
|
|
|
|
|
&'b self,
|
|
|
|
|
range: R,
|
|
|
|
|
) -> Option<VecRef<'b, [T]>> {
|
|
|
|
|
VecRef::from_range(self, range)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -491,9 +495,7 @@ impl<T> VecCell<T> {
|
|
|
|
|
/// std::mem::drop(x);
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn try_iter<'b>(&'b self) -> impl Iterator<Item = Option<VecRef<'b, T>>> {
|
|
|
|
|
(0..self.len()).map(|index| {
|
|
|
|
|
self.borrow(index)
|
|
|
|
|
})
|
|
|
|
|
(0..self.len()).map(|index| self.borrow(index))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Resets the [`borrows`](VecCell::borrows) and [`mut_borrow`](VecCell::mut_borrow) counters.
|
|
|
|
@ -547,11 +549,134 @@ impl<T> VecCell<T> {
|
|
|
|
|
/// If no reference was [forgotten](std::mem::forget), then `mut_borrow == None` and `borrows == 0`.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn into_raw_parts(self) -> (Vec<UnsafeCell<T>>, Option<usize>, usize) {
|
|
|
|
|
(self.inner, self.mut_borrow.into_inner(), self.borrows.into_inner())
|
|
|
|
|
(
|
|
|
|
|
self.inner,
|
|
|
|
|
self.mut_borrow.into_inner(),
|
|
|
|
|
self.borrows.into_inner(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// == Unsafe functions section ==
|
|
|
|
|
|
|
|
|
|
/// Sorts the vector, but might not preserve the order of equal elements.
|
|
|
|
|
///
|
|
|
|
|
/// This sort uses the same implementation as `[T]::sort_unstable_by`.
|
|
|
|
|
///
|
|
|
|
|
/// ## Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use veccell::*;
|
|
|
|
|
/// let mut vec: VecCell<usize> = VecCell::new();
|
|
|
|
|
///
|
|
|
|
|
/// vec.push(30);
|
|
|
|
|
/// vec.push(0);
|
|
|
|
|
/// vec.push(20);
|
|
|
|
|
/// vec.push(10);
|
|
|
|
|
///
|
|
|
|
|
/// vec.sort_unstable();
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(vec.borrow(0).unwrap(), 0);
|
|
|
|
|
/// assert_eq!(vec.borrow(1).unwrap(), 10);
|
|
|
|
|
/// assert_eq!(vec.borrow(2).unwrap(), 20);
|
|
|
|
|
/// assert_eq!(vec.borrow(3).unwrap(), 30);
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn sort_unstable(&mut self)
|
|
|
|
|
where
|
|
|
|
|
T: Ord,
|
|
|
|
|
{
|
|
|
|
|
self.sort_unstable_by(|a, b| a.cmp(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sorts the vector with a comparator function, but might not preserve the order of
|
|
|
|
|
/// equal elements.
|
|
|
|
|
///
|
|
|
|
|
/// This sort uses the same implementation as `[T]::sort_unstable_by`.
|
|
|
|
|
///
|
|
|
|
|
/// ## Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use veccell::*;
|
|
|
|
|
/// let mut vec: VecCell<usize> = VecCell::new();
|
|
|
|
|
///
|
|
|
|
|
/// vec.push(30);
|
|
|
|
|
/// vec.push(0);
|
|
|
|
|
/// vec.push(20);
|
|
|
|
|
/// vec.push(10);
|
|
|
|
|
///
|
|
|
|
|
/// vec.sort_unstable_by(|a, b| b.cmp(a));
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(vec.borrow(0).unwrap(), 30);
|
|
|
|
|
/// assert_eq!(vec.borrow(1).unwrap(), 20);
|
|
|
|
|
/// assert_eq!(vec.borrow(2).unwrap(), 10);
|
|
|
|
|
/// assert_eq!(vec.borrow(3).unwrap(), 0);
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn sort_unstable_by<F>(&mut self, mut compare: F)
|
|
|
|
|
where
|
|
|
|
|
T: Ord,
|
|
|
|
|
F: FnMut(&T, &T) -> Ordering,
|
|
|
|
|
{
|
|
|
|
|
assert_eq!(
|
|
|
|
|
self.borrows.get(),
|
|
|
|
|
0,
|
|
|
|
|
"Sorting requires that no item is currently borrowed"
|
|
|
|
|
);
|
|
|
|
|
assert!(
|
|
|
|
|
self.mut_borrow.get().is_none(),
|
|
|
|
|
"Sorting requires that no item is currently (mutably) borrowed"
|
|
|
|
|
);
|
|
|
|
|
self.inner.sort_unstable_by(|a, b| {
|
|
|
|
|
// SAFETY: self is borrowed mutably and a and b are not itself changed.
|
|
|
|
|
let a = unsafe { &*a.get() };
|
|
|
|
|
let b = unsafe { &*b.get() };
|
|
|
|
|
compare(a, b)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sorts the vector with a key extraction function, but might not preserve the order of
|
|
|
|
|
/// equal elements.
|
|
|
|
|
///
|
|
|
|
|
/// This sort uses the same implementation as `[T]::sort_unstable_by_key`.
|
|
|
|
|
///
|
|
|
|
|
/// ## Example
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # use veccell::*;
|
|
|
|
|
/// let mut vec: VecCell<isize> = VecCell::new();
|
|
|
|
|
///
|
|
|
|
|
/// vec.push(30);
|
|
|
|
|
/// vec.push(0);
|
|
|
|
|
/// vec.push(20);
|
|
|
|
|
/// vec.push(10);
|
|
|
|
|
///
|
|
|
|
|
/// vec.sort_unstable_by_key(|a| -(*a));
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(vec.borrow(0).unwrap(), 30);
|
|
|
|
|
/// assert_eq!(vec.borrow(1).unwrap(), 20);
|
|
|
|
|
/// assert_eq!(vec.borrow(2).unwrap(), 10);
|
|
|
|
|
/// assert_eq!(vec.borrow(3).unwrap(), 0);
|
|
|
|
|
/// ```
|
|
|
|
|
pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
|
|
|
|
|
where
|
|
|
|
|
F: FnMut(&T) -> K,
|
|
|
|
|
K: Ord,
|
|
|
|
|
{
|
|
|
|
|
assert_eq!(
|
|
|
|
|
self.borrows.get(),
|
|
|
|
|
0,
|
|
|
|
|
"Sorting requires that no item is currently borrowed"
|
|
|
|
|
);
|
|
|
|
|
assert!(
|
|
|
|
|
self.mut_borrow.get().is_none(),
|
|
|
|
|
"Sorting requires that no item is currently (mutably) borrowed"
|
|
|
|
|
);
|
|
|
|
|
self.inner.sort_unstable_by(|a, b| {
|
|
|
|
|
// SAFETY: self is borrowed mutably and a and b are not itself changed.
|
|
|
|
|
let a = f(unsafe { &*a.get() });
|
|
|
|
|
let b = f(unsafe { &*b.get() });
|
|
|
|
|
a.cmp(&b)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Alternative to `get`, which skips all checks and returns a mutable reference.
|
|
|
|
|
/// Neither the `mut_borrow`, nor the `borrows` buffer will be updated or read,
|
|
|
|
|
/// so make sure that no exclusive reference to the element at `index` is made.
|
|
|
|
@ -571,7 +696,11 @@ impl<T> VecCell<T> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Constructs a `VecCell` from its raw parts.
|
|
|
|
|
pub unsafe fn from_raw_parts(inner: Vec<UnsafeCell<T>>, mut_borrow: Option<usize>, borrows: usize) -> Self {
|
|
|
|
|
pub unsafe fn from_raw_parts(
|
|
|
|
|
inner: Vec<UnsafeCell<T>>,
|
|
|
|
|
mut_borrow: Option<usize>,
|
|
|
|
|
borrows: usize,
|
|
|
|
|
) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
inner,
|
|
|
|
|
borrows: Cell::new(borrows),
|
|
|
|
@ -599,12 +728,16 @@ impl<T: fmt::Debug> fmt::Debug for VecCell<T> {
|
|
|
|
|
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<[_]>>())
|
|
|
|
|
.field(
|
|
|
|
|
"inner",
|
|
|
|
|
&self
|
|
|
|
|
.try_iter()
|
|
|
|
|
.map(|x| match x {
|
|
|
|
|
Some(y) => BorrowStatus::Ok(y),
|
|
|
|
|
None => BorrowStatus::Borrowed,
|
|
|
|
|
})
|
|
|
|
|
.collect::<Box<[_]>>(),
|
|
|
|
|
)
|
|
|
|
|
.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -619,7 +752,7 @@ impl<'a, T: 'a> IntoIterator for &'a VecCell<T> {
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
|
VecCellRefIter {
|
|
|
|
|
vec: self,
|
|
|
|
|
index: 0
|
|
|
|
|
index: 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -629,7 +762,7 @@ impl<'a, T: 'a> IntoIterator for &'a VecCell<T> {
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct VecCellRefIter<'a, T> {
|
|
|
|
|
vec: &'a VecCell<T>,
|
|
|
|
|
index: usize
|
|
|
|
|
index: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, T> Iterator for VecCellRefIter<'a, T> {
|
|
|
|
@ -637,12 +770,15 @@ impl<'a, T> Iterator for VecCellRefIter<'a, T> {
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
if self.index >= self.vec.len() {
|
|
|
|
|
return None
|
|
|
|
|
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),
|
|
|
|
|
None => panic!(
|
|
|
|
|
"Error while borrowing immutably element {} of VecCell: already mutably borrowed",
|
|
|
|
|
self.index
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
self.index += 1;
|
|
|
|
|
|
|
|
|
@ -681,7 +817,7 @@ impl<T> IntoIterator for VecCell<T> {
|
|
|
|
|
/// Panics if a value is currently mutably borrowed
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
|
VecCellIntoIter {
|
|
|
|
|
iter: self.inner.into_iter()
|
|
|
|
|
iter: self.inner.into_iter(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -718,7 +854,10 @@ impl<T: Clone> Clone for VecCell<T> {
|
|
|
|
|
/// Panics if a value is currently mutably borrowed
|
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
VecCell {
|
|
|
|
|
inner: self.into_iter().map(|x| UnsafeCell::new((*x).clone())).collect::<Vec<_>>(),
|
|
|
|
|
inner: self
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|x| UnsafeCell::new((*x).clone()))
|
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
|
mut_borrow: Cell::new(None),
|
|
|
|
|
borrows: Cell::new(0),
|
|
|
|
|
}
|
|
|
|
@ -731,12 +870,12 @@ impl<T: PartialEq> PartialEq for VecCell<T> {
|
|
|
|
|
/// Panics if a value in `self` or `other` is currently mutably borrowed when it is encountered in the comparison.
|
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
|
if self.len() != other.len() {
|
|
|
|
|
return false
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (s, o) in self.iter().zip(other.iter()) {
|
|
|
|
|
if *s != *o {
|
|
|
|
|
return false
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -750,12 +889,12 @@ impl<T: PartialEq> PartialEq<Vec<T>> for VecCell<T> {
|
|
|
|
|
/// Panics if a value in `self` is currently mutably borrowed when it is encountered in the comparison.
|
|
|
|
|
fn eq(&self, other: &Vec<T>) -> bool {
|
|
|
|
|
if self.len() != other.len() {
|
|
|
|
|
return false
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (s, o) in self.iter().zip(other.iter()) {
|
|
|
|
|
if *s != *o {
|
|
|
|
|
return false
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -766,7 +905,10 @@ impl<T: PartialEq> PartialEq<Vec<T>> for VecCell<T> {
|
|
|
|
|
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<_>>(),
|
|
|
|
|
inner: vec
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|x| UnsafeCell::new(x))
|
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
|
mut_borrow: Cell::new(None),
|
|
|
|
|
borrows: Cell::new(0),
|
|
|
|
|
}
|
|
|
|
@ -783,9 +925,11 @@ impl<T> From<VecCell<T>> for Vec<T> {
|
|
|
|
|
impl<T: serde::Serialize> serde::Serialize for VecCell<T> {
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
where
|
|
|
|
|
S: serde::Serializer
|
|
|
|
|
S: serde::Serializer,
|
|
|
|
|
{
|
|
|
|
|
let range = self.borrow_range(..).expect("Cannot borrow immutably VecCell: already borrowed mutably.");
|
|
|
|
|
let range = self
|
|
|
|
|
.borrow_range(..)
|
|
|
|
|
.expect("Cannot borrow immutably VecCell: already borrowed mutably.");
|
|
|
|
|
(*range).serialize(serializer)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -794,7 +938,7 @@ impl<T: serde::Serialize> serde::Serialize for VecCell<T> {
|
|
|
|
|
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>
|
|
|
|
|
D: serde::Deserializer<'de>,
|
|
|
|
|
{
|
|
|
|
|
let vec: Vec<T> = Vec::deserialize(deserializer)?;
|
|
|
|
|
Ok(Self::from(vec))
|
|
|
|
|