1use {Array, DynamicArray, PrefixedArray, PrefixedArrayInfo};
2
3use std::cell::Cell;
4use std::iter::FromIterator;
5use std::ops::{Index, IndexMut};
6
7pub 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 #[inline]
69 pub fn as_slice(&self) -> &[T] {
70 self.inner.as_slice()
71 }
72
73 #[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 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}