utils/array.rs
1//! Array helpers.
2
3use std::fmt;
4use std::hash::Hash;
5use std::ops::{Deref, DerefMut};
6
7/// A fixed-size array-backed vector.
8///
9/// `ArrayVec` has a fixed-sized `N` long array and a length field to track how many elements are
10/// populated. It is useful for storing a small but variable number of elements without heap
11/// allocation.
12///
13/// The implementation is intentionally simple, and requires [`Copy`] and [`Default`] bounds on some
14/// methods instead of using [`std::mem::MaybeUninit`].
15#[derive(Clone, PartialEq, Eq, Hash)]
16pub struct ArrayVec<T, const N: usize> {
17 len: usize,
18 data: [T; N],
19}
20
21impl<T, const N: usize> ArrayVec<T, N> {
22 /// Creates a new empty `ArrayVec`.
23 ///
24 /// # Examples
25 /// ```
26 /// # use utils::array::ArrayVec;
27 /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
28 /// assert_eq!(vec.len(), 0);
29 /// ```
30 #[inline]
31 #[must_use]
32 pub fn new() -> Self
33 where
34 T: Copy + Default,
35 {
36 Self {
37 len: 0,
38 data: [T::default(); N],
39 }
40 }
41
42 /// Creates a new `ArrayVec`, copying initial data from the provided slice.
43 ///
44 /// # Examples
45 /// ```
46 /// # use utils::array::ArrayVec;
47 /// let mut vec: ArrayVec<i32, 5> = ArrayVec::<i32, 5>::from_slice(&[1, 2, 3]).unwrap();
48 /// assert_eq!(vec.len(), 3);
49 /// assert_eq!(vec.pop(), Some(3));
50 /// assert_eq!(vec.pop(), Some(2));
51 /// assert_eq!(vec.pop(), Some(1));
52 /// assert_eq!(vec.pop(), None);
53 ///
54 /// assert_eq!(ArrayVec::<i32, 5>::from_slice(&[1, 2, 3, 4, 5, 6]), None);
55 /// ```
56 #[inline]
57 #[must_use]
58 pub fn from_slice(slice: &[T]) -> Option<Self>
59 where
60 T: Copy + Default,
61 {
62 if slice.len() > N {
63 None
64 } else {
65 let mut data = [T::default(); N];
66 data[..slice.len()].copy_from_slice(slice);
67 Some(Self {
68 len: slice.len(),
69 data,
70 })
71 }
72 }
73
74 /// Adds an element to the end of the vector.
75 ///
76 /// Returns [`Err`] containing the provided value if the vector is already full.
77 ///
78 /// # Examples
79 /// ```
80 /// # use utils::array::ArrayVec;
81 /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
82 /// assert_eq!(vec.push(1), Ok(()));
83 /// assert_eq!(vec.push(2), Ok(()));
84 /// assert_eq!(vec.push(3), Err(3)); // Vector is full
85 /// ```
86 #[inline]
87 pub fn push(&mut self, value: T) -> Result<(), T> {
88 if self.len < N {
89 self.data[self.len] = value;
90 self.len += 1;
91 Ok(())
92 } else {
93 Err(value)
94 }
95 }
96
97 /// Removes the last element from the vector and returns it, or [`None`] if it is empty.
98 ///
99 /// # Examples
100 /// ```
101 /// # use utils::array::ArrayVec;
102 /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
103 /// vec.push(1).unwrap();
104 /// assert_eq!(vec.pop(), Some(1));
105 /// assert_eq!(vec.pop(), None);
106 /// ```
107 #[inline]
108 pub fn pop(&mut self) -> Option<T>
109 where
110 T: Default,
111 {
112 if self.len > 0 {
113 self.len -= 1;
114 Some(std::mem::take(&mut self.data[self.len]))
115 } else {
116 None
117 }
118 }
119
120 /// Returns a slice of all the populated elements in the vector.
121 ///
122 /// # Examples
123 ///
124 /// ```
125 /// # use utils::array::ArrayVec;
126 /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
127 /// vec.push(1).unwrap();
128 /// vec.push(2).unwrap();
129 /// assert_eq!(vec.as_slice(), &[1, 2]);
130 /// ```
131 #[inline]
132 pub fn as_slice(&self) -> &[T] {
133 #[cfg(feature = "unsafe")]
134 unsafe {
135 std::hint::assert_unchecked(self.len <= N);
136 }
137
138 &self.data[..self.len]
139 }
140
141 /// Returns a mutable slice of all the populated elements in the vector.
142 ///
143 /// # Examples
144 ///
145 /// ```
146 /// # use utils::array::ArrayVec;
147 /// let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
148 /// vec.push(1).unwrap();
149 /// vec.push(2).unwrap();
150 /// let mut slice = vec.as_mut_slice();
151 /// slice[1] = 10;
152 /// assert_eq!(slice, &[1, 10]);
153 /// ```
154 #[inline]
155 pub fn as_mut_slice(&mut self) -> &mut [T] {
156 #[cfg(feature = "unsafe")]
157 unsafe {
158 std::hint::assert_unchecked(self.len <= N);
159 }
160
161 &mut self.data[..self.len]
162 }
163
164 /// Returns the capacity of the vector, which is always `N`.
165 ///
166 /// # Examples
167 /// ```
168 /// # use utils::array::ArrayVec;
169 /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
170 /// assert_eq!(vec.capacity(), 5);
171 /// ```
172 #[inline]
173 pub fn capacity(&self) -> usize {
174 N
175 }
176
177 /// Returns whether the vector is full.
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// # use utils::array::ArrayVec;
183 /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
184 /// assert!(!vec.is_full());
185 /// vec.push(1).unwrap();
186 /// assert!(!vec.is_full());
187 /// vec.push(2).unwrap();
188 /// assert!(vec.is_full());
189 /// ```
190 #[inline]
191 pub fn is_full(&self) -> bool {
192 self.len == N
193 }
194
195 /// Returns the backing array.
196 ///
197 /// Any items after the current length will be set to the default value.
198 ///
199 /// # Examples
200 /// ```
201 /// # use utils::array::ArrayVec;
202 /// let mut vec: ArrayVec<i32, 5> = ArrayVec::new();
203 /// vec.push(1).unwrap();
204 /// vec.push(2).unwrap();
205 /// vec.push(3).unwrap();
206 /// vec.pop().unwrap();
207 /// assert_eq!(vec.into_array(), [1, 2, 0, 0, 0]);
208 /// ```
209 #[inline]
210 pub fn into_array(self) -> [T; N] {
211 self.data
212 }
213}
214
215impl<T, const N: usize> Deref for ArrayVec<T, N> {
216 type Target = [T];
217
218 #[inline]
219 fn deref(&self) -> &Self::Target {
220 self.as_slice()
221 }
222}
223
224impl<T, const N: usize> DerefMut for ArrayVec<T, N> {
225 #[inline]
226 fn deref_mut(&mut self) -> &mut Self::Target {
227 self.as_mut_slice()
228 }
229}
230
231impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
232 type Item = &'a T;
233 type IntoIter = std::slice::Iter<'a, T>;
234
235 #[inline]
236 fn into_iter(self) -> Self::IntoIter {
237 self.iter()
238 }
239}
240
241impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayVec<T, N> {
242 type Item = &'a mut T;
243 type IntoIter = std::slice::IterMut<'a, T>;
244
245 #[inline]
246 fn into_iter(self) -> Self::IntoIter {
247 self.iter_mut()
248 }
249}
250
251impl<T: fmt::Debug, const N: usize> fmt::Debug for ArrayVec<T, N> {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 f.debug_struct("ArrayVec")
254 .field("len", &self.len)
255 .field("cap", &N)
256 .field("data", &self.as_slice())
257 .finish()
258 }
259}
260
261impl<T: Default + Copy, const N: usize> Default for ArrayVec<T, N> {
262 fn default() -> Self {
263 Self::new()
264 }
265}
266
267impl<T, const N: usize> From<[T; N]> for ArrayVec<T, N> {
268 fn from(data: [T; N]) -> Self {
269 ArrayVec { len: N, data }
270 }
271}