🐛 Use stable APIs only

pull/1/head
Shad Amethyst 2 years ago
parent 0cdf2526a2
commit 18ef956a91
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

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

@ -15,8 +15,6 @@
//! - You want mutable access to multiple elements at a time *(you may use `Vec<RefCell<T>>` instead)* //! - You want mutable access to multiple elements at a time *(you may use `Vec<RefCell<T>>` instead)*
//! - You need to share the array across multiple threads *(you may use `Vec<Mutex<T>>` or `Arc<Vec<Mutex<T>>>` instead)* //! - You need to share the array across multiple threads *(you may use `Vec<Mutex<T>>` or `Arc<Vec<Mutex<T>>>` instead)*
#![feature(type_alias_impl_trait)]
use std::cell::{Cell, UnsafeCell}; use std::cell::{Cell, UnsafeCell};
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@ -582,30 +580,68 @@ impl<T: fmt::Debug> fmt::Debug for VecCell<T> {
impl<'a, T: 'a> IntoIterator for &'a VecCell<T> { impl<'a, T: 'a> IntoIterator for &'a VecCell<T> {
type Item = VecRef<'a, T>; type Item = VecRef<'a, T>;
type IntoIter = impl Iterator<Item = Self::Item>; type IntoIter = VecCellRefIter<'a, T>;
/// # Panics /// # Panics
/// ///
/// Panics if a value is currently mutably borrowed /// Panics if a value is currently mutably borrowed
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
(0..self.len()).map(|index| { VecCellRefIter {
match self.get(index) { vec: self,
Some(x) => x, index: 0
None => panic!("Error while borrowing immutably element {} of VecCell: already mutably borrowed", index), }
} }
}) }
// TODO: remove once https://github.com/rust-lang/rust/issues/63063 is merged
#[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.get(self.index) {
Some(x) => x,
None => panic!("Error while borrowing immutably element {} of VecCell: already mutably borrowed", self.index),
};
self.index += 1;
Some(res)
} }
} }
impl<T> IntoIterator for VecCell<T> { impl<T> IntoIterator for VecCell<T> {
type Item = T; type Item = T;
type IntoIter = impl Iterator<Item = Self::Item>; type IntoIter = VecCellIntoIter<T>;
/// # Panics /// # Panics
/// ///
/// Panics if a value is currently mutably borrowed /// Panics if a value is currently mutably borrowed
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter().map(|x| x.into_inner()) VecCellIntoIter {
iter: self.inner.into_iter()
}
}
}
// TODO: remove once https://github.com/rust-lang/rust/issues/63063 is merged
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())
} }
} }
@ -803,9 +839,12 @@ impl<'a, T: ?Sized> Clone for VecRef<'a, T> {
} }
} }
// Lets us safely destructure VecRefMut while implementing the Drop logic
struct VecRefMutBorrow<'a>(&'a Cell<Option<usize>>);
/// Wraps a mutably borrowed value from a [`VecCell`]. /// Wraps a mutably borrowed value from a [`VecCell`].
pub struct VecRefMut<'a, T: ?Sized> { pub struct VecRefMut<'a, T: ?Sized> {
mut_borrow: &'a Cell<Option<usize>>, mut_borrow: VecRefMutBorrow<'a>,
value: &'a mut T, value: &'a mut T,
} }
@ -834,7 +873,7 @@ impl<'a, T: ?Sized> VecRefMut<'a, T> {
vec.mut_borrow.set(Some(index)); vec.mut_borrow.set(Some(index));
Some(Self { Some(Self {
mut_borrow: &vec.mut_borrow, mut_borrow: VecRefMutBorrow(&vec.mut_borrow),
value: unsafe { value: unsafe {
vec.get_mut_unchecked(index) vec.get_mut_unchecked(index)
} }
@ -881,16 +920,28 @@ impl<'a, T: ?Sized> VecRefMut<'a, T> {
&mut *self.value &mut *self.value
} }
// pub fn map<'b, U: ?Sized, F>(original: VecRefMut<'b, T>, f: F) -> VecRefMut<'b, U> /// Transforms a `VecRefMut<'_, T>` into a `VecRefMut<'_, U>` from a function that maps `&mut T` to `&mut U`.
// where ///
// F: FnOnce(&mut T) -> &mut U /// This function does not use `self` and must be called explicitly via `VecRefMut::map(value, function)`.
// { ///
// let VecRefMut { value, mut_borrow } = original; /// # Examples
// VecRefMut { ///
// value: f(value), /// ```
// mut_borrow /// # use veccell::*;
// } /// fn return_favorite_value_mut<'a>(array: &'a VecCell<Vec<u8>>) -> VecRefMut<'a, u8> {
// } /// VecRefMut::map(array.borrow_mut(42).unwrap(), |vec| &mut vec[7])
/// }
/// ```
pub fn map<'b, U: ?Sized, F>(original: VecRefMut<'b, T>, f: F) -> VecRefMut<'b, U>
where
F: FnOnce(&mut T) -> &mut U
{
let VecRefMut { value, mut_borrow } = original;
VecRefMut {
value: f(value),
mut_borrow
}
}
} }
impl<'a, T: ?Sized> Deref for VecRefMut<'a, T> { impl<'a, T: ?Sized> Deref for VecRefMut<'a, T> {
@ -909,11 +960,11 @@ impl<'a, T: ?Sized> DerefMut for VecRefMut<'a, T> {
} }
} }
impl<'a, T: ?Sized> Drop for VecRefMut<'a, T> { impl<'a> Drop for VecRefMutBorrow<'a> {
#[inline] #[inline]
fn drop(&mut self) { fn drop(&mut self) {
debug_assert!(self.mut_borrow.get().is_some()); debug_assert!(self.0.get().is_some());
self.mut_borrow.set(None); self.0.set(None);
} }
} }

Loading…
Cancel
Save