smodel/util/
shared_array.rs

1use std::cell::RefCell;
2use std::hash::Hash;
3use std::rc::Rc;
4
5/// A shared mutable array of `T` managed by reference counting.
6///
7/// # Cloning
8/// 
9/// The `Clone` trait implements cloning of the array by reference.
10/// Use the `clone_content()` method to clone the array by content.
11/// 
12/// # Equality
13/// 
14/// The `PartialEq` trait performs reference comparison of two arrays.
15/// 
16/// # Hashing
17/// 
18/// The `Hash` trait performs hashing of the array by reference.
19#[derive(Clone)]
20pub struct SharedArray<T>(Rc<RefCell<Vec<T>>>);
21
22impl<T> PartialEq for SharedArray<T> {
23    fn eq(&self, other: &Self) -> bool {
24        Rc::ptr_eq(&self.0, &other.0)
25    }
26}
27
28impl<T> Eq for SharedArray<T> {}
29
30impl<T> Hash for SharedArray<T> {
31    /// Performs hashing of the array by reference.
32    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
33        self.0.as_ptr().hash(state)
34    }
35}
36
37impl<T> SharedArray<T> {
38    pub fn new() -> Self {
39        Self(Rc::new(RefCell::new(vec![])))
40    }
41
42    pub fn get(&self, index: usize) -> Option<T> where T: Clone {
43        self.0.borrow().get(index).map(|v| v.clone())
44    }
45
46    pub fn set(&mut self, index: usize, value: T) where T: Clone {
47        self.0.borrow_mut()[index] = value.clone();
48    }
49
50    pub fn remove(&mut self, index: usize) {
51        self.0.borrow_mut().remove(index);
52    }
53
54    pub fn includes(&self, value: &T) -> bool where T: PartialEq {
55        self.0.borrow().contains(value)
56    }
57
58    pub fn index_of(&self, value: &T) -> Option<usize> where T: PartialEq {
59        let this = self.0.borrow();
60        for i in 0..self.length() {
61            let value_2 = this.get(i).unwrap();
62            if value == value_2 {
63                return Some(i);
64            }
65        }
66        None
67    }
68
69    pub fn length(&self) -> usize {
70        self.0.borrow().len()
71    }
72
73    pub fn push(&mut self, value: T) {
74        self.0.borrow_mut().push(value);
75    }
76
77    pub fn clear(&mut self) {
78        self.0.borrow_mut().clear();
79    }
80
81    pub fn iter(&self) -> SharedArrayIterator<T> where T: Clone {
82        SharedArrayIterator {
83            array: &self,
84            index: 0,
85        }
86    }
87
88    pub fn clone_content(&self) -> Self where T: Clone {
89        let mut r = Self::new();
90        for v in self.iter() {
91            r.push(v);
92        }
93        r
94    }
95}
96
97pub struct SharedArrayIterator<'a, T> {
98    array: &'a SharedArray<T>,
99    index: usize,
100}
101
102impl<'a, T> Iterator for SharedArrayIterator<'a, T> where T: Clone {
103    type Item = T;
104    fn next(&mut self) -> Option<Self::Item> {
105        let v = self.array.get(self.index);
106        if v.is_some() {
107            self.index += 1;
108            v
109        } else {
110            None
111        }
112    }
113}
114
115impl<const N: usize, T> From<[T; N]> for SharedArray<T> where T: Clone {
116    fn from(value: [T; N]) -> Self {
117        Self::from_iter(value)
118    }
119}
120
121impl<T> From<Vec<T>> for SharedArray<T> where T: Clone {
122    fn from(value: Vec<T>) -> Self {
123        Self::from_iter(value)
124    }
125}
126
127impl<T> FromIterator<T> for SharedArray<T> where T: Clone {
128    fn from_iter<T2: IntoIterator<Item = T>>(iter: T2) -> Self {
129        let mut r = Self::new();
130        for v in iter {
131            r.push(v.clone());
132        }
133        r
134    }
135}
136
137impl<A> Extend<A> for SharedArray<A> {
138    fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
139        for v in iter.into_iter() {
140            self.push(v);
141        }
142    }
143}
144
145#[macro_export]
146macro_rules! shared_array {
147    ($($element:expr),*) => {
148        SharedArray::from([$($element),*])
149    };
150    ($($element:expr),+ ,) => {
151        SharedArray::from([$($element),+])
152    };
153}