Skip to main content

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}