slicevec/
lib.rs

1//! Provides a vector that uses an external slice for storage.
2
3#![no_std]
4
5use core::borrow::{Borrow, BorrowMut};
6use core::ops::{Deref, DerefMut};
7use core::mem::{swap, replace};
8use core::cmp;
9
10/// A Vector using a slice for backing storage (passed in at creation time).
11///
12/// Changes to the vector are visible in the backing storage after the `SliceVec` is dropped.
13///
14/// A `SliceVec` can be dereferenced to a truncated slice containing all elements in the `SliceVec`.
15/// The returned slice is different from the backing slice in that it only contains the first `n`
16/// values, where `n` is the current length of the `SliceVec`. The backing slice may contain unused
17/// "dummy" elements after the last element.
18///
19/// This is essentially a less ergonomic but more flexible version of the `arrayvec` crate's
20/// `ArrayVec` type: You have to crate the backing storage yourself, but `SliceVec` works with
21/// arrays of *any* length (unlike `ArrayVec`, which works with a fixed set of lengths, since Rust
22/// doesn't (yet) have integer generics).
23#[derive(Debug)]
24pub struct SliceVec<'a, T: 'a> {
25    storage: &'a mut [T],
26    len: usize,
27}
28
29impl<'a, T> SliceVec<'a, T> {
30    /// Create a new `SliceVec`, using the given slice as backing storage for elements.
31    ///
32    /// The capacity of the vector equals the length of the slice, you have to make sure that the
33    /// slice is large enough for all elements.
34    pub fn new(storage: &'a mut [T]) -> Self {
35        SliceVec {
36            storage: storage,
37            len: 0,
38        }
39    }
40
41    /// Returns the maximum number of elements that can be stored in this vector. This is equal to
42    /// the length of the backing storage passed at creation of this `SliceVec`.
43    pub fn capacity(&self) -> usize {
44        self.storage.len()
45    }
46
47    /// Returns the number of elements stored in this `SliceVec`.
48    pub fn len(&self) -> usize {
49        self.len
50    }
51
52    /// Returns `true` if the length of this vector is 0, `false` otherwise.
53    pub fn is_empty(&self) -> bool {
54        self.len == 0
55    }
56
57    /// Returns `true` if the backing slice is completely filled.
58    ///
59    /// When this is the case, all operations that insert additional elements into the `SliceVec`
60    /// will fail.
61    pub fn is_full(&self) -> bool {
62        self.len == self.storage.len()
63    }
64
65    /// Tries to append an element to the end of this vector.
66    ///
67    /// If the backing storage is already full, returns `Err(elem)`.
68    pub fn push(&mut self, elem: T) -> Result<(), T> {
69        if self.len < self.capacity() {
70            self.storage[self.len] = elem;
71            self.len += 1;
72            Ok(())
73        } else {
74            Err(elem)
75        }
76    }
77
78    /// Removes and returns the last elements stored inside the vector, replacing it with `elem`.
79    ///
80    /// If the vector is empty, returns `None` and drops `elem`.
81    pub fn pop_and_replace(&mut self, elem: T) -> Option<T> {
82        // FIXME should this return a `Result<T, T>` instead?
83        if self.len > 0 {
84            self.len -= 1;
85            let elem = replace(&mut self.storage[self.len], elem);
86            Some(elem)
87        } else {
88            None
89        }
90    }
91
92    /// Shortens the vector to `len` elements.
93    ///
94    /// Excess elements are not dropped. They are kept in the backing slice.
95    pub fn truncate(&mut self, len: usize) {
96        self.len = cmp::min(self.len, len);
97    }
98
99    /// Clears the vector, removing all elements.
100    ///
101    /// Equivalent to `.truncate(0)`.
102    pub fn clear(&mut self) {
103        self.truncate(0);
104    }
105
106    /// Extract a slice containing the entire vector.
107    ///
108    /// The returned slice will be shorter than the backing slice if the vector hasn't yet exceeded
109    /// its capacity.
110    pub fn as_slice(&self) -> &[T] {
111        &self.storage[..self.len]
112    }
113
114    /// Extract a mutable slice containing the entire vector.
115    ///
116    /// The returned slice will be shorter than the backing slice if the vector hasn't yet exceeded
117    /// its capacity.
118    pub fn as_mut_slice(&mut self) -> &mut [T] {
119        &mut self.storage[..self.len]
120    }
121}
122
123impl<'a, T: 'a + Default> SliceVec<'a, T> {
124    /// Removes and returns the last element in this vector.
125    ///
126    /// Returns `None` if the vector is empty.
127    ///
128    /// This operation is restricted to element types that implement `Default`, since the element's
129    /// spot in the backing storage is replaced by a default value.
130    pub fn pop(&mut self) -> Option<T> {
131        if self.len > 0 {
132            self.len -= 1;
133            let elem = replace(&mut self.storage[self.len], T::default());
134            Some(elem)
135        } else {
136            None
137        }
138    }
139
140    /// Removes and returns the element at `index` and replaces it with the last element.
141    ///
142    /// The last element's place in the backing slice is replaced by `T`'s default value.
143    ///
144    /// Panics if `index` is out of bounds.
145    pub fn swap_remove(&mut self, index: usize) -> T {
146        let len = self.len();
147        self.as_mut_slice().swap(index, len - 1);
148        // the unwrap should never fail since we already touched the slice, causing a bounds check
149        self.pop().expect("swap_remove failed pop")
150    }
151
152    /// Removes and returns the element at `index` and shifts down all elements after it.
153    ///
154    /// Unlike `swap_remove`, this preserves the ordering of the vector, but is `O(n)` instead of
155    /// `O(1)`.
156    pub fn remove(&mut self, index: usize) -> T {
157        // Just because I'm too lazy to reason about `unsafe` code, let's try something else...
158        assert!(index < self.len);
159
160        // Swap all elements downwards until we arrive at `index`
161        let mut replacement = T::default();
162        for i in (index..self.len).rev() {
163            swap(&mut self.storage[i], &mut replacement);
164        }
165        self.len -= 1;
166
167        replacement
168    }
169}
170
171impl<'a, T> Deref for SliceVec<'a, T> {
172    type Target = [T];
173
174    fn deref(&self) -> &[T] {
175        self.as_slice()
176    }
177}
178
179impl<'a, T> DerefMut for SliceVec<'a, T> {
180    fn deref_mut(&mut self) -> &mut [T] {
181        self.as_mut_slice()
182    }
183}
184
185// Forward useful `[T]` impls so `SliceVec` is useful in generic contexts.
186// TODO: There are a lot more we can forward. Is this the right way? `Vec<T>` also forwards dozens.
187
188impl<'a, T> AsRef<[T]> for SliceVec<'a, T> {
189    fn as_ref(&self) -> &[T] {
190        self.as_slice()
191    }
192}
193
194impl<'a, T> AsMut<[T]> for SliceVec<'a, T> {
195    fn as_mut(&mut self) -> &mut [T] {
196        self.as_mut_slice()
197    }
198}
199
200impl<'a, T> Borrow<[T]> for SliceVec<'a, T> {
201    fn borrow(&self) -> &[T] {
202        self.as_slice()
203    }
204}
205
206impl<'a, T> BorrowMut<[T]> for SliceVec<'a, T> {
207    fn borrow_mut(&mut self) -> &mut [T] {
208        self.as_mut_slice()
209    }
210}
211
212#[cfg(test)]
213mod tests {
214    use super::*;
215
216    #[test]
217    fn basic() {
218        const CAP: usize = 1;
219        let mut storage = [0; CAP];
220
221        {
222            let mut s = SliceVec::new(&mut storage);
223            assert!(s.is_empty());
224            assert_eq!(s.len(), 0);
225            assert_eq!(s.capacity(), CAP);
226
227            assert_eq!(s.push(123), Ok(()));
228            assert_eq!(s.len(), 1);
229            assert!(!s.is_empty());
230            assert_eq!(s.as_slice(), &[123]);
231            assert_eq!(s.push(42), Err(42));
232            assert!(!s.is_empty());
233            assert_eq!(s.as_slice(), &[123]);
234            assert_eq!(s.pop(), Some(123));
235            assert_eq!(s.len(), 0);
236            assert!(s.is_empty());
237            assert_eq!(s.as_slice(), &[]);
238            assert_eq!(&*s, &[]);
239        }
240    }
241
242    #[test]
243    fn swap_remove() {
244        let mut storage = [0; 5];
245        let mut v = SliceVec::new(&mut storage);
246        v.push(0).unwrap();
247        v.push(1).unwrap();
248        v.push(2).unwrap();
249        v.push(3).unwrap();
250        assert_eq!(v.as_slice(), &[0, 1, 2, 3]);
251        assert_eq!(v.swap_remove(0), 0);
252        assert_eq!(v.as_slice(), &[3, 1, 2]);
253        assert_eq!(v.swap_remove(2), 2);
254        assert_eq!(v.as_slice(), &[3, 1]);
255        v.push(100).unwrap();
256        v.push(101).unwrap();
257        assert_eq!(v.as_slice(), &[3, 1, 100, 101]);
258        assert_eq!(v.swap_remove(2), 100);
259        assert_eq!(v.as_slice(), &[3, 1, 101]);
260        v.push(102).unwrap();
261        assert_eq!(v.as_slice(), &[3, 1, 101, 102]);
262        assert_eq!(v.swap_remove(1), 1);
263        assert_eq!(v.as_slice(), &[3, 102, 101]);
264    }
265
266    #[test]
267    #[should_panic]
268    fn swap_remove_empty() {
269        let mut storage = [0; 5];
270        let mut v = SliceVec::new(&mut storage);
271        v.push(7).unwrap();
272        v.clear();
273        assert_eq!(v.as_slice(), &[]);
274        assert!(v.is_empty());
275
276        v.swap_remove(0);
277    }
278
279    #[test]
280    #[should_panic]
281    fn swap_remove_out_of_bounds() {
282        let mut storage = [0; 5];
283        let mut v = SliceVec::new(&mut storage);
284        v.push(0).unwrap();
285        v.push(1).unwrap();
286        v.push(2).unwrap();
287        v.push(3).unwrap();
288        assert_eq!(v.as_slice(), &[0, 1, 2, 3]);
289
290        v.swap_remove(4);
291    }
292
293    #[test]
294    fn remove() {
295        let mut storage = [0; 5];
296        let mut v = SliceVec::new(&mut storage);
297        v.push(0).unwrap();
298        v.push(1).unwrap();
299        v.push(2).unwrap();
300        v.push(3).unwrap();
301        assert_eq!(v.remove(0), 0);
302        assert_eq!(v.as_slice(), &[1, 2, 3]);
303        assert_eq!(v.remove(2), 3);
304        assert_eq!(v.as_slice(), &[1, 2]);
305        v.push(3).unwrap();
306        v.push(4).unwrap();
307        v.push(5).unwrap();
308        assert_eq!(v.as_slice(), &[1, 2, 3, 4, 5]);
309        assert_eq!(v.remove(1), 2);
310        assert_eq!(v.as_slice(), &[1, 3, 4, 5]);
311    }
312
313    #[test]
314    #[should_panic]
315    fn remove_empty() {
316        let mut storage = [0; 5];
317        let mut v = SliceVec::new(&mut storage);
318        v.push(7).unwrap();
319        v.clear();
320        assert_eq!(v.as_slice(), &[]);
321        assert!(v.is_empty());
322
323        v.remove(0);
324    }
325
326    #[test]
327    #[should_panic]
328    fn remove_out_of_bounds() {
329        let mut storage = [0; 5];
330        let mut v = SliceVec::new(&mut storage);
331        v.push(0).unwrap();
332        v.push(1).unwrap();
333        v.push(2).unwrap();
334        v.push(3).unwrap();
335        assert_eq!(v.as_slice(), &[0, 1, 2, 3]);
336
337        v.remove(4);
338    }
339
340    #[test]
341    fn is_full() {
342        let mut storage = [0; 3];
343        let mut v = SliceVec::new(&mut storage);
344        assert!(!v.is_full());
345        v.push(0).unwrap();
346        assert!(!v.is_full());
347        v.push(1).unwrap();
348        assert!(!v.is_full());
349        v.push(2).unwrap();
350        assert!(v.is_full());
351        v.push(3).unwrap_err();
352    }
353}