🐛 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]
name = "veccell"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
authors = [ "Shad Amethyst <adrien.burgun@orange.fr>" ]
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 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::fmt::{self, Debug};
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> {
type Item = VecRef<'a, T>;
type IntoIter = impl Iterator<Item = Self::Item>;
type IntoIter = VecCellRefIter<'a, T>;
/// # Panics
///
/// Panics if a value is currently mutably borrowed
fn into_iter(self) -> Self::IntoIter {
(0..self.len()).map(|index| {
match self.get(index) {
Some(x) => x,
None => panic!("Error while borrowing immutably element {} of VecCell: already mutably borrowed", index),
VecCellRefIter {
vec: self,
index: 0
}
})
}
}
// 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> {
type Item = T;
type IntoIter = impl Iterator<Item = Self::Item>;
type IntoIter = VecCellIntoIter<T>;
/// # Panics
///
/// Panics if a value is currently mutably borrowed
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`].
pub struct VecRefMut<'a, T: ?Sized> {
mut_borrow: &'a Cell<Option<usize>>,
mut_borrow: VecRefMutBorrow<'a>,
value: &'a mut T,
}
@ -834,7 +873,7 @@ impl<'a, T: ?Sized> VecRefMut<'a, T> {
vec.mut_borrow.set(Some(index));
Some(Self {
mut_borrow: &vec.mut_borrow,
mut_borrow: VecRefMutBorrow(&vec.mut_borrow),
value: unsafe {
vec.get_mut_unchecked(index)
}
@ -881,16 +920,28 @@ impl<'a, T: ?Sized> VecRefMut<'a, T> {
&mut *self.value
}
// 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
// }
// }
/// Transforms a `VecRefMut<'_, T>` into a `VecRefMut<'_, U>` from a function that maps `&mut T` to `&mut U`.
///
/// This function does not use `self` and must be called explicitly via `VecRefMut::map(value, function)`.
///
/// # Examples
///
/// ```
/// # 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> {
@ -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]
fn drop(&mut self) {
debug_assert!(self.mut_borrow.get().is_some());
self.mut_borrow.set(None);
debug_assert!(self.0.get().is_some());
self.0.set(None);
}
}

Loading…
Cancel
Save