this repo has no description
1#![cfg_attr(not(test), no_std)]
2// #![no_std]
3
4use core::borrow::{Borrow, BorrowMut};
5use core::error::Error;
6use core::hash::{Hash, Hasher};
7use core::mem::MaybeUninit;
8use core::ops::{Bound, Deref, DerefMut, RangeBounds};
9use core::ptr::NonNull;
10use core::{cmp, fmt, mem, ptr, slice};
11
12pub struct CapacityError<T>(pub T);
13
14impl<T> Error for CapacityError<T> {}
15
16impl<T> fmt::Display for CapacityError<T> {
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 f.write_str("insufficient capacity")
19 }
20}
21
22impl<T> fmt::Debug for CapacityError<T> {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 write!(f, "CapacityError: insufficient capacity")
25 }
26}
27
28/// A vector with a fixed capacity.
29///
30/// The `ArrayVec` is a vector backed by a fixed size array. Elements are stored inline in the vector
31/// itself (rather than on the heap) making `ArrayVec` suitable to be allocated on the stack or
32/// used in `const` contexts.
33///
34/// The maximum capacity of the vector is determined by the `CAP` generic parameter, attempting to
35/// insert more elements than `CAP` will always fail.
36pub struct ArrayVec<T, const CAP: usize> {
37 len: usize,
38 data: [MaybeUninit<T>; CAP],
39}
40
41impl<T, const CAP: usize> Default for ArrayVec<T, CAP> {
42 fn default() -> Self {
43 Self::new()
44 }
45}
46
47impl<T, const CAP: usize> Drop for ArrayVec<T, CAP> {
48 fn drop(&mut self) {
49 self.clear();
50 }
51}
52
53impl<T, const CAP: usize> ArrayVec<T, CAP> {
54 /// Create a new empty `ArrayVec`.
55 ///
56 /// The maximum capacity is given by the generic parameter `CAP`.
57 #[inline]
58 pub const fn new() -> Self {
59 Self {
60 data: [const { MaybeUninit::uninit() }; CAP],
61 len: 0,
62 }
63 }
64
65 /// Returns the number of elements in the `ArrayVec`.
66 #[inline(always)]
67 pub const fn len(&self) -> usize {
68 self.len
69 }
70
71 /// Returns `true` if the `ArrayVec` is empty, `false` otherwise.
72 #[inline]
73 pub const fn is_empty(&self) -> bool {
74 self.len() == 0
75 }
76
77 /// Returns the capacity of the `ArrayVec`.
78 #[inline(always)]
79 pub const fn capacity(&self) -> usize {
80 CAP
81 }
82
83 /// Returns `true` if the `ArrayVec` is completely filled to its capacity, `false` otherwise.
84 pub const fn is_full(&self) -> bool {
85 self.len() == self.capacity()
86 }
87
88 /// Returns the capacity left in the `ArrayVec`.
89 pub const fn remaining_capacity(&self) -> usize {
90 self.capacity() - self.len()
91 }
92
93 /// Returns a raw pointer to the vector’s buffer.
94 pub const fn as_ptr(&self) -> *const T {
95 self.data.as_ptr().cast()
96 }
97
98 /// Returns a raw mutable pointer to the vector’s buffer.
99 pub const fn as_mut_ptr(&mut self) -> *mut T {
100 self.data.as_mut_ptr().cast()
101 }
102
103 /// Extracts a slice containing the entire vector.
104 pub const fn as_slice(&self) -> &[T] {
105 // SAFETY: `slice::from_raw_parts` requires
106 // 1. pointee is a contiguous, aligned buffer of size `len` containing properly-initialized `T`s.
107 // 2. Data must not be mutated for the returned lifetime.
108 // 3. Further, `len * size_of::<T>` <= `isize::MAX`, and allocation does not "wrap" through overflowing memory addresses.
109 //
110 // The ArrayVec API guarantees properly-initialized items within 0..len
111 // and the backing store being a Rust array guarantees correct alignment and contiguity.
112 // 3. Is also guaranteed by construction (can't express a type that's too large) and we
113 // since we borrow self here 2. is upheld as well.
114 unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
115 }
116
117 /// Extracts a mutable slice of the entire vector.
118 pub const fn as_mut_slice(&mut self) -> &mut [T] {
119 // SAFETY: `slice::from_raw_parts` requires
120 // 1. pointee is a contiguous, aligned buffer of size `len` containing properly-initialized `T`s.
121 // 2. Data must not be mutated for the returned lifetime.
122 // 3. Further, `len * size_of::<T>` <= `isize::MAX`, and allocation does not "wrap" through overflowing memory addresses.
123 //
124 // The ArrayVec API guarantees properly-initialized items within 0..len
125 // and the backing store being a Rust array guarantees correct alignment and contiguity.
126 // 3. Is also guaranteed by construction (can't express a type that's too large) and we
127 // since we borrow self here 2. is upheld as well.
128 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
129 }
130
131 /// Push `element` to the end of the vector.
132 ///
133 /// # Panics
134 ///
135 /// Panics if the `ArrayVec` is full.
136 pub fn push(&mut self, element: T) {
137 self.try_push(element).unwrap();
138 }
139
140 /// Push `element` to the end of the vector.
141 ///
142 /// # Errors
143 ///
144 /// Returns `Err(CapacityError)` with the element if the `ArrayVec` is full.
145 pub const fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> {
146 if self.len() < CAP {
147 // Safety: we have checked the capacity above
148 unsafe {
149 self.push_unchecked(element);
150 }
151 Ok(())
152 } else {
153 Err(CapacityError(element))
154 }
155 }
156
157 /// Push `element` to the end of the vector, without doing bounds checking.
158 ///
159 /// # Safety
160 ///
161 /// Calling this method with on an already full vector is *[undefined behavior]*.
162 /// The caller has to ensure that `self.len() < self.capacity()`.
163 #[track_caller]
164 pub const unsafe fn push_unchecked(&mut self, element: T) {
165 let len = self.len();
166 debug_assert!(len < CAP);
167 self.data[len].write(element);
168 self.len += 1;
169 }
170
171 /// Removes the last element from a vector and returns it, or [`None`] if it
172 /// is empty.
173 ///
174 /// # Time complexity
175 ///
176 /// Takes *O*(1) time.
177 #[inline]
178 pub const fn pop(&mut self) -> Option<T> {
179 if self.len == 0 {
180 None
181 } else {
182 // Safety: we have checked `len` is NOT zero above, which means there
183 // must be at least one element in the vec at the `len - 1` index.
184 unsafe {
185 self.len -= 1;
186 core::hint::assert_unchecked(self.len < self.capacity());
187 Some(ptr::read(self.as_ptr().add(self.len())))
188 }
189 }
190 }
191
192 /// Remove all elements in the vector.
193 pub fn clear(&mut self) {
194 let len = self.len;
195 self.len = 0;
196 for elt in self.data.iter_mut().take(len) {
197 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
198 unsafe { MaybeUninit::assume_init_drop(elt) };
199 }
200 }
201
202 /// Retains only the elements specified by the predicate.
203 pub fn retain<F>(&mut self, mut f: F)
204 where
205 F: FnMut(&mut T) -> bool,
206 {
207 // The implementation below is taken from std::vec::Vec
208
209 let original_len = self.len();
210 self.len = 0;
211
212 struct BackshiftOnDrop<'a, T, const CAP: usize> {
213 v: &'a mut ArrayVec<T, CAP>,
214 processed_len: usize,
215 deleted_cnt: usize,
216 original_len: usize,
217 }
218
219 impl<T, const CAP: usize> Drop for BackshiftOnDrop<'_, T, CAP> {
220 fn drop(&mut self) {
221 if self.deleted_cnt > 0 {
222 // Safety: Trailing unchecked items must be valid since we never touch them.
223 unsafe {
224 ptr::copy(
225 self.v.as_ptr().add(self.processed_len),
226 self.v
227 .as_mut_ptr()
228 .add(self.processed_len - self.deleted_cnt),
229 self.original_len - self.processed_len,
230 );
231 }
232 }
233 self.v.len = self.original_len - self.deleted_cnt;
234 }
235 }
236
237 let mut g = BackshiftOnDrop {
238 v: self,
239 processed_len: 0,
240 deleted_cnt: 0,
241 original_len,
242 };
243
244 #[inline(always)]
245 fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>(
246 f: &mut F,
247 g: &mut BackshiftOnDrop<'_, T, CAP>,
248 ) -> bool {
249 // Safety: Unchecked element must be valid.
250 let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) };
251 // Safety: Unchecked element must be valid.
252 if !f(unsafe { cur.as_mut().unwrap() }) {
253 g.processed_len += 1;
254 g.deleted_cnt += 1;
255 // Safety: We never touch this element again after dropped.
256 unsafe { ptr::drop_in_place(cur) };
257 return false;
258 }
259 if DELETED {
260 // Safety: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
261 // We use copy for move, and never touch this element again.
262 unsafe {
263 let hole_slot = cur.sub(g.deleted_cnt);
264 ptr::copy_nonoverlapping(cur, hole_slot, 1);
265 }
266 }
267 g.processed_len += 1;
268 true
269 }
270
271 // Stage 1: Nothing was deleted.
272 while g.processed_len != original_len {
273 if !process_one::<F, T, CAP, false>(&mut f, &mut g) {
274 break;
275 }
276 }
277
278 // Stage 2: Some elements were deleted.
279 while g.processed_len != original_len {
280 process_one::<F, T, CAP, true>(&mut f, &mut g);
281 }
282
283 drop(g);
284 }
285
286 /// Removes the subslice indicated by the given range from the vector,
287 /// returning a double-ended iterator over the removed subslice.
288 ///
289 /// If the iterator is dropped before being fully consumed,
290 /// it drops the remaining removed elements.
291 ///
292 /// The returned iterator keeps a mutable borrow on the vector to optimize
293 /// its implementation.
294 ///
295 /// # Panics
296 ///
297 /// Panics if the starting point is greater than the end point or if
298 /// the end point is greater than the length of the vector.
299 ///
300 /// # Leaking
301 ///
302 /// If the returned iterator goes out of scope without being dropped (due to
303 /// [`mem::forget`], for example), the vector may have lost and leaked
304 /// elements arbitrarily, including elements outside the range.
305 pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, CAP>
306 where
307 R: RangeBounds<usize>,
308 {
309 // Memory safety
310 //
311 // When the Drain is first created, it shortens the length of
312 // the source vector to make sure no uninitialized or moved-from elements
313 // are accessible at all if the Drain's destructor never gets to run.
314 //
315 // Drain will ptr::read out the values to remove.
316 // When finished, remaining tail of the vec is copied back to cover
317 // the hole, and the vector length is restored to the new length.
318
319 let len = self.len();
320 let start = match range.start_bound() {
321 Bound::Unbounded => 0,
322 Bound::Included(&i) => i,
323 Bound::Excluded(&i) => i.saturating_add(1),
324 };
325 let end = match range.end_bound() {
326 Bound::Excluded(&j) => j,
327 Bound::Included(&j) => j.saturating_add(1),
328 Bound::Unbounded => len,
329 };
330
331 // set our length to start, to be safe in case Drain is leaked
332 self.len = start;
333 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
334 // Note: we do this unsafe slicing here because we also need to mutably borrow self (for backshifting the tail)
335 let range_slice = unsafe { slice::from_raw_parts(self.as_ptr().add(start), end - start) };
336
337 Drain {
338 tail_start: end,
339 tail_len: len - end,
340 iter: range_slice.iter(),
341 #[expect(clippy::ref_as_ptr, reason = "passing &mut self to a function would invalidate the slice iterator")]
342 // Safety: We have a &mut to self, so creating a pointer from it is always safe.
343 vec: unsafe { NonNull::new_unchecked(self as *mut _) },
344 }
345 }
346
347 /// Shortens the vector, keeping the first `len` elements and dropping
348 /// the rest
349 pub fn truncate(&mut self, new_len: usize) {
350 let len = self.len();
351 if new_len < len {
352 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
353 // we have checked that new_len is less than len so all elements within 0..new_len must be
354 // initialized
355 unsafe {
356 self.len = new_len;
357 let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len);
358 ptr::drop_in_place(tail);
359 }
360 }
361 }
362
363 /// Returns the remaining spare capacity of the vector as a slice of
364 /// `MaybeUninit<T>`.
365 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
366 let len = self.len();
367 &mut self.data[len..]
368 }
369
370 /// Extend the `ArrayVec` with elements from the provided slice
371 ///
372 /// # Panics
373 ///
374 /// Panics if the `ArrayVec` does not have enough capacity to accommodate
375 /// the elements.
376 pub fn extend_from_slice(&mut self, slice: &[T])
377 where
378 T: Clone,
379 {
380 self.try_extend_from_slice(slice).unwrap();
381 }
382
383 /// Extend the `ArrayVec` with elements from the provided slice
384 ///
385 /// # Errors
386 ///
387 /// Returns a `CapacityError` if the `ArrayVec` does not have enough capacity to accommodate
388 /// the elements.
389 pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError<()>>
390 where
391 T: Clone,
392 {
393 if self.remaining_capacity() < other.len() {
394 return Err(CapacityError(()));
395 }
396
397 for (element, slot) in other.iter().cloned().zip(self.spare_capacity_mut()) {
398 slot.write(element);
399 }
400 self.len += other.len();
401
402 Ok(())
403 }
404}
405
406impl<T, const CAP: usize> fmt::Debug for ArrayVec<T, CAP>
407where
408 T: fmt::Debug,
409{
410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411 (**self).fmt(f)
412 }
413}
414
415impl<T, const CAP: usize> Clone for ArrayVec<T, CAP>
416where
417 T: Clone,
418{
419 fn clone(&self) -> Self {
420 self.iter().cloned().collect()
421 }
422
423 fn clone_from(&mut self, rhs: &Self) {
424 // recursive case for the common prefix
425 let prefix = cmp::min(self.len(), rhs.len());
426 self[..prefix].clone_from_slice(&rhs[..prefix]);
427
428 if prefix < self.len() {
429 // rhs was shorter
430 self.truncate(prefix);
431 } else {
432 let rhs_elems = &rhs[self.len()..];
433 self.extend_from_slice(rhs_elems);
434 }
435 }
436}
437
438impl<T, const CAP: usize> Deref for ArrayVec<T, CAP> {
439 type Target = [T];
440 #[inline]
441 fn deref(&self) -> &Self::Target {
442 self.as_slice()
443 }
444}
445
446impl<T, const CAP: usize> DerefMut for ArrayVec<T, CAP> {
447 #[inline]
448 fn deref_mut(&mut self) -> &mut Self::Target {
449 self.as_mut_slice()
450 }
451}
452
453impl<T, const CAP: usize> Hash for ArrayVec<T, CAP>
454where
455 T: Hash,
456{
457 fn hash<H: Hasher>(&self, state: &mut H) {
458 Hash::hash(&**self, state);
459 }
460}
461
462impl<T, const CAP: usize> PartialEq for ArrayVec<T, CAP>
463where
464 T: PartialEq,
465{
466 fn eq(&self, other: &Self) -> bool {
467 **self == **other
468 }
469}
470
471impl<T, const CAP: usize> PartialEq<[T]> for ArrayVec<T, CAP>
472where
473 T: PartialEq,
474{
475 fn eq(&self, other: &[T]) -> bool {
476 **self == *other
477 }
478}
479
480impl<T, const CAP: usize> Eq for ArrayVec<T, CAP> where T: Eq {}
481
482impl<T, const CAP: usize> Borrow<[T]> for ArrayVec<T, CAP> {
483 fn borrow(&self) -> &[T] {
484 self
485 }
486}
487
488impl<T, const CAP: usize> BorrowMut<[T]> for ArrayVec<T, CAP> {
489 fn borrow_mut(&mut self) -> &mut [T] {
490 self
491 }
492}
493
494impl<T, const CAP: usize> AsRef<[T]> for ArrayVec<T, CAP> {
495 fn as_ref(&self) -> &[T] {
496 self
497 }
498}
499
500impl<T, const CAP: usize> AsMut<[T]> for ArrayVec<T, CAP> {
501 fn as_mut(&mut self) -> &mut [T] {
502 self
503 }
504}
505
506impl<T, const CAP: usize> PartialOrd for ArrayVec<T, CAP>
507where
508 T: PartialOrd,
509{
510 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
511 (**self).partial_cmp(other)
512 }
513
514 fn lt(&self, other: &Self) -> bool {
515 (**self).lt(other)
516 }
517
518 fn le(&self, other: &Self) -> bool {
519 (**self).le(other)
520 }
521
522 fn ge(&self, other: &Self) -> bool {
523 (**self).ge(other)
524 }
525
526 fn gt(&self, other: &Self) -> bool {
527 (**self).gt(other)
528 }
529}
530
531impl<T, const CAP: usize> Ord for ArrayVec<T, CAP>
532where
533 T: Ord,
534{
535 fn cmp(&self, other: &Self) -> cmp::Ordering {
536 (**self).cmp(other)
537 }
538}
539
540/// Create an `ArrayVec` from an iterator.
541///
542/// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity.
543impl<T, const CAP: usize> FromIterator<T> for ArrayVec<T, CAP> {
544 /// Create an `ArrayVec` from an iterator.
545 ///
546 /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity.
547 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
548 let mut array = ArrayVec::new();
549 for element in iter {
550 array.push(element);
551 }
552 array
553 }
554}
555
556impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec<T, CAP> {
557 type Item = &'a T;
558 type IntoIter = slice::Iter<'a, T>;
559 fn into_iter(self) -> Self::IntoIter {
560 self.iter()
561 }
562}
563
564impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec<T, CAP> {
565 type Item = &'a mut T;
566 type IntoIter = slice::IterMut<'a, T>;
567 fn into_iter(self) -> Self::IntoIter {
568 self.iter_mut()
569 }
570}
571
572impl<T, const CAP: usize> IntoIterator for ArrayVec<T, CAP> {
573 type Item = T;
574 type IntoIter = IntoIter<T, CAP>;
575 fn into_iter(self) -> IntoIter<T, CAP> {
576 IntoIter {
577 index: 0,
578 vec: self,
579 }
580 }
581}
582
583pub struct IntoIter<T, const CAP: usize> {
584 index: usize,
585 vec: ArrayVec<T, CAP>,
586}
587
588impl<T, const CAP: usize> Drop for IntoIter<T, CAP> {
589 fn drop(&mut self) {
590 let len = self.vec.len();
591 self.vec.len = 0;
592 for elt in &mut self.vec.data[self.index..len] {
593 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
594 unsafe { MaybeUninit::assume_init_drop(elt) };
595 }
596 }
597}
598
599impl<T, const CAP: usize> fmt::Debug for IntoIter<T, CAP>
600where
601 T: fmt::Debug,
602{
603 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
604 f.debug_list().entries(&self.vec[self.index..]).finish()
605 }
606}
607
608impl<T, const CAP: usize> Iterator for IntoIter<T, CAP> {
609 type Item = T;
610
611 fn next(&mut self) -> Option<Self::Item> {
612 if self.vec.is_empty() || self.index >= self.vec.len {
613 None
614 } else {
615 let elt = mem::replace(&mut self.vec.data[self.index], MaybeUninit::uninit());
616 self.index += 1;
617 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
618 Some(unsafe { MaybeUninit::assume_init(elt) })
619 }
620 }
621
622 fn size_hint(&self) -> (usize, Option<usize>) {
623 (self.vec.len(), Some(self.vec.len()))
624 }
625}
626
627impl<T, const CAP: usize> DoubleEndedIterator for IntoIter<T, CAP> {
628 fn next_back(&mut self) -> Option<Self::Item> {
629 if self.vec.is_empty() || self.index >= self.vec.len {
630 None
631 } else {
632 let elt = mem::replace(&mut self.vec.data[self.vec.len - 1], MaybeUninit::uninit());
633 self.vec.len -= 1;
634 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
635 Some(unsafe { MaybeUninit::assume_init(elt) })
636 }
637 }
638}
639
640impl<T, const CAP: usize> ExactSizeIterator for IntoIter<T, CAP> {}
641
642/// A draining iterator for `ArrayVec`.
643pub struct Drain<'a, T, const CAP: usize> {
644 /// Index of tail to preserve
645 tail_start: usize,
646 /// Length of tail
647 tail_len: usize,
648 /// Current remaining range to remove
649 iter: slice::Iter<'a, T>,
650 vec: NonNull<ArrayVec<T, CAP>>,
651}
652
653impl<T, const CAP: usize> Iterator for Drain<'_, T, CAP> {
654 type Item = T;
655
656 fn next(&mut self) -> Option<Self::Item> {
657 self.iter.next().map(|elt| {
658 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
659 unsafe { ptr::read(ptr::from_ref(elt)) }
660 })
661 }
662
663 fn size_hint(&self) -> (usize, Option<usize>) {
664 self.iter.size_hint()
665 }
666}
667
668impl<T, const CAP: usize> DoubleEndedIterator for Drain<'_, T, CAP> {
669 fn next_back(&mut self) -> Option<Self::Item> {
670 self.iter.next_back().map(|elt| {
671 // Safety: ArrayVec API guarantees properly-initialized items within 0..len
672 unsafe { ptr::read(ptr::from_ref(elt)) }
673 })
674 }
675}
676
677impl<T, const CAP: usize> ExactSizeIterator for Drain<'_, T, CAP> {}
678
679impl<T, const CAP: usize> Drop for Drain<'_, T, CAP> {
680 fn drop(&mut self) {
681 /// Fill the drained range by backshifting the "tail" (elements after the drained range).
682 ///
683 /// We do this in a drop guard so that no matter what happens, even if T's drop panics
684 /// we leave an ArrayVec without uninitialized holes behind.
685 struct DropGuard<'r, 'a, T, const CAP: usize>(&'r mut Drain<'a, T, CAP>);
686
687 impl<'r, 'a, T, const CAP: usize> Drop for DropGuard<'r, 'a, T, CAP> {
688 fn drop(&mut self) {
689 if self.0.tail_len > 0 {
690 // Safety: See ArrayVec::drain comment
691 unsafe {
692 let source_vec = self.0.vec.as_mut();
693
694 // memmove back untouched tail, update to new length
695 let start = source_vec.len();
696 let tail = self.0.tail_start;
697 if tail != start {
698 // as_mut_ptr creates a &mut, invalidating other pointers.
699 // This pattern avoids calling it with a pointer already present.
700 let ptr = source_vec.as_mut_ptr();
701 let src = ptr.add(tail);
702 let dst = ptr.add(start);
703 ptr::copy(src, dst, self.0.tail_len);
704 }
705 source_vec.len = start + self.0.tail_len;
706 }
707 }
708 }
709 }
710
711 let guard = DropGuard(self);
712
713 // drain the iterator and drop its elements
714 for _ in guard.0.by_ref() {}
715 // while let Some(_) = guard.0.next() {}
716 }
717}
718
719#[cfg(test)]
720mod tests {
721 use super::*;
722
723 #[test]
724 fn new_creates_empty_vec() {
725 let vec: ArrayVec<i32, 10> = ArrayVec::new();
726 assert_eq!(vec.len(), 0);
727 assert!(vec.is_empty());
728 assert_eq!(vec.capacity(), 10);
729 }
730
731 #[test]
732 fn default_creates_empty_vec() {
733 let vec: ArrayVec<i32, 10> = ArrayVec::default();
734 assert_eq!(vec.len(), 0);
735 assert!(vec.is_empty());
736 }
737
738 #[test]
739 fn push_increases_length() {
740 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
741 vec.push(1);
742 assert_eq!(vec.len(), 1);
743 vec.push(2);
744 assert_eq!(vec.len(), 2);
745 }
746
747 #[test]
748 #[should_panic]
749 fn push_panics_when_full() {
750 let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
751 vec.push(1);
752 vec.push(2);
753 vec.push(3);
754 }
755
756 #[test]
757 fn try_push_succeeds_when_not_full() {
758 let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
759 assert!(vec.try_push(1).is_ok());
760 assert!(vec.try_push(2).is_ok());
761 }
762
763 #[test]
764 fn try_push_fails_when_full() {
765 let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
766 vec.push(1);
767 vec.push(2);
768 let result = vec.try_push(3);
769 assert!(result.is_err());
770 assert_eq!(result.unwrap_err().0, 3);
771 }
772
773 #[test]
774 fn is_full_returns_true_when_at_capacity() {
775 let mut vec: ArrayVec<i32, 2> = ArrayVec::new();
776 assert!(!vec.is_full());
777 vec.push(1);
778 assert!(!vec.is_full());
779 vec.push(2);
780 assert!(vec.is_full());
781 }
782
783 #[test]
784 fn as_slice_returns_valid_slice() {
785 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
786 vec.push(1);
787 vec.push(2);
788 vec.push(3);
789 let slice = vec.as_slice();
790 assert_eq!(slice, &[1, 2, 3]);
791 }
792
793 #[test]
794 fn as_mut_slice_allows_modification() {
795 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
796 vec.push(1);
797 vec.push(2);
798 let slice = vec.as_mut_slice();
799 slice[0] = 10;
800 assert_eq!(vec.as_slice(), &[10, 2]);
801 }
802 #[test]
803 fn clear_removes_all_elements() {
804 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
805 vec.push(1);
806 vec.push(2);
807 vec.push(3);
808 vec.clear();
809 assert_eq!(vec.len(), 0);
810 assert!(vec.is_empty());
811 }
812
813 #[test]
814 fn retain_keeps_matching_elements() {
815 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
816 vec.push(1);
817 vec.push(2);
818 vec.push(3);
819 vec.push(4);
820 vec.retain(|x| *x % 2 == 0);
821 assert_eq!(vec.as_slice(), &[2, 4]);
822 }
823
824 #[test]
825 fn clone_from_updates_to_match_source() {
826 let mut vec1: ArrayVec<i32, 10> = ArrayVec::new();
827 vec1.push(1);
828 vec1.push(2);
829 let mut vec2: ArrayVec<i32, 10> = ArrayVec::new();
830 vec2.push(3);
831 vec2.push(4);
832 vec2.push(5);
833 vec2.clone_from(&vec1);
834 assert_eq!(vec2.as_slice(), &[1, 2]);
835 }
836
837 #[test]
838 fn try_extend_from_slice_succeeds_with_capacity() {
839 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
840 vec.push(1);
841 assert!(vec.try_extend_from_slice(&[2, 3]).is_ok());
842 assert_eq!(vec.as_slice(), &[1, 2, 3]);
843 }
844
845 #[test]
846 fn try_extend_from_slice_fails_without_capacity() {
847 let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
848 vec.push(1);
849 let result = vec.try_extend_from_slice(&[2, 3, 4]);
850 assert!(result.is_err());
851 }
852
853 #[test]
854 fn extend_from_slice_adds_elements() {
855 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
856 vec.push(1);
857 vec.extend_from_slice(&[2, 3, 4]);
858 assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
859 }
860
861 #[test]
862 #[should_panic]
863 fn extend_from_slice_panics_when_insufficient_capacity() {
864 let mut vec: ArrayVec<i32, 3> = ArrayVec::new();
865 vec.push(1);
866 vec.extend_from_slice(&[2, 3, 4]);
867 }
868
869 #[test]
870 fn truncate_removes_trailing_elements() {
871 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
872 vec.push(1);
873 vec.push(2);
874 vec.push(3);
875 vec.push(4);
876 vec.truncate(2);
877 assert_eq!(vec.len(), 2);
878 assert_eq!(vec.as_slice(), &[1, 2]);
879 }
880
881 #[test]
882 fn drain_removes_elements_in_range() {
883 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
884 vec.extend_from_slice(&[1, 2, 3, 4, 5]);
885 let drained: Vec<_> = vec.drain(1..3).collect();
886 assert_eq!(drained, &[2, 3]);
887 assert_eq!(vec.as_slice(), &[1, 4, 5]);
888 }
889
890 #[test]
891 fn drain_calls_drop_on_remaining_elements() {
892 use core::sync::atomic::{AtomicUsize, Ordering};
893 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
894
895 struct DropCounter;
896 impl Drop for DropCounter {
897 fn drop(&mut self) {
898 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
899 }
900 }
901
902 {
903 let mut vec: ArrayVec<DropCounter, 5> = ArrayVec::new();
904 vec.push(DropCounter);
905 vec.push(DropCounter);
906 vec.push(DropCounter);
907 let mut drain = vec.drain(0..2);
908 drain.next(); // consume one element
909 // Drop drain without consuming all elements
910 drop(drain);
911
912 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 2);
913 }
914 // All 3 elements should be dropped: 1 consumed, 1 remaining in drain, 1 in vec
915 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
916 }
917
918 #[test]
919 fn drain_restores_tail_on_early_drop() {
920 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
921 vec.extend_from_slice(&[1, 2, 3, 4, 5]);
922 assert_eq!(vec.len(), 5);
923 {
924 let mut drain = vec.drain(1..3);
925 drain.next(); // consume one element (2)
926 // drain is dropped here without consuming all elements
927 }
928 // Tail should be restored: [1, 4, 5]
929 assert_eq!(vec.as_slice(), &[1, 4, 5]);
930 }
931
932 #[test]
933 fn drain_empty_range() {
934 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
935 vec.extend_from_slice(&[1, 2, 3]);
936 assert_eq!(vec.len(), 3);
937 let drained: Vec<_> = vec.drain(1..1).collect();
938 assert_eq!(drained.len(), 0);
939 assert_eq!(vec.as_slice(), &[1, 2, 3]);
940 }
941
942 #[test]
943 fn drain_full_range() {
944 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
945 vec.extend_from_slice(&[1, 2, 3, 4]);
946 assert_eq!(vec.len(), 4);
947 let drained: Vec<_> = vec.drain(..).collect();
948 assert_eq!(drained, &[1, 2, 3, 4]);
949 assert_eq!(vec.len(), 0);
950 assert!(vec.is_empty());
951 }
952
953 #[test]
954 fn drain_double_ended() {
955 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
956 vec.extend_from_slice(&[1, 2, 3, 4, 5]);
957 assert_eq!(vec.len(), 5);
958 let mut drain = vec.drain(1..4);
959 assert_eq!(drain.next(), Some(2));
960 assert_eq!(drain.next_back(), Some(4));
961 assert_eq!(drain.next(), Some(3));
962 assert_eq!(drain.next(), None);
963 drop(drain);
964 assert_eq!(vec.as_slice(), &[1, 5]);
965 }
966
967 #[test]
968 fn into_iter_consumes_all_elements() {
969 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
970 vec.extend_from_slice(&[1, 2, 3, 4, 5]);
971 let collected: Vec<_> = vec.into_iter().collect();
972 assert_eq!(collected, &[1, 2, 3, 4, 5]);
973 }
974
975 #[test]
976 fn into_iter_empty_vec() {
977 let vec: ArrayVec<i32, 10> = ArrayVec::new();
978 let collected: Vec<_> = vec.into_iter().collect();
979 assert_eq!(collected.len(), 0);
980 }
981
982 #[test]
983 fn into_iter_double_ended() {
984 let mut vec: ArrayVec<i32, 10> = ArrayVec::new();
985 vec.extend_from_slice(&[1, 2, 3, 4, 5]);
986 let mut iter = vec.into_iter();
987 assert_eq!(iter.next(), Some(1));
988 assert_eq!(iter.next_back(), Some(5));
989 assert_eq!(iter.next(), Some(2));
990 assert_eq!(iter.next_back(), Some(4));
991 assert_eq!(iter.next(), Some(3));
992 assert_eq!(iter.next(), None);
993 assert_eq!(iter.next_back(), None);
994 }
995
996 #[test]
997 fn into_iter_panic_in_drop() {
998 use core::sync::atomic::{AtomicUsize, Ordering};
999 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
1000
1001 enum DropEl {
1002 Count,
1003 Panic,
1004 }
1005
1006 impl Drop for DropEl {
1007 fn drop(&mut self) {
1008 match *self {
1009 DropEl::Count => {
1010 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
1011 }
1012 DropEl::Panic => {
1013 panic!("Oh no");
1014 }
1015 }
1016 }
1017 }
1018
1019 let mut vec: ArrayVec<DropEl, 5> = ArrayVec::new();
1020 vec.push(DropEl::Count);
1021 vec.push(DropEl::Panic);
1022 vec.push(DropEl::Count);
1023
1024 let mut iter = vec.into_iter();
1025 iter.next();
1026 let _ = std::panic::catch_unwind(|| drop(iter));
1027
1028 // Note we don't see enough drop counts, essentially every element after the panic is leaked
1029 // but at least we don't access uninitialized elements and trigger UB
1030 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
1031 }
1032
1033 #[test]
1034 fn drain_panic_in_drop() {
1035 use core::sync::atomic::{AtomicUsize, Ordering};
1036 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
1037
1038 enum DropEl {
1039 Count,
1040 Panic,
1041 }
1042
1043 impl Drop for DropEl {
1044 fn drop(&mut self) {
1045 match *self {
1046 DropEl::Count => {
1047 DROP_COUNT.fetch_add(1, Ordering::SeqCst);
1048 }
1049 DropEl::Panic => {
1050 panic!("Oh no");
1051 }
1052 }
1053 }
1054 }
1055
1056 let mut vec: ArrayVec<DropEl, 5> = ArrayVec::new();
1057 vec.push(DropEl::Count);
1058 vec.push(DropEl::Panic);
1059 vec.push(DropEl::Count);
1060
1061 let drain = vec.drain(1..2);
1062 assert_eq!(drain.len(), 1);
1063 let _ = std::panic::catch_unwind(|| drop(drain));
1064 assert_eq!(vec.len(), 2);
1065 drop(vec);
1066 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 2);
1067 }
1068}