fera_array/
rc.rs

1use {Array, DynamicArray, PrefixedArray, PrefixedArrayInfo};
2
3use std::cell::Cell;
4use std::iter::FromIterator;
5use std::ops::{Index, IndexMut};
6
7/// A reference-counted pointer to an array.
8///
9/// It allow access to the elements of the array with one indirection, allow the array to grow
10/// until the specified capacity and has a function `RcArray::make_mut`.
11///
12/// It is different from `Rc<Vec>` and `Rc<[T]>`. In `Rc<Vec>` it is necessary to follow two
13/// indirection to access an element. In `Rc<[T]>` the array cannot grow and the function
14/// `Rc::make_mut` is not applicable.
15///
16/// TODO: write about `mem::size_of`.
17///
18/// # Examples
19///
20/// ```
21/// use fera_array::{Array, RcArray};
22///
23/// let a = RcArray::with_value(0, 5);
24/// // a and b share the inner data, this is a O(1) operation
25/// let mut b = a.clone();
26///
27/// // the inner data in cloned (copy on write)
28/// b[1] = 1;
29/// assert_eq!(0, a[1]);
30/// assert_eq!(1, b[1]);
31///
32/// // the inner data is not shared, so it can be modified without being cloned
33/// b[2] = 2;
34/// ```
35pub struct RcArray<T> {
36    inner: PrefixedArray<Info, T>,
37}
38
39struct Info {
40    count: Cell<usize>,
41    cap: usize,
42    len: usize,
43}
44
45impl PrefixedArrayInfo for Info {
46    #[inline]
47    fn len(&self) -> usize {
48        self.len
49    }
50
51    #[inline]
52    fn capacity(&self) -> usize {
53        self.cap
54    }
55}
56
57impl<T> RcArray<T> {
58    fn new(cap: usize) -> Self {
59        let info = Info {
60            cap: cap,
61            len: 0,
62            count: Cell::new(1),
63        };
64        RcArray { inner: PrefixedArray::allocate(info) }
65    }
66
67    /// Returns a slice containing the entire array.
68    #[inline]
69    pub fn as_slice(&self) -> &[T] {
70        self.inner.as_slice()
71    }
72
73    /// Returns a mutable slice containing the entire array.
74    #[inline]
75    pub fn as_mut_slice(&mut self) -> &mut [T] {
76        self.inner.as_mut_slice()
77    }
78
79    #[inline]
80    fn info(&self) -> &Info {
81        self.inner.info()
82    }
83
84    #[inline]
85    fn info_mut(&mut self) -> &mut Info {
86        self.inner.info_mut()
87    }
88
89    #[inline]
90    fn count(&self) -> &Cell<usize> {
91        &self.info().count
92    }
93
94    #[inline]
95    fn inc(&self) {
96        let v = self.count().get() + 1;
97        self.count().set(v);
98    }
99
100    #[inline]
101    fn dec(&self) {
102        let v = self.count().get() - 1;
103        self.count().set(v);
104    }
105
106    #[inline]
107    fn is_zero(&self) -> bool {
108        self.count().get() == 0
109    }
110
111    #[inline]
112    fn is_unique(&self) -> bool {
113        self.count().get() == 1
114    }
115}
116
117impl<T: Clone> RcArray<T> {
118    /// Makes the array mutable. The inner data is cloned if there is more than one reference to
119    /// it, otherwise the array is already mutable.
120    pub fn make_mut(&mut self) -> &mut [T] {
121        if !self.is_unique() {
122            *self = Self::from_iter(self.as_slice().iter().cloned());
123        }
124        self.as_mut_slice()
125    }
126}
127
128impl<T> Drop for RcArray<T> {
129    fn drop(&mut self) {
130        self.dec();
131        if self.is_zero() {
132            unsafe { self.inner.drop_and_deallocate() }
133        }
134    }
135}
136
137impl<T> Clone for RcArray<T> {
138    #[inline]
139    fn clone(&self) -> Self {
140        self.inc();
141        RcArray { inner: unsafe { self.inner.clone_shallow() } }
142    }
143}
144
145impl<T> FromIterator<T> for RcArray<T> {
146    fn from_iter<I>(iter: I) -> Self
147    where
148        I: IntoIterator<Item = T>,
149    {
150        let iter = iter.into_iter();
151        let mut a = RcArray::new(iter.size_hint().0);
152        for v in iter {
153            unsafe {
154                let len = a.info().len();
155                a.inner.write(len as usize, v);
156                a.info_mut().len = len + 1;
157            }
158            assert!(a.info().len <= a.info().cap);
159        }
160        a
161    }
162}
163
164impl<T> Index<usize> for RcArray<T> {
165    type Output = T;
166
167    #[inline]
168    fn index(&self, index: usize) -> &T {
169        self.as_slice().index(index)
170    }
171}
172
173impl<T: Clone> IndexMut<usize> for RcArray<T> {
174    #[inline]
175    fn index_mut(&mut self, index: usize) -> &mut T {
176        self.make_mut().index_mut(index)
177    }
178}
179
180impl<T: Clone> Array<T> for RcArray<T> {
181    fn with_value(value: T, n: usize) -> Self
182    where
183        T: Clone,
184    {
185        let mut a = RcArray::new(n);
186        a.extend_with_element(value, n);
187        a
188    }
189
190    #[inline]
191    fn len(&self) -> usize {
192        self.info().len
193    }
194
195    #[inline]
196    fn get(&self, index: usize) -> Option<&T> {
197        self.as_slice().get(index)
198    }
199
200    #[inline]
201    fn get_mut(&mut self, index: usize) -> Option<&mut T> {
202        self.make_mut().get_mut(index)
203    }
204
205    #[inline]
206    unsafe fn get_unchecked(&self, index: usize) -> &T {
207        self.as_slice().get_unchecked(index)
208    }
209
210    #[inline]
211    unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
212        self.make_mut().get_unchecked_mut(index)
213    }
214}
215
216impl<T: Clone> DynamicArray<T> for RcArray<T> {
217    fn with_capacity(cap: usize) -> Self {
218        Self::new(cap)
219    }
220
221    #[inline]
222    unsafe fn set_len(&mut self, len: usize) {
223        self.info_mut().len = len;
224    }
225
226    #[inline]
227    fn capacity(&self) -> usize {
228        self.info().cap
229    }
230}
231
232
233#[cfg(test)]
234mod tests {
235    use super::Info;
236    use {ArrayTests, DynamicArrayTests, PrefixedArray, RcArray};
237    use testdrop::TestDrop;
238
239    #[test]
240    fn rc_size() {
241        use std::mem;
242        assert_eq!(
243            mem::size_of::<PrefixedArray<Info, u32>>(),
244            mem::size_of::<RcArray<u32>>()
245        );
246    }
247
248    #[test]
249    fn drop_() {
250        let test = TestDrop::new();
251        let (a, item_a) = test.new_item();
252        let (b, item_b) = test.new_item();
253        let (c, item_c) = test.new_item();
254        let v: RcArray<_> = vec![item_a, item_b, item_c].into_iter().collect();
255
256        let w = v.clone();
257        assert_eq!(2, w.count().get());
258        drop(w);
259
260        test.assert_no_drop(a);
261        test.assert_no_drop(b);
262        test.assert_no_drop(c);
263
264        drop(v);
265
266        test.assert_drop(a);
267        test.assert_drop(b);
268        test.assert_drop(c);
269    }
270
271    struct T;
272
273    impl ArrayTests for T {
274        type A = RcArray<usize>;
275    }
276
277    delegate_tests!{
278        T,
279        basic_0,
280        basic_001k,
281        basic_100k,
282        clone_001k,
283        clone_100k
284    }
285
286    impl DynamicArrayTests for T {}
287
288    delegate_tests!{
289        T,
290        capacity,
291        push_1k,
292        clone_push
293    }
294
295    #[cfg(all(feature = "nightly", test))]
296    mod benchs {
297        use super::T;
298        use test::Bencher;
299        use ArrayBenchs;
300
301        impl ArrayBenchs for T {}
302
303        delegate_benchs!{
304            T,
305            fold_xor_0001k,
306            fold_xor_0010k,
307            fold_xor_0100k,
308            fold_xor_1000k,
309            clone_change_0001k,
310            clone_change_0010k,
311            clone_change_0100k,
312            clone_change_1000k
313        }
314    }
315}