🔥 Rename VecCell::get to VecCell::borrow

pull/1/head
Shad Amethyst 2 years ago
parent 54349d1d26
commit 4c1cae2537
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

@ -1,6 +1,6 @@
[package]
name = "veccell"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
authors = [ "Shad Amethyst <adrien.burgun@orange.fr>" ]
description = "Provides VecCell, a variant of Vec with interior mutability."

@ -7,7 +7,7 @@ You would use this crate if:
- You need a `Vec` with interior mutability
- You only want mutable access to one element at a time
- You want immutable access to all other elements while an element is borrowed mutably
- You need a constant memory cost
- You need a constant memory cost for the aliasing checks
You would need something else if:
@ -39,14 +39,14 @@ arr.push(48);
arr.push(2);
let mut third = arr.borrow_mut(2).unwrap(); // Borrow the third element mutably
let first = arr.get(0).unwrap(); // Borrow the first element immutably
let first = arr.borrow(0).unwrap(); // Borrow the first element immutably
*third *= *first; // Multiply the third element by the first element
println!("{}", third.get()); // Prints 64
std::mem::drop(third); // Drop the mutable borrow
println!("{}", arr.get(2).unwrap().get()); // Also prints 64
println!("{}", arr.borrow(2).unwrap().get()); // Also prints 64
```
However, to prevent aliasing, while an element is borrowed mutably, it cannot be borrowed immutably:
@ -62,9 +62,9 @@ arr.push(8);
let mut third = arr.borrow_mut(2).unwrap(); // Borrow the third element mutably
// Here, arr.get(2) returns None,
// Here, arr.borrow(2) returns None,
// because the third element is already borrowed mutably.
let third2 = arr.get(2);
let third2 = arr.borrow(2);
assert!(third2.is_none());
@ -89,7 +89,7 @@ arr.push(32);
arr.push(48);
arr.push(8);
let second = arr.get(1).unwrap();
let second = arr.borrow(1).unwrap();
let third = arr.borrow_mut(2);

@ -31,7 +31,7 @@ pub use vecrefmut::VecRefMut;
/// New mutable references may only be created if there are no active mutable *or immutable* references.
/// New immutable references may only be created for indices that aren't mutably borrowed.
///
/// - To borrow an item immutably, use [`get()`](VecCell::get).
/// - To borrow an item immutably, use [`borrow()`](VecCell::borrow).
/// - To borrow an item mutably, use [`borrow_mut()`](VecCell::borrow_mut).
/// - If you have a mutable reference to the `VecCell`, then you may also use [`get_mut()`](VecCell::get_mut).
/// - You may access the internal `Vec<UnsafeCell<T>>` using [`inner()`](VecCell::inner) and [`inner_mut()`](VecCell::inner_mut).
@ -62,7 +62,7 @@ pub use vecrefmut::VecRefMut;
/// // Get a mutable reference *then* an immutable reference
/// // (would fail if the order was reversed)
/// let mut current = vec.borrow_mut(index).unwrap();
/// let prev = vec.get(index - 1).unwrap();
/// let prev = vec.borrow(index - 1).unwrap();
///
/// // Give both references to update
/// update(current.get_mut(), prev.get());
@ -221,7 +221,7 @@ impl<T> VecCell<T> {
/// // There are no borrows at this point
/// assert_eq!(vec.borrows(), 0);
///
/// let x = vec.get(1);
/// let x = vec.borrow(1);
///
/// // There is exactly one borrow at this point
/// assert_eq!(vec.borrows(), 1);
@ -270,11 +270,11 @@ impl<T> VecCell<T> {
///
/// vec.push(32);
/// assert_eq!(vec.len(), 1);
/// assert_eq!(vec.get(0).unwrap(), 32);
/// assert_eq!(vec.borrow(0).unwrap(), 32);
///
/// vec.push(127);
/// assert_eq!(vec.len(), 2);
/// assert_eq!(vec.get(1).unwrap(), 127);
/// assert_eq!(vec.borrow(1).unwrap(), 127);
/// ```
pub fn push(&mut self, value: T) {
self.inner.push(UnsafeCell::new(value));
@ -319,11 +319,11 @@ impl<T> VecCell<T> {
/// vec.push(2);
/// vec.push(3);
///
/// let x = vec.get(1).unwrap();
/// let x = vec.borrow(1).unwrap();
///
/// assert_eq!(*x, 2);
///
/// let y = vec.get(1).unwrap();
/// let y = vec.borrow(1).unwrap();
///
/// assert_eq!(x, y);
///
@ -331,7 +331,7 @@ impl<T> VecCell<T> {
/// std::mem::drop(x);
/// std::mem::drop(y);
/// ```
pub fn get<'b>(&'b self, index: usize) -> Option<VecRef<'b, T>> {
pub fn borrow<'b>(&'b self, index: usize) -> Option<VecRef<'b, T>> {
VecRef::new(self, index)
}
@ -351,7 +351,7 @@ impl<T> VecCell<T> {
/// vec.push(2);
/// vec.push(3);
///
/// let s = vec.borrow_range(0..2); // Gets elements 0 and 1
/// let s = vec.borrow_range(0..2).unwrap(); // Gets elements 0 and 1
/// ```
pub fn borrow_range<'b, R: std::ops::RangeBounds<usize>>(&'b self, range: R) -> Option<VecRange<'b, T>> {
VecRange::new(self, range)
@ -375,7 +375,7 @@ impl<T> VecCell<T> {
/// vec.push(3);
///
/// let mut x = vec.borrow_mut(1).unwrap();
/// let y = vec.get(2).unwrap();
/// let y = vec.borrow(2).unwrap();
///
/// *x = *y;
///
@ -383,7 +383,7 @@ impl<T> VecCell<T> {
/// std::mem::drop(x);
/// std::mem::drop(y);
///
/// assert_eq!(vec.get(1).unwrap(), 3);
/// assert_eq!(vec.borrow(1).unwrap(), 3);
/// ```
pub fn borrow_mut<'b>(&'b self, index: usize) -> Option<VecRefMut<'b, T>> {
VecRefMut::new(self, index)
@ -405,7 +405,7 @@ impl<T> VecCell<T> {
/// let x = vec.get_mut(1).unwrap();
/// *x = 5;
///
/// assert_eq!(vec.get(1).unwrap(), 5);
/// assert_eq!(vec.borrow(1).unwrap(), 5);
/// ```
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.inner.get_mut(index).map(UnsafeCell::get_mut)
@ -489,7 +489,7 @@ impl<T> VecCell<T> {
/// ```
pub fn try_iter<'b>(&'b self) -> impl Iterator<Item = Option<VecRef<'b, T>>> {
(0..self.len()).map(|index| {
self.get(index)
self.borrow(index)
})
}
@ -509,7 +509,7 @@ impl<T> VecCell<T> {
/// vec.push(2);
///
/// let x = vec.borrow_mut(1);
/// let y = vec.get(2);
/// let y = vec.borrow(2);
///
/// std::mem::forget(x);
/// std::mem::forget(y);
@ -622,6 +622,7 @@ impl<'a, T: 'a> IntoIterator for &'a VecCell<T> {
}
// TODO: remove once https://github.com/rust-lang/rust/issues/63063 is merged
/// Iterator returned by [`VecCell::iter`]
#[derive(Clone)]
pub struct VecCellRefIter<'a, T> {
vec: &'a VecCell<T>,
@ -636,7 +637,7 @@ impl<'a, T> Iterator for VecCellRefIter<'a, T> {
return None
}
let res = match self.vec.get(self.index) {
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),
};
@ -644,8 +645,30 @@ impl<'a, T> Iterator for VecCellRefIter<'a, T> {
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>;
@ -661,6 +684,7 @@ impl<T> IntoIterator for VecCell<T> {
}
// TODO: remove once https://github.com/rust-lang/rust/issues/63063 is merged
/// Iterator returned by [`VecCell::into_iter`]
pub struct VecCellIntoIter<T> {
iter: std::vec::IntoIter<UnsafeCell<T>>,
}
@ -671,8 +695,20 @@ impl<T> Iterator for VecCellIntoIter<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> {
/// # Panics
///
@ -734,6 +770,12 @@ impl<T> From<Vec<T>> for VecCell<T> {
}
}
impl<T> From<VecCell<T>> for Vec<T> {
fn from(veccell: VecCell<T>) -> Vec<T> {
veccell.into_iter().collect::<Vec<_>>()
}
}
#[cfg(test)]
mod test;

@ -66,14 +66,14 @@ fn test_borrow() {
let mut x = vec.borrow_mut(1).unwrap();
assert_eq!(vec.get(0).unwrap(), 1);
assert_eq!(vec.get(1), None);
assert_eq!(vec.borrow(0).unwrap(), 1);
assert_eq!(vec.borrow(1), None);
*x = 3;
std::mem::drop(x);
assert_eq!(vec.get(1).unwrap(), 3);
assert_eq!(vec.borrow(1).unwrap(), 3);
}
#[test]
@ -90,8 +90,8 @@ fn test_double_borrow() {
assert!(vec.borrow_mut(1).is_none());
assert_eq!(vec.mut_borrow(), Some(1));
assert_eq!(vec.get(0).unwrap(), 1);
assert_eq!(vec.get(1), None);
assert_eq!(vec.borrow(0).unwrap(), 1);
assert_eq!(vec.borrow(1), None);
*x = 3;
@ -99,19 +99,19 @@ fn test_double_borrow() {
std::mem::drop(y);
assert_eq!(vec.mut_borrow(), None);
assert_eq!(vec.get(1).unwrap(), 3);
assert_eq!(vec.borrow(1).unwrap(), 3);
}
#[test]
fn test_out_of_bounds() {
let mut vec: VecCell<usize> = VecCell::new();
assert!(vec.get(0).is_none());
assert!(vec.borrow(0).is_none());
vec.push(1);
assert!(vec.get(0).is_some());
assert!(vec.get(1).is_none());
assert!(vec.borrow(0).is_some());
assert!(vec.borrow(1).is_none());
}
#[test]
@ -121,7 +121,7 @@ fn test_borrow_clone() {
vec.push(1);
vec.push(2);
let x = vec.get(0);
let x = vec.borrow(0);
assert_eq!(vec.borrows(), 1);
assert_eq!(vec.borrows(), 1);
assert_eq!(vec.mut_borrow(), None);
@ -139,9 +139,9 @@ fn test_borrow_clone() {
std::mem::drop(y);
assert_eq!(vec.borrows(), 0);
let x = vec.get(0);
let x = vec.borrow(0);
assert_eq!(vec.borrows(), 1);
let y = vec.get(0);
let y = vec.borrow(0);
assert_eq!(vec.borrows(), 2);
let z = x.clone();
assert_eq!(vec.borrows(), 3);
@ -161,7 +161,7 @@ fn test_borrow_mut() {
vec.push(1);
vec.push(2);
let x = vec.get(0);
let x = vec.borrow(0);
assert!(x.is_some());
let y = vec.borrow_mut(0);

@ -48,6 +48,8 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
}
/// Returns a reference to the borrowed value.
/// Equivalent to `&*vec_ref`.
///
/// The reference may not outlive this `VecRef` instance.
///
/// # Example
@ -59,7 +61,7 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
/// vec.push(String::from("hello"));
/// vec.push(String::from("world"));
///
/// let guard = vec.get(0).unwrap();
/// let guard = vec.borrow(0).unwrap();
/// assert_eq!(guard.get(), "hello");
/// ```
pub fn get(&self) -> &T {
@ -87,7 +89,7 @@ impl<'a, T: ?Sized> VecRef<'a, T> {
/// ```
/// # use veccell::*;
/// fn return_favorite_value<'a>(array: &'a VecCell<Vec<u8>>) -> VecRef<'a, u8> {
/// VecRef::map(array.get(42).unwrap(), |vec| &vec[7])
/// VecRef::map(array.borrow(42).unwrap(), |vec| &vec[7])
/// }
/// ```
pub fn map<'b, U: ?Sized, F>(original: VecRef<'b, T>, f: F) -> VecRef<'b, U>
@ -222,6 +224,7 @@ impl<'a, T> VecRange<'a, T> {
}
}
// TODO: use std::mem::transmute to implement From<VecRange<'a, T>> for VecRef<'a, [T]>?
impl<'a, T> From<VecRange<'a, T>> for VecRef<'a, [UnsafeCell<T>]> {
fn from(range: VecRange<'a, T>) -> Self {
Self {

Loading…
Cancel
Save