use std::cell::RefCell; use std::hash::Hash; use std::rc::Rc; /// A shared mutable array of `T` managed by reference counting. /// /// # Cloning /// /// The `Clone` trait implements cloning of the array by reference. /// Use the `clone_content()` method to clone the array by content. /// /// # Equality /// /// The `PartialEq` trait performs reference comparison of two arrays. /// /// # Hashing /// /// The `Hash` trait performs hashing of the array by reference. #[derive(Clone)] pub struct SharedArray(Rc>>); impl PartialEq for SharedArray { fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.0, &other.0) } } impl Eq for SharedArray {} impl Hash for SharedArray { /// Performs hashing of the array by reference. fn hash(&self, state: &mut H) { self.0.as_ptr().hash(state) } } impl SharedArray { pub fn new() -> Self { Self(Rc::new(RefCell::new(vec![]))) } pub fn get(&self, index: usize) -> Option where T: Clone { self.0.borrow().get(index).map(|v| v.clone()) } pub fn set(&mut self, index: usize, value: T) where T: Clone { self.0.borrow_mut()[index] = value.clone(); } pub fn remove(&mut self, index: usize) { self.0.borrow_mut().remove(index); } pub fn includes(&self, value: &T) -> bool where T: PartialEq { self.0.borrow().contains(value) } pub fn index_of(&self, value: &T) -> Option where T: PartialEq { let this = self.0.borrow(); for i in 0..self.length() { let value_2 = this.get(i).unwrap(); if value == value_2 { return Some(i); } } None } pub fn length(&self) -> usize { self.0.borrow().len() } pub fn push(&mut self, value: T) { self.0.borrow_mut().push(value); } pub fn iter(&self) -> SharedArrayIterator where T: Clone { SharedArrayIterator { array: &self, index: 0, } } pub fn clone_content(&self) -> Self where T: Clone { let mut r = Self::new(); for v in self.iter() { r.push(v); } r } } pub struct SharedArrayIterator<'a, T> { array: &'a SharedArray, index: usize, } impl<'a, T> Iterator for SharedArrayIterator<'a, T> where T: Clone { type Item = T; fn next(&mut self) -> Option { let v = self.array.get(self.index); if v.is_some() { self.index += 1; v } else { None } } } impl From<[T; N]> for SharedArray where T: Clone { fn from(value: [T; N]) -> Self { Self::from_iter(value) } } impl From> for SharedArray where T: Clone { fn from(value: Vec) -> Self { Self::from_iter(value) } } impl FromIterator for SharedArray where T: Clone { fn from_iter>(iter: T2) -> Self { let mut r = Self::new(); for v in iter { r.push(v.clone()); } r } } impl Extend for SharedArray { fn extend>(&mut self, iter: T) { for v in iter.into_iter() { self.push(v); } } } pub macro shared_array { ($($element:expr),*) => { SharedArray::from([$($element),*]) }, ($($element:expr),+ ,) => { SharedArray::from([$($element),+]) }, }