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 a reference to the backing array.
165 ///
166 /// Any items after the current length will be set to the default value.
167 ///
168 /// # Examples
169 /// ```
170 /// # use utils::array::ArrayVec;
171 /// let mut vec: ArrayVec<i32, 8> = ArrayVec::new();
172 /// vec.push(10).unwrap();
173 /// vec.push(6).unwrap();
174 /// vec.pop().unwrap();
175 /// assert_eq!(vec.into_array(), [10, 0, 0, 0, 0, 0, 0, 0]);
176 /// ```
177 #[inline]
178 pub fn as_array(&self) -> &[T; N] {
179 &self.data
180 }
181
182 /// Returns the capacity of the vector, which is always `N`.
183 ///
184 /// # Examples
185 /// ```
186 /// # use utils::array::ArrayVec;
187 /// let vec: ArrayVec<i32, 5> = ArrayVec::new();
188 /// assert_eq!(vec.capacity(), 5);
189 /// ```
190 #[inline]
191 pub fn capacity(&self) -> usize {
192 N
193 }
194
195 /// Returns whether the vector is full.
196 ///
197 /// # Examples
198 ///
199 /// ```
200 /// # use utils::array::ArrayVec;
201 /// let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
202 /// assert!(!vec.is_full());
203 /// vec.push(1).unwrap();
204 /// assert!(!vec.is_full());
205 /// vec.push(2).unwrap();
206 /// assert!(vec.is_full());
207 /// ```
208 #[inline]
209 pub fn is_full(&self) -> bool {
210 self.len == N
211 }
212
213 /// Returns the backing array.
214 ///
215 /// Any items after the current length will be set to the default value.
216 ///
217 /// # Examples
218 /// ```
219 /// # use utils::array::ArrayVec;
220 /// let mut vec: ArrayVec<i32, 5> = ArrayVec::new();
221 /// vec.push(1).unwrap();
222 /// vec.push(2).unwrap();
223 /// vec.push(3).unwrap();
224 /// vec.pop().unwrap();
225 /// assert_eq!(vec.into_array(), [1, 2, 0, 0, 0]);
226 /// ```
227 #[inline]
228 pub fn into_array(self) -> [T; N] {
229 self.data
230 }
231}
232
233impl<T, const N: usize> Deref for ArrayVec<T, N> {
234 type Target = [T];
235
236 #[inline]
237 fn deref(&self) -> &Self::Target {
238 self.as_slice()
239 }
240}
241
242impl<T, const N: usize> DerefMut for ArrayVec<T, N> {
243 #[inline]
244 fn deref_mut(&mut self) -> &mut Self::Target {
245 self.as_mut_slice()
246 }
247}
248
249impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
250 type Item = &'a T;
251 type IntoIter = std::slice::Iter<'a, T>;
252
253 #[inline]
254 fn into_iter(self) -> Self::IntoIter {
255 self.iter()
256 }
257}
258
259impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayVec<T, N> {
260 type Item = &'a mut T;
261 type IntoIter = std::slice::IterMut<'a, T>;
262
263 #[inline]
264 fn into_iter(self) -> Self::IntoIter {
265 self.iter_mut()
266 }
267}
268
269impl<T: fmt::Debug, const N: usize> fmt::Debug for ArrayVec<T, N> {
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 f.debug_struct("ArrayVec")
272 .field("len", &self.len)
273 .field("cap", &N)
274 .field("data", &self.as_slice())
275 .finish()
276 }
277}
278
279impl<T: Default + Copy, const N: usize> Default for ArrayVec<T, N> {
280 fn default() -> Self {
281 Self::new()
282 }
283}
284
285impl<T, const N: usize> From<[T; N]> for ArrayVec<T, N> {
286 fn from(data: [T; N]) -> Self {
287 ArrayVec { len: N, data }
288 }
289}