heaparray/impls/
generic.rs

1use crate::base::*;
2use crate::prelude::*;
3
4/// Array pointer that also knows what its length is.
5///
6/// In addition to the invariants discussed in
7/// [`BaseArrayPtr`](trait.BaseArrayPtr.html), implementors of this trait need
8/// to maintain the following for any instance created via
9/// `let array = Self::alloc(len)`:
10/// - The method `array.set_len(len)`, and only that method, can change the result
11///   of `array.get_len()`, and after calling `array.set_len(len)`, `array.get_len()`
12///   will return the value that was set
13/// - Any pointer returned by `array.get_ptr(i)` or `array.get_ptr_mut()` where
14///   `i < len` points to aligned, allocated memory
15/// - both `array.get_label()` and `array.get_label_mut()` point to allocated, aligned
16///   memory as well.
17pub unsafe trait SafeArrayPtr<E, L>: BaseArrayPtr<E, L> {
18    /// Set the length of this array
19    fn set_len(&mut self, len: usize);
20
21    /// Get the length of this array
22    fn get_len(&self) -> usize;
23}
24
25/// Safe, generic interface to [`BaseArray`](../base/struct.BaseArray.html).
26///
27/// Uses length information to guarrantee memory safety, and excludes operations
28/// that cannot be performed safely from its API.
29#[repr(transparent)]
30pub struct SafeArray<E, L, P>
31where
32    P: SafeArrayPtr<E, L>,
33{
34    data: BaseArray<E, L, P>,
35}
36
37impl<E, L, P> Container for SafeArray<E, L, P>
38where
39    P: SafeArrayPtr<E, L>,
40{
41    fn len(&self) -> usize {
42        self.data.as_ptr().get_len()
43    }
44}
45
46impl<E, L, P> Drop for SafeArray<E, L, P>
47where
48    P: SafeArrayPtr<E, L>,
49{
50    fn drop(&mut self) {
51        let len = self.len();
52        unsafe { self.data.drop(len) };
53    }
54}
55
56impl<E, L, P> CopyMap<usize, E> for SafeArray<E, L, P>
57where
58    P: SafeArrayPtr<E, L>,
59{
60    fn get(&self, key: usize) -> Option<&E> {
61        if key >= self.len() {
62            None
63        } else {
64            Some(unsafe { &*self.data.get(key) })
65        }
66    }
67    fn get_mut(&mut self, key: usize) -> Option<&mut E> {
68        if key >= self.len() {
69            None
70        } else {
71            Some(unsafe { &mut *self.data.get_mut(key) })
72        }
73    }
74    fn insert(&mut self, key: usize, value: E) -> Option<E> {
75        match self.get_mut(key) {
76            Some(slot) => Some(mem::replace(slot, value)),
77            None => None,
78        }
79    }
80}
81
82impl<E, L, P> LabelledArray<E, L> for SafeArray<E, L, P>
83where
84    P: SafeArrayPtr<E, L>,
85{
86    fn with_label<F>(label: L, len: usize, func: F) -> Self
87    where
88        F: FnMut(&mut L, usize) -> E,
89    {
90        let mut out = Self {
91            data: BaseArray::new(label, len, func),
92        };
93        out.data.as_ptr_mut().set_len(len);
94        out
95    }
96    fn get_label(&self) -> &L {
97        self.data.get_label()
98    }
99    unsafe fn get_unchecked(&self, idx: usize) -> &E {
100        self.data.get(idx)
101    }
102}
103
104impl<E, L, P> LabelledArrayMut<E, L> for SafeArray<E, L, P>
105where
106    P: SafeArrayPtr<E, L>,
107{
108    fn get_label_mut(&mut self) -> &mut L {
109        self.data.get_label_mut()
110    }
111    unsafe fn get_mut_unchecked(&mut self, idx: usize) -> &mut E {
112        self.data.get_mut(idx)
113    }
114}
115
116impl<E, P> MakeArray<E> for SafeArray<E, (), P>
117where
118    P: SafeArrayPtr<E, ()>,
119{
120    fn new<F>(len: usize, mut func: F) -> Self
121    where
122        F: FnMut(usize) -> E,
123    {
124        Self::with_label((), len, |_, idx| func(idx))
125    }
126}
127
128impl<E, L, P> DefaultLabelledArray<E, L> for SafeArray<E, L, P>
129where
130    P: SafeArrayPtr<E, L>,
131    E: Default,
132{
133    fn with_len(label: L, len: usize) -> Self {
134        Self::with_label(label, len, |_, _| E::default())
135    }
136}
137
138impl<E, L, P> Clone for SafeArray<E, L, P>
139where
140    P: SafeArrayPtr<E, L>,
141    E: Clone,
142    L: Clone,
143{
144    fn clone(&self) -> Self {
145        Self::with_label(self.get_label().clone(), self.len(), |_, i| self[i].clone())
146    }
147    fn clone_from(&mut self, source: &Self) {
148        if source.len() != self.len() {
149            *self = source.clone();
150        } else {
151            self.get_label_mut().clone_from(source.get_label());
152            for i in 0..source.len() {
153                self[i].clone_from(&source[i]);
154            }
155        }
156    }
157}
158
159impl<E, L, P> Index<usize> for SafeArray<E, L, P>
160where
161    P: SafeArrayPtr<E, L>,
162{
163    type Output = E;
164    fn index(&self, idx: usize) -> &E {
165        self.get(idx).unwrap()
166    }
167}
168
169impl<E, L, P> IndexMut<usize> for SafeArray<E, L, P>
170where
171    P: SafeArrayPtr<E, L>,
172{
173    fn index_mut(&mut self, idx: usize) -> &mut E {
174        self.get_mut(idx).unwrap()
175    }
176}
177
178impl<E, L, P> IntoIterator for SafeArray<E, L, P>
179where
180    P: SafeArrayPtr<E, L>,
181{
182    type Item = E;
183    type IntoIter = BaseArrayIter<E, L, P>;
184
185    fn into_iter(self) -> Self::IntoIter {
186        let len = self.len();
187        let iter = unsafe { core::ptr::read(&self.data).into_iter(len) };
188        mem::forget(self);
189        iter
190    }
191}
192
193impl<E, L, P> SliceArray<E> for SafeArray<E, L, P>
194where
195    P: SafeArrayPtr<E, L>,
196{
197    fn as_slice(&self) -> &[E] {
198        let len = self.len();
199        unsafe { self.data.as_slice(len) }
200    }
201}
202
203impl<E, L, P> SliceArrayMut<E> for SafeArray<E, L, P>
204where
205    P: SafeArrayPtr<E, L>,
206{
207    fn as_slice_mut(&mut self) -> &mut [E] {
208        let len = self.len();
209        unsafe { self.data.as_slice_mut(len) }
210    }
211}
212
213impl<'a, E, L, P> IntoIterator for &'a SafeArray<E, L, P>
214where
215    P: SafeArrayPtr<E, L>,
216{
217    type Item = &'a E;
218    type IntoIter = core::slice::Iter<'a, E>;
219    fn into_iter(self) -> Self::IntoIter {
220        self.as_slice().into_iter()
221    }
222}
223
224impl<'a, E, L, P> IntoIterator for &'a mut SafeArray<E, L, P>
225where
226    P: SafeArrayPtr<E, L>,
227{
228    type Item = &'a mut E;
229    type IntoIter = core::slice::IterMut<'a, E>;
230    fn into_iter(self) -> Self::IntoIter {
231        self.as_slice_mut().into_iter()
232    }
233}
234
235impl<E, L, P> fmt::Debug for SafeArray<E, L, P>
236where
237    P: SafeArrayPtr<E, L>,
238    E: fmt::Debug,
239    L: fmt::Debug,
240{
241    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
242        formatter
243            .debug_struct("Array")
244            .field("label", &self.get_label())
245            .field("len", &self.len())
246            .field("elements", &self.as_slice())
247            .finish()
248    }
249}
250
251unsafe impl<E, L, P> Send for SafeArray<E, L, P>
252where
253    P: SafeArrayPtr<E, L>,
254    E: Send,
255    L: Send,
256{
257}
258
259unsafe impl<E, L, P> Sync for SafeArray<E, L, P>
260where
261    P: SafeArrayPtr<E, L>,
262    E: Sync,
263    L: Sync,
264{
265}