planck_noalloc/vec.rs
1//! Fixed-capacity vector implementation backed by a stack-allocated array.
2//!
3//! This module provides [`ArrayVec`], a vector-like data structure with a compile-time
4//! fixed capacity. Unlike `Vec` from the standard library, `ArrayVec` stores its elements
5//! inline in a fixed-size array on the stack, avoiding heap allocation entirely.
6//!
7//! # Features
8//!
9//! - Zero heap allocations
10//! - Compile-time fixed capacity
11//! - API similar to standard `Vec`
12//! - Works in `no_std` environments
13//! - Safe handling of uninitialized memory
14//!
15//! # Capacity Management
16//!
17//! The capacity is specified as a const generic parameter and cannot be changed at runtime.
18//! Attempting to push beyond capacity will either return an error ([`ArrayVec::try_push`])
19//! or panic ([`ArrayVec::push`]).
20//!
21//! # Performance
22//!
23//! - Push/pop operations: O(1)
24//! - Indexing: O(1)
25//! - Better cache locality than heap-allocated vectors
26//! - No allocator overhead
27//!
28//! # Examples
29//!
30//! ```
31//! use planck_noalloc::vec::ArrayVec;
32//!
33//! let mut vec = ArrayVec::<i32, 10>::new();
34//!
35//! // Push elements
36//! vec.push(1);
37//! vec.push(2);
38//! vec.push(3);
39//!
40//! // Access elements
41//! assert_eq!(vec[0], 1);
42//! assert_eq!(vec.len(), 3);
43//!
44//! // Iterate
45//! for value in vec.iter() {
46//! println!("{}", value);
47//! }
48//!
49//! // Get as slice
50//! let slice = vec.as_slice();
51//! assert_eq!(slice, &[1, 2, 3]);
52//! ```
53
54use core::mem::MaybeUninit;
55
56/// A fixed-size array, which has vector-like operations.
57///
58/// `ArrayVec` provides a vector-like interface with a compile-time fixed capacity `N`.
59/// Elements are stored in a stack-allocated array, making it suitable for `no_std`
60/// environments and situations where heap allocation is not available or desirable.
61///
62/// # Type Parameters
63///
64/// - `T`: The type of elements stored in the vector
65/// - `N`: The maximum number of elements (capacity)
66///
67/// # Examples
68///
69/// ```
70/// use planck_noalloc::vec::ArrayVec;
71///
72/// // Create a vector with capacity 4
73/// let mut vec = ArrayVec::<String, 4>::new();
74/// vec.push(String::from("hello"));
75/// vec.push(String::from("world"));
76///
77/// assert_eq!(vec.len(), 2);
78/// ```
79#[derive(Debug)]
80pub struct ArrayVec<T, const N: usize> {
81 data: [MaybeUninit<T>; N],
82 len: usize,
83}
84
85/// Errors that can occur when operating on an [`ArrayVec`].
86#[derive(Debug, Clone)]
87pub enum ArrayVecError {
88 /// The operation would exceed the fixed capacity of the `ArrayVec`.
89 CapacityOverflow,
90}
91
92impl core::fmt::Display for ArrayVecError {
93 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
94 match self {
95 Self::CapacityOverflow => f.write_str("capacity overflow"),
96 }
97 }
98}
99
100impl core::error::Error for ArrayVecError {}
101
102impl<T, const N: usize> Default for ArrayVec<T, N> {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108impl<T, const N: usize> ArrayVec<T, N> {
109 /// Creates a new `ArrayVec` with no elements.
110 ///
111 /// # Examples
112 ///
113 /// ```
114 /// use planck_noalloc::vec::ArrayVec;
115 ///
116 /// let mut vec = ArrayVec::<u8, 4>::new();
117 /// assert_eq!(vec.len(), 0);
118 /// assert!(vec.is_empty());
119 /// ```
120 #[must_use]
121 pub const fn new() -> Self {
122 Self {
123 data: [const { MaybeUninit::uninit() }; N],
124 len: 0,
125 }
126 }
127
128 /// Tries to push a value into the `ArrayVec`.
129 ///
130 /// # Errors
131 ///
132 /// Returns an error if the `ArrayVec` is full.
133 ///
134 /// # Examples
135 ///
136 /// ```
137 /// use planck_noalloc::vec::ArrayVec;
138 ///
139 /// let mut vec = ArrayVec::<u8, 1>::new();
140 /// assert!(vec.try_push(1).is_ok());
141 /// assert_eq!(vec.len(), 1);
142 /// assert!(vec.try_push(2).is_err());
143 /// ```
144 pub fn try_push(&mut self, value: T) -> Result<(), ArrayVecError> {
145 if self.len == N {
146 return Err(ArrayVecError::CapacityOverflow);
147 }
148 self.data[self.len].write(value);
149 self.len += 1;
150 Ok(())
151 }
152
153 /// Pushes a value into the `ArrayVec`.
154 ///
155 /// # Panics
156 ///
157 /// Panics if the `ArrayVec` is full.
158 pub fn push(&mut self, value: T) {
159 self.try_push(value).expect("ArrayVec: ran out of capacity");
160 }
161
162 /// Removes and returns the last element, or `None` if empty.
163 #[must_use]
164 pub fn pop(&mut self) -> Option<T> {
165 if self.len == 0 {
166 return None;
167 }
168 self.len -= 1;
169 // SAFETY: The element at `self.len` was initialized by a previous push.
170 Some(unsafe { self.data[self.len].assume_init_read() })
171 }
172
173 /// Removes all elements.
174 pub fn clear(&mut self) {
175 while self.pop().is_some() {}
176 }
177
178 /// Removes the element at `index` by swapping it with the last element.
179 ///
180 /// # Panics
181 ///
182 /// Panics if `index >= len`.
183 pub fn swap_remove(&mut self, index: usize) -> T {
184 assert!(index < self.len, "index out of bounds");
185 self.len -= 1;
186 // Swap the target with the last element, then read the target.
187 self.data.swap(index, self.len);
188 // SAFETY: The element at `self.len` (formerly at `index`) was initialized.
189 unsafe { self.data[self.len].assume_init_read() }
190 }
191
192 /// Returns the number of elements in the `ArrayVec`.
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// use planck_noalloc::vec::ArrayVec;
198 ///
199 /// let mut vec = ArrayVec::<u8, 4>::new();
200 /// assert_eq!(vec.len(), 0);
201 /// vec.push(1);
202 /// assert_eq!(vec.len(), 1);
203 /// vec.push(2);
204 /// assert_eq!(vec.len(), 2);
205 /// ```
206 #[must_use]
207 pub fn len(&self) -> usize {
208 self.len
209 }
210
211 /// Returns true if the `ArrayVec` is empty.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use planck_noalloc::vec::ArrayVec;
217 ///
218 /// let mut vec = ArrayVec::<u8, 4>::new();
219 /// assert!(vec.is_empty());
220 /// vec.push(1);
221 /// assert!(!vec.is_empty());
222 /// ```
223 #[must_use]
224 pub fn is_empty(&self) -> bool {
225 self.len == 0
226 }
227
228 /// Returns a slice of all the elements in the `ArrayVec`.
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// use planck_noalloc::vec::ArrayVec;
234 ///
235 /// let mut vec = ArrayVec::<u8, 4>::new();
236 /// vec.push(1);
237 /// vec.push(2);
238 /// vec.push(3);
239 /// vec.push(4);
240 ///
241 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
242 /// ```
243 #[must_use]
244 pub fn as_slice(&self) -> &[T] {
245 // SAFETY: Elements 0..self.len are initialized by the push invariant,
246 // and the pointer from `self.data` is valid for `self.len` elements.
247 unsafe { core::slice::from_raw_parts(self.data.as_ptr().cast::<T>(), self.len) }
248 }
249
250 /// Returns a mutable slice of all the elements in the `ArrayVec`.
251 ///
252 /// # Examples
253 ///
254 /// ```
255 /// use planck_noalloc::vec::ArrayVec;
256 ///
257 /// let mut vec = ArrayVec::<u8, 4>::new();
258 /// vec.push(1);
259 /// vec.push(2);
260 /// vec.push(3);
261 /// vec.push(4);
262 ///
263 /// assert_eq!(vec.as_mut_slice(), &mut [1, 2, 3, 4]);
264 /// ```
265 #[must_use]
266 pub fn as_mut_slice(&mut self) -> &mut [T] {
267 // SAFETY: Elements 0..self.len are initialized by the push invariant,
268 // and the mutable pointer from `self.data` is valid for `self.len` elements.
269 unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr().cast::<T>(), self.len) }
270 }
271
272 /// Returns an iterator over the elements of the `ArrayVec`.
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// use planck_noalloc::vec::ArrayVec;
278 ///
279 /// let mut vec = ArrayVec::<u8, 4>::new();
280 /// vec.push(1);
281 /// vec.push(2);
282 /// vec.push(3);
283 /// vec.push(4);
284 ///
285 /// for i in vec.iter() {
286 /// assert!(*i == 1 || *i == 2 || *i == 3 || *i == 4);
287 /// // do something
288 /// }
289 /// ```
290 pub fn iter(&self) -> core::slice::Iter<'_, T> {
291 self.as_slice().iter()
292 }
293
294 /// Returns a mutable iterator over the elements of the `ArrayVec`.
295 ///
296 /// # Examples
297 ///
298 /// ```
299 /// use planck_noalloc::vec::ArrayVec;
300 ///
301 /// let mut vec = ArrayVec::<u8, 4>::new();
302 /// vec.push(1);
303 /// vec.push(2);
304 /// vec.push(3);
305 /// vec.push(4);
306 ///
307 /// for i in vec.iter_mut() {
308 /// *i += 1;
309 /// // do something
310 /// }
311 /// ```
312 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
313 self.as_mut_slice().iter_mut()
314 }
315
316 /// Reverses the order of the elements in the `ArrayVec`.
317 ///
318 /// # Examples
319 ///
320 /// ```
321 /// use planck_noalloc::vec::ArrayVec;
322 ///
323 /// let mut vec = ArrayVec::<u8, 4>::new();
324 /// vec.push(1);
325 /// vec.push(2);
326 /// vec.push(3);
327 /// vec.push(4);
328 ///
329 /// vec.reverse();
330 ///
331 /// assert_eq!(vec.as_slice(), &[4, 3, 2, 1]);
332 /// ```
333 pub fn reverse(&mut self) {
334 let len = self.len;
335 for i in 0..len / 2 {
336 let j = len - i - 1;
337 self.data.swap(i, j);
338 }
339 }
340
341 /// Inserts `value` at `index`, shifting all elements after it to the right.
342 ///
343 /// # Panics
344 ///
345 /// Panics if `index > len` or if the `ArrayVec` is full.
346 pub fn insert(&mut self, index: usize, value: T) {
347 assert!(index <= self.len, "index out of bounds");
348 assert!(self.len < N, "ArrayVec: ran out of capacity");
349 // SAFETY: We shift elements [index..len] one position right.
350 // All elements in that range are initialized. After the shift,
351 // index `self.len` is moved from `self.len - 1` (or is the gap
352 // at `index`). We then write `value` into the gap at `index`.
353 unsafe {
354 let ptr = self.data.as_mut_ptr().add(index);
355 core::ptr::copy(ptr, ptr.add(1), self.len - index);
356 ptr.cast::<T>().write(value);
357 }
358 self.len += 1;
359 }
360
361 /// Removes and returns the element at `index`, shifting all elements
362 /// after it to the left. Preserves ordering.
363 ///
364 /// # Panics
365 ///
366 /// Panics if `index >= len`.
367 pub fn remove(&mut self, index: usize) -> T {
368 assert!(index < self.len, "index out of bounds");
369 // SAFETY: The element at `index` is initialized. We read it out,
370 // then shift elements [index+1..len] one position left.
371 unsafe {
372 let ptr = self.data.as_mut_ptr().add(index);
373 let value = ptr.cast::<T>().read();
374 core::ptr::copy(ptr.add(1), ptr, self.len - index - 1);
375 self.len -= 1;
376 value
377 }
378 }
379
380 /// Returns the last element, or `None` if empty.
381 #[must_use]
382 pub fn last(&self) -> Option<&T> {
383 if self.len == 0 {
384 None
385 } else {
386 Some(&self[self.len - 1])
387 }
388 }
389
390 /// Returns true if the `ArrayVec` is at capacity.
391 #[must_use]
392 pub fn is_full(&self) -> bool {
393 self.len == N
394 }
395
396 /// Returns a pointer to the underlying data.
397 #[must_use]
398 pub fn as_ptr(&self) -> *const T {
399 self.data.as_ptr().cast::<T>()
400 }
401
402 /// Returns a mutable pointer to the underlying data.
403 #[must_use]
404 pub fn as_mut_ptr(&mut self) -> *mut T {
405 self.data.as_mut_ptr().cast::<T>()
406 }
407}
408
409impl<T, const U: usize> ArrayVec<T, U>
410where
411 T: Copy + PartialEq,
412{
413 /// Returns true if the `ArrayVec` contains the given value.
414 ///
415 /// # Examples
416 /// ```
417 /// use planck_noalloc::vec::ArrayVec;
418 ///
419 /// let mut vec = ArrayVec::<u8, 4>::new();
420 /// vec.push(1);
421 /// vec.push(2);
422 /// vec.push(3);
423 /// vec.push(4);
424 ///
425 /// assert!(vec.contains(&1));
426 /// assert!(!vec.contains(&5));
427 /// ```
428 #[must_use]
429 pub fn contains(&self, value: &T) -> bool {
430 self.iter().any(|x| x == value)
431 }
432}
433
434impl<T, const U: usize> ArrayVec<T, U>
435where
436 T: Copy + Ord,
437{
438 /// Sorts the `ArrayVec` in place.
439 /// The sort is not stable, meaning that the relative order of elements that are equal is not
440 /// preserved.
441 ///
442 /// # Examples
443 ///
444 /// ```
445 /// use planck_noalloc::vec::ArrayVec;
446 ///
447 /// let mut vec = ArrayVec::<u8, 4>::new();
448 /// vec.push(1);
449 /// vec.push(2);
450 /// vec.push(3);
451 /// vec.push(4);
452 ///
453 /// vec.sort_unstable();
454 ///
455 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
456 /// ```
457 pub fn sort_unstable(&mut self) {
458 self.as_mut_slice().sort_unstable();
459 }
460}
461
462impl<T, const N: usize> core::ops::Index<usize> for ArrayVec<T, N> {
463 type Output = T;
464
465 /// Returns a reference to the element at the given index.
466 ///
467 /// # Panics
468 ///
469 /// Panics if the index is out of bounds.
470 ///
471 /// # Examples
472 ///
473 /// ```
474 /// use planck_noalloc::vec::ArrayVec;
475 ///
476 /// let mut vec = ArrayVec::<u8, 4>::new();
477 /// vec.push(1);
478 /// vec.push(2);
479 /// vec.push(3);
480 /// vec.push(4);
481 ///
482 /// assert_eq!(vec[0], 1);
483 /// assert_eq!(vec[1], 2);
484 /// assert_eq!(vec[2], 3);
485 /// assert_eq!(vec[3], 4);
486 /// ```
487 fn index(&self, index: usize) -> &Self::Output {
488 assert!(index < self.len, "index out of bounds");
489 // SAFETY: Elements 0..self.len are initialized by the push invariant.
490 unsafe { self.data[index].assume_init_ref() }
491 }
492}
493
494impl<T, const N: usize> core::ops::IndexMut<usize> for ArrayVec<T, N> {
495 /// Returns a mutable reference to the element at the given index.
496 ///
497 /// # Panics
498 ///
499 /// Panics if the index is out of bounds.
500 ///
501 /// # Examples
502 ///
503 /// ```
504 /// use planck_noalloc::vec::ArrayVec;
505 ///
506 /// let mut vec = ArrayVec::<u8, 4>::new();
507 /// vec.push(1);
508 /// vec.push(2);
509 /// vec.push(3);
510 /// vec.push(4);
511 ///
512 /// assert_eq!(vec[0], 1);
513 /// assert_eq!(vec[1], 2);
514 /// assert_eq!(vec[2], 3);
515 /// assert_eq!(vec[3], 4);
516 ///
517 /// vec[0] = 5;
518 /// assert_eq!(vec[0], 5);
519 /// ```
520 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
521 assert!(index < self.len, "index out of bounds");
522 // SAFETY: Elements 0..self.len are initialized by the push invariant.
523 unsafe { self.data[index].assume_init_mut() }
524 }
525}
526
527impl<T, const N: usize> Drop for ArrayVec<T, N> {
528 fn drop(&mut self) {
529 // Drop all initialized elements.
530 for i in 0..self.len {
531 // SAFETY: Elements at indices 0..len are guaranteed to be initialized
532 // by the ArrayVec invariant (push initializes, len tracks count).
533 unsafe {
534 self.data[i].assume_init_drop();
535 }
536 }
537 }
538}
539
540impl<'a, T, const N: usize> IntoIterator for &'a ArrayVec<T, N> {
541 type Item = &'a T;
542 type IntoIter = core::slice::Iter<'a, T>;
543
544 fn into_iter(self) -> Self::IntoIter {
545 self.iter()
546 }
547}
548
549impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayVec<T, N> {
550 type Item = &'a mut T;
551 type IntoIter = core::slice::IterMut<'a, T>;
552
553 fn into_iter(self) -> Self::IntoIter {
554 self.iter_mut()
555 }
556}
557
558#[cfg(all(test, feature = "std"))]
559mod tests {
560 extern crate std;
561 use std::vec;
562 use std::vec::Vec;
563
564 use super::*;
565
566 #[test]
567 fn new_is_empty() {
568 let vec = ArrayVec::<i32, 4>::new();
569 assert!(vec.is_empty());
570 assert_eq!(vec.len(), 0);
571 }
572
573 #[test]
574 fn push_and_len() {
575 let mut vec = ArrayVec::<i32, 4>::new();
576 vec.push(10);
577 assert_eq!(vec.len(), 1);
578 vec.push(20);
579 assert_eq!(vec.len(), 2);
580 }
581
582 #[test]
583 fn push_to_capacity() {
584 let mut vec = ArrayVec::<i32, 3>::new();
585 vec.push(1);
586 vec.push(2);
587 vec.push(3);
588 assert_eq!(vec.len(), 3);
589 }
590
591 #[test]
592 #[should_panic(expected = "ran out of capacity")]
593 fn push_overflow_panics() {
594 let mut vec = ArrayVec::<i32, 2>::new();
595 vec.push(1);
596 vec.push(2);
597 vec.push(3); // should panic
598 }
599
600 #[test]
601 fn try_push_ok_and_err() {
602 let mut vec = ArrayVec::<i32, 2>::new();
603 assert!(vec.try_push(1).is_ok());
604 assert!(vec.try_push(2).is_ok());
605 assert!(vec.try_push(3).is_err());
606 }
607
608 #[test]
609 fn pop_returns_last() {
610 let mut vec = ArrayVec::<i32, 4>::new();
611 vec.push(10);
612 vec.push(20);
613 assert_eq!(vec.pop(), Some(20));
614 assert_eq!(vec.pop(), Some(10));
615 }
616
617 #[test]
618 fn pop_empty_none() {
619 let mut vec = ArrayVec::<i32, 4>::new();
620 assert_eq!(vec.pop(), None);
621 }
622
623 #[test]
624 fn clear_empties() {
625 let mut vec = ArrayVec::<i32, 4>::new();
626 vec.push(1);
627 vec.push(2);
628 vec.clear();
629 assert!(vec.is_empty());
630 assert_eq!(vec.len(), 0);
631 }
632
633 #[test]
634 fn swap_remove_middle() {
635 let mut vec = ArrayVec::<i32, 4>::new();
636 vec.push(10);
637 vec.push(20);
638 vec.push(30);
639 let removed = vec.swap_remove(1);
640 assert_eq!(removed, 20);
641 assert_eq!(vec.len(), 2);
642 // 30 was swapped into index 1
643 assert_eq!(vec.as_slice(), &[10, 30]);
644 }
645
646 #[test]
647 fn swap_remove_first() {
648 let mut vec = ArrayVec::<i32, 4>::new();
649 vec.push(10);
650 vec.push(20);
651 vec.push(30);
652 let removed = vec.swap_remove(0);
653 assert_eq!(removed, 10);
654 assert_eq!(vec.as_slice(), &[30, 20]);
655 }
656
657 #[test]
658 fn swap_remove_last() {
659 let mut vec = ArrayVec::<i32, 4>::new();
660 vec.push(10);
661 vec.push(20);
662 let removed = vec.swap_remove(1);
663 assert_eq!(removed, 20);
664 assert_eq!(vec.as_slice(), &[10]);
665 }
666
667 #[test]
668 #[should_panic(expected = "index out of bounds")]
669 fn swap_remove_out_of_bounds() {
670 let mut vec = ArrayVec::<i32, 4>::new();
671 vec.push(1);
672 vec.swap_remove(5);
673 }
674
675 #[test]
676 fn as_slice_and_as_mut_slice() {
677 let mut vec = ArrayVec::<i32, 4>::new();
678 vec.push(1);
679 vec.push(2);
680 vec.push(3);
681 assert_eq!(vec.as_slice(), &[1, 2, 3]);
682 vec.as_mut_slice()[1] = 99;
683 assert_eq!(vec.as_slice(), &[1, 99, 3]);
684 }
685
686 #[test]
687 fn index_and_index_mut() {
688 let mut vec = ArrayVec::<i32, 4>::new();
689 vec.push(10);
690 vec.push(20);
691 assert_eq!(vec[0], 10);
692 assert_eq!(vec[1], 20);
693 vec[0] = 99;
694 assert_eq!(vec[0], 99);
695 }
696
697 #[test]
698 fn iter_collects() {
699 let mut vec = ArrayVec::<i32, 4>::new();
700 vec.push(1);
701 vec.push(2);
702 vec.push(3);
703 let collected: Vec<&i32> = vec.iter().collect();
704 assert_eq!(collected, vec![&1, &2, &3]);
705 }
706
707 #[test]
708 fn iter_mut_modifies() {
709 let mut vec = ArrayVec::<i32, 4>::new();
710 vec.push(1);
711 vec.push(2);
712 vec.push(3);
713 for v in vec.iter_mut() {
714 *v *= 10;
715 }
716 assert_eq!(vec.as_slice(), &[10, 20, 30]);
717 }
718
719 #[test]
720 fn reverse_elements() {
721 let mut vec = ArrayVec::<i32, 4>::new();
722 vec.push(1);
723 vec.push(2);
724 vec.push(3);
725 vec.push(4);
726 vec.reverse();
727 assert_eq!(vec.as_slice(), &[4, 3, 2, 1]);
728 }
729
730 #[test]
731 fn reverse_single() {
732 let mut vec = ArrayVec::<i32, 4>::new();
733 vec.push(42);
734 vec.reverse();
735 assert_eq!(vec.as_slice(), &[42]);
736 }
737
738 #[test]
739 fn reverse_empty() {
740 let mut vec = ArrayVec::<i32, 4>::new();
741 vec.reverse(); // should not panic
742 assert!(vec.is_empty());
743 }
744
745 #[test]
746 fn contains_element() {
747 let mut vec = ArrayVec::<i32, 4>::new();
748 vec.push(10);
749 vec.push(20);
750 vec.push(30);
751 assert!(vec.contains(&20));
752 assert!(!vec.contains(&99));
753 }
754
755 #[test]
756 fn sort_unstable_orders() {
757 let mut vec = ArrayVec::<i32, 4>::new();
758 vec.push(3);
759 vec.push(1);
760 vec.push(4);
761 vec.push(2);
762 vec.sort_unstable();
763 assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
764 }
765
766 #[test]
767 fn sort_already_sorted() {
768 let mut vec = ArrayVec::<i32, 4>::new();
769 vec.push(1);
770 vec.push(2);
771 vec.push(3);
772 vec.sort_unstable();
773 assert_eq!(vec.as_slice(), &[1, 2, 3]);
774 }
775
776 #[test]
777 fn zero_capacity_vec() {
778 let vec = ArrayVec::<i32, 0>::new();
779 assert!(vec.is_empty());
780 assert_eq!(vec.len(), 0);
781 }
782
783 #[test]
784 fn zero_capacity_try_push_fails() {
785 let mut vec = ArrayVec::<i32, 0>::new();
786 assert!(vec.try_push(1).is_err());
787 }
788
789 #[test]
790 fn insert_at_beginning() {
791 let mut vec = ArrayVec::<i32, 4>::new();
792 vec.push(2);
793 vec.push(3);
794 vec.insert(0, 1);
795 assert_eq!(vec.as_slice(), &[1, 2, 3]);
796 }
797
798 #[test]
799 fn insert_at_middle() {
800 let mut vec = ArrayVec::<i32, 4>::new();
801 vec.push(1);
802 vec.push(3);
803 vec.insert(1, 2);
804 assert_eq!(vec.as_slice(), &[1, 2, 3]);
805 }
806
807 #[test]
808 fn insert_at_end() {
809 let mut vec = ArrayVec::<i32, 4>::new();
810 vec.push(1);
811 vec.push(2);
812 vec.insert(2, 3);
813 assert_eq!(vec.as_slice(), &[1, 2, 3]);
814 }
815
816 #[test]
817 fn insert_into_empty() {
818 let mut vec = ArrayVec::<i32, 4>::new();
819 vec.insert(0, 42);
820 assert_eq!(vec.as_slice(), &[42]);
821 }
822
823 #[test]
824 #[should_panic(expected = "index out of bounds")]
825 fn insert_out_of_bounds() {
826 let mut vec = ArrayVec::<i32, 4>::new();
827 vec.push(1);
828 vec.insert(5, 2);
829 }
830
831 #[test]
832 #[should_panic(expected = "ran out of capacity")]
833 fn insert_full_panics() {
834 let mut vec = ArrayVec::<i32, 2>::new();
835 vec.push(1);
836 vec.push(2);
837 vec.insert(0, 3);
838 }
839
840 #[test]
841 fn remove_first() {
842 let mut vec = ArrayVec::<i32, 4>::new();
843 vec.push(1);
844 vec.push(2);
845 vec.push(3);
846 let removed = vec.remove(0);
847 assert_eq!(removed, 1);
848 assert_eq!(vec.as_slice(), &[2, 3]);
849 }
850
851 #[test]
852 fn remove_middle() {
853 let mut vec = ArrayVec::<i32, 4>::new();
854 vec.push(1);
855 vec.push(2);
856 vec.push(3);
857 let removed = vec.remove(1);
858 assert_eq!(removed, 2);
859 assert_eq!(vec.as_slice(), &[1, 3]);
860 }
861
862 #[test]
863 fn remove_last() {
864 let mut vec = ArrayVec::<i32, 4>::new();
865 vec.push(1);
866 vec.push(2);
867 vec.push(3);
868 let removed = vec.remove(2);
869 assert_eq!(removed, 3);
870 assert_eq!(vec.as_slice(), &[1, 2]);
871 }
872
873 #[test]
874 #[should_panic(expected = "index out of bounds")]
875 fn remove_out_of_bounds() {
876 let mut vec = ArrayVec::<i32, 4>::new();
877 vec.push(1);
878 vec.remove(5);
879 }
880
881 #[test]
882 fn remove_only_element() {
883 let mut vec = ArrayVec::<i32, 4>::new();
884 vec.push(42);
885 let removed = vec.remove(0);
886 assert_eq!(removed, 42);
887 assert!(vec.is_empty());
888 }
889
890 #[test]
891 fn last_empty() {
892 let vec = ArrayVec::<i32, 4>::new();
893 assert_eq!(vec.last(), None);
894 }
895
896 #[test]
897 fn last_non_empty() {
898 let mut vec = ArrayVec::<i32, 4>::new();
899 vec.push(1);
900 vec.push(2);
901 assert_eq!(vec.last(), Some(&2));
902 }
903
904 #[test]
905 fn is_full_check() {
906 let mut vec = ArrayVec::<i32, 2>::new();
907 assert!(!vec.is_full());
908 vec.push(1);
909 assert!(!vec.is_full());
910 vec.push(2);
911 assert!(vec.is_full());
912 }
913
914 #[test]
915 fn insert_remove_round_trip() {
916 let mut vec = ArrayVec::<i32, 8>::new();
917 for i in 0..5 {
918 vec.push(i * 10);
919 }
920 // [0, 10, 20, 30, 40]
921 vec.insert(2, 15);
922 // [0, 10, 15, 20, 30, 40]
923 assert_eq!(vec.as_slice(), &[0, 10, 15, 20, 30, 40]);
924 let removed = vec.remove(3);
925 assert_eq!(removed, 20);
926 // [0, 10, 15, 30, 40]
927 assert_eq!(vec.as_slice(), &[0, 10, 15, 30, 40]);
928 }
929}