cds/
arrayvec.rs

1//! A vector-like array.
2
3use crate::{
4    len::{LengthType, Usize},
5    mem::{SpareMemoryPolicy, Uninitialized},
6};
7use core::{
8    marker::PhantomData,
9    mem,
10    ops::{Bound, RangeBounds},
11    ptr,
12    result::Result,
13    slice,
14};
15
16mod drain;
17pub use drain::*;
18
19pub mod errors;
20use errors::*;
21
22mod retain;
23use retain::*;
24
25/// A continuous non-growable array with vector-like API.
26///
27/// Written as `ArrayVec<T, C, L, SM>`, array vector has the capacity to store `C` elements of type
28/// `T`.
29///
30/// It uses type `L` as [`length type`], and `SM` as [`spare memory policy`].
31///
32/// `ArrayVec` stores elements inline in the struct itself, and doesn't allocate memory on the heap.
33///
34/// The size of `ArrayVec` struct is not constant, as it depends on the requested capacity and
35/// size of `T` (like a standard array).
36///
37/// `ArrayVec` may be created empty, with no elements.
38/// However, once created, contrary to `Vec` which allocates memory only when elements are pushed,
39/// `ArrayVec` occupies all the memory needed for the requested capacity.
40///
41/// The capacity of `ArrayVec` cannot be dynamically changed.
42///
43/// [`spare memory policy`]: SpareMemoryPolicy
44/// [`length type`]: LengthType
45///
46///
47/// # Examples
48///
49/// ```rust
50/// # use cds::{arrayvec::ArrayVec, array_vec, len::U8};
51/// let mut v = ArrayVec::<u64, 12, U8>::new();
52/// assert_eq!(v.len(), 0);
53/// assert_eq!(v.capacity(), 12);
54/// assert_eq!(v.spare_capacity(), 12);
55/// assert_eq!(v, []);
56///
57/// v.push(1);
58/// v.push(2);
59///
60/// assert_eq!(v.len(), 2);
61/// assert_eq!(v.capacity(), 12);
62/// assert_eq!(v.spare_capacity(), 10);
63/// assert_eq!(v, [1, 2]);
64///
65/// v[0] = 7;
66/// assert_eq!(v, [7, 2]);
67/// ```
68///
69/// The [`array_vec!`] macro is provided for convenient initialization:
70///
71/// ```rust
72/// # use cds::array_vec;
73/// let mut v = array_vec![12; u64; 1, 2, 3];
74/// assert_eq!(v, [1, 2, 3]);
75///
76/// v.push(7);
77/// assert_eq!(v, [1, 2, 3, 7]);
78/// ```
79///
80/// [`push`] panics if there is no spare capacity:
81///
82/// ```should_panic
83/// # use cds::array_vec;
84/// let mut v = array_vec![3; 6, 7, 8];
85/// assert_eq!(v.has_spare_capacity(), false);
86/// v.push(9);  // <-- this panics as there is no spare capacity
87/// ```
88///
89/// Avoid a panic with [`try_push`] method, which returns [`InsufficientCapacityError`] instead:
90///
91/// ```rust
92/// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityError};
93/// let mut v = array_vec![3; 6, 7, 8];
94/// assert!(matches!(v.try_push(9), Err(e) if e == InsufficientCapacityError));
95/// ```
96///
97/// An `ArrayVec` can be created from an iterator:
98///
99/// ```rust
100/// # use cds::{arrayvec::ArrayVec, len::U8};
101/// type A = ArrayVec<u64, 5, U8>;
102/// let vec = vec![1, 2, 3, 4, 5];
103/// let a = vec.iter()
104///            .map(|x| x * x)
105///            .filter(|x| x % 2 == 0)
106///            .collect::<A>();
107/// assert_eq!(a, [4, 16]);
108/// ```
109///
110/// If the iterator yields more than [`CAPACITY`] elements, the method panics:
111///
112/// ```should_panic
113/// # use cds::{arrayvec::ArrayVec, len::U64, mem::Uninitialized};
114/// type A = ArrayVec<u64, 3, U64, Uninitialized>; // <-- the capacity is 3
115/// let vec = vec![1, 2, 3, 4, 5];
116/// let a = vec.iter()                             // <-- but the iterator yields 5 elements
117///            .map(|x| x * x)
118///            .collect::<A>();                    // <-- this panics
119/// ```
120///
121/// Avoid a panic with [`try_from_iter`] method, which returns [`InsufficientCapacityError`]
122/// instead:
123///
124/// ```rust
125/// # use cds::{arrayvec::{ArrayVec, errors::InsufficientCapacityError}, len::U64};
126/// type A = ArrayVec<u64, 3, U64>;
127/// let vec = vec![1, 2, 3, 4, 5];
128/// let iter = vec.iter().map(|x| x * x);
129/// assert!(matches!(A::try_from_iter(iter), Err(e) if e == InsufficientCapacityError));
130/// ```
131///
132/// [`array_vec!`]: crate::array_vec
133/// [`CAPACITY`]: ArrayVec::CAPACITY
134/// [`try_from_iter`]: ArrayVec::try_from_iter
135/// [`try_push`]: ArrayVec::try_push
136/// [`push`]: ArrayVec::push
137pub struct ArrayVec<T, const C: usize, L = Usize, SM = Uninitialized>
138where
139    L: LengthType,
140    SM: SpareMemoryPolicy<T>,
141{
142    arr: [mem::MaybeUninit<T>; C],
143    len: L,
144    phantom1: PhantomData<SM>,
145}
146
147impl<T, L, SM, const C: usize> ArrayVec<T, C, L, SM>
148where
149    L: LengthType,
150    SM: SpareMemoryPolicy<T>,
151{
152    /// The capacity of the array-vector as associated constant.
153    ///
154    /// The capacity can also be obtained via the [`capacity`] method.
155    ///
156    /// # Examples
157    /// ```rust
158    /// # use cds::{arrayvec::ArrayVec, len::U8, mem::Uninitialized};
159    /// type A = ArrayVec<u64, 8, U8, Uninitialized>;
160    /// let v = A::new();
161    /// assert_eq!(A::CAPACITY, 8);
162    /// assert_eq!(v.capacity(), A::CAPACITY);
163    /// ```
164    ///
165    /// [`capacity`]: ArrayVec::capacity
166    pub const CAPACITY: usize = C;
167
168    /// Creates an empty `ArrayVec`.
169    ///
170    /// # Safety
171    ///
172    /// This method panics if requested capacity `C` exceeds the maximal value that can be stored in
173    /// length type `L`.
174    ///
175    /// # Examples
176    ///
177    /// ```rust
178    /// # use cds::{arrayvec::ArrayVec, len::U8, mem::Zeroed};
179    /// let a = ArrayVec::<u64, 8, U8, Zeroed>::new();
180    /// assert_eq!(a.capacity(), 8);
181    /// assert_eq!(a.len(), 0);
182    /// ```
183    #[inline]
184    pub fn new() -> Self {
185        assert!(C <= L::MAX);
186        let mut v = ArrayVec {
187            // it is safe to call `assume_init` to create an array of `MaybeUninit`
188            arr: unsafe { mem::MaybeUninit::uninit().assume_init() },
189            len: L::new(0),
190            phantom1: PhantomData,
191        };
192        unsafe { SM::init(v.as_mut_ptr(), Self::CAPACITY) };
193        v
194    }
195
196    /// Returns the number of elements in the array-vector.
197    ///
198    /// # Examples
199    ///
200    /// ```rust
201    /// # use cds::{arrayvec::ArrayVec, array_vec};
202    /// let mut a = array_vec![12; 3, 4];
203    /// assert_eq!(a.len(), 2);
204    /// a.pop();
205    /// assert_eq!(a.len(), 1);
206    /// ```
207    #[inline]
208    pub fn len(&self) -> usize {
209        self.len.as_usize()
210    }
211
212    /// Returns `true` if the array-vector contains no elements.
213    ///
214    /// Equivalent to `len() == 0`.
215    ///
216    /// # Examples
217    /// ```rust
218    /// # use cds::array_vec;
219    /// assert_eq!(array_vec![3; u64].is_empty(), true);
220    /// assert_eq!(array_vec![3; u64; 1].is_empty(), false);
221    /// ```
222    #[inline]
223    pub fn is_empty(&self) -> bool {
224        self.len == 0
225    }
226
227    /// Returns `true` if the array-vector is completely full.
228    ///
229    /// Equivalent to `len() == capacity()`.
230    ///
231    /// # Examples
232    /// ```rust
233    /// # use cds::array_vec;
234    /// let mut v = array_vec![3; u64; 1, 2];
235    /// assert_eq!(v.is_full(), false);
236    /// v.push(3);
237    /// assert_eq!(v.is_full(), true);
238    /// ```
239    #[inline]
240    pub fn is_full(&self) -> bool {
241        self.len == Self::CAPACITY
242    }
243
244    /// Returns a raw pointer to the array-vector's buffer.
245    ///
246    /// The caller must ensure that the array-vector outlives the pointer this function returns.
247    /// Otherwise, it will end up pointing to garbage.
248    ///
249    /// The caller must also ensure that the memory the pointer (non-transitively) points to is
250    /// never written to (except inside an `UnsafeCell`) using this pointer or any pointer derived
251    /// from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
252    ///
253    /// [`as_mut_ptr`]: ArrayVec::as_mut_ptr
254    #[inline]
255    pub fn as_ptr(&self) -> *const T {
256        self.arr.as_ptr() as *const T
257    }
258
259    /// Returns an unsafe mutable pointer to the array-vector's buffer.
260    ///
261    /// The caller must ensure that the array-vector outlives the pointer this function returns.
262    /// Otherwise, it will end up pointing to garbage.
263    #[inline]
264    pub fn as_mut_ptr(&mut self) -> *mut T {
265        self.arr.as_mut_ptr() as *mut T
266    }
267
268    /// Extracts a slice of the entire array-vector.
269    #[inline]
270    pub fn as_slice(&self) -> &[T] {
271        unsafe { slice::from_raw_parts(self.as_ptr(), self.len.as_usize()) }
272    }
273
274    /// Extracts a mutable slice of the entire array-vector.
275    #[inline]
276    pub fn as_mut_slice(&mut self) -> &mut [T] {
277        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len.as_usize()) }
278    }
279
280    /// Returns the total number of elements the array-vector can hold.
281    ///
282    /// This is a convenience method. The capacity of the array-vector is known at compilation time
283    /// and can be also obtained via the [`CAPACITY`] associated constant.
284    ///
285    /// # Examples
286    ///
287    /// ```rust
288    /// # use cds::array_vec;
289    /// let mut v = array_vec![17; u64];
290    /// assert_eq!(v.capacity(), 17);
291    /// ```
292    ///
293    /// [`CAPACITY`]: ArrayVec::CAPACITY
294    #[inline]
295    pub fn capacity(&self) -> usize {
296        Self::CAPACITY
297    }
298
299    /// Returns the number of elements the array-vector can hold in addition to already held ones.
300    ///
301    /// Equivalent to `capacity() - len()`.
302    ///
303    /// # Examples
304    ///
305    /// ```rust
306    /// # use cds::array_vec;
307    /// let mut v = array_vec![2; u64];
308    /// assert_eq!(v.capacity(), 2);
309    /// assert_eq!(v.spare_capacity(), 2);
310    ///
311    /// v.push(1);
312    /// assert_eq!(v.capacity(), 2);
313    /// assert_eq!(v.spare_capacity(), 1);
314    /// ```
315    #[inline]
316    pub fn spare_capacity(&self) -> usize {
317        Self::CAPACITY - self.len.as_usize()
318    }
319
320    /// Checks if there is spare capacity in the array-vector.
321    ///
322    /// Equivalent to `len() < capacity()`, `spare_capacity() != 0` and `!is_full()`.
323    ///
324    /// # Examples
325    ///
326    /// ```rust
327    /// # use cds::array_vec;
328    /// let mut v = array_vec![2; u64];
329    /// assert_eq!(v.capacity(), 2);
330    /// assert_eq!(v.has_spare_capacity(), true);
331    ///
332    /// v.push(1);
333    /// v.push(2);
334    /// assert_eq!(v.has_spare_capacity(), false);
335    /// ```
336    #[inline]
337    pub fn has_spare_capacity(&self) -> bool {
338        self.len < Self::CAPACITY
339    }
340
341    /// Forces the length of the array-vector to `new_len`.
342    ///
343    /// Note that this method doesn't [`drop`] elements, which may lead to a resource leak if
344    /// `new_len < len()` and `T` has a custom [`Drop`] implementation. See [`truncate`] for a
345    /// method that handles array-vector truncation properly.
346    ///
347    /// # Safety
348    ///
349    /// - `new_len` must be less than or equal to the array-vector's [`CAPACITY`]
350    /// - the elements at `old_len..new_len` must be initialized
351    ///
352    /// [`CAPACITY`]: ArrayVec::CAPACITY
353    ///
354    /// # Panics
355    ///
356    /// This method uses debug assertions to verify that `new_len` is in bounds.
357    ///
358    /// [`drop`]: core::mem::drop
359    /// [`Drop`]: core::ops::Drop
360    /// [`truncate`]: ArrayVec::truncate
361    #[inline]
362    pub unsafe fn set_len(&mut self, new_len: usize) {
363        debug_assert!(new_len <= Self::CAPACITY);
364        self.len.set(new_len);
365    }
366
367    /// Appends an element to the back of the array-vector.
368    ///
369    /// # Panics
370    ///
371    /// This method panics if there is no spare capacity to accommodate the new element.
372    /// See [`try_push`] for a method that returns an error instead.
373    ///
374    /// # Examples
375    ///
376    /// ```rust
377    /// # use cds::array_vec;
378    /// let mut v = array_vec![2; u64];
379    /// v.push(1);
380    /// v.push(2);
381    /// ```
382    ///
383    /// [`push`] panics if there is no spare capacity:
384    ///
385    /// ```should_panic
386    /// # use cds::array_vec;
387    /// let mut v = array_vec![2; u64];
388    /// v.push(1);
389    /// v.push(2);
390    /// v.push(3);  // <-- this panics
391    /// ```
392    ///
393    /// [`try_push`]: ArrayVec::try_push
394    /// [`push`]: ArrayVec::push
395    #[inline]
396    pub fn push(&mut self, e: T) {
397        if self.len >= Self::CAPACITY {
398            panic!("insufficient capacity");
399        }
400        unsafe { self.push_unchecked(e) };
401    }
402
403    /// Tries to append an element to the back of the array-vector.
404    ///
405    /// Returns [`InsufficientCapacityError`] if there is no spare capacity to accommodate a new
406    /// element.
407    ///
408    /// This is a non-panic version of [`push`].
409    ///
410    /// # Examples
411    ///
412    /// ```rust
413    /// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityError};
414    /// let mut v = array_vec![2; u64];
415    /// assert!(v.try_push(1).is_ok());
416    /// assert!(v.try_push(2).is_ok());
417    /// assert!(matches!(v.try_push(3), Err(e) if e == InsufficientCapacityError));
418    /// assert_eq!(v, [1, 2]);
419    /// ```
420    ///
421    /// [`push`]: ArrayVec::push
422    #[inline]
423    pub fn try_push(&mut self, e: T) -> Result<(), InsufficientCapacityError> {
424        if self.len < Self::CAPACITY {
425            unsafe { self.push_unchecked(e) };
426            Ok(())
427        } else {
428            Err(InsufficientCapacityError {})
429        }
430    }
431
432    /// Tries to append an element to the back of the array-vector.
433    ///
434    /// Returns [`InsufficientCapacityErrorVal`] if there is no spare capacity to accommodate a new
435    /// element.
436    ///
437    /// The difference between this method and [`try_push`] is that in case of an error
438    /// [`try_push_val`] returns the element back to the caller.
439    ///
440    /// This is a non-panic version of [`push`].
441    ///
442    /// # Examples
443    /// ```rust
444    /// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityErrorVal};
445    /// let mut v = array_vec![2; u64];
446    /// assert_eq!(v, []);
447    ///
448    /// assert!(v.try_push_val(1).is_ok());
449    /// assert!(v.try_push_val(2).is_ok());
450    /// assert_eq!(v, [1, 2]);
451    ///
452    /// assert!(matches!(v.try_push_val(3), Err(InsufficientCapacityErrorVal(e)) if e == 3));
453    /// assert_eq!(v, [1, 2]);
454    /// ```
455    ///
456    /// [`try_push_val`]: ArrayVec::try_push_val
457    /// [`try_push`]: ArrayVec::try_push
458    /// [`push`]: ArrayVec::push
459    #[inline]
460    pub fn try_push_val(&mut self, value: T) -> Result<(), InsufficientCapacityErrorVal<T>> {
461        if self.len < Self::CAPACITY {
462            unsafe { self.push_unchecked(value) };
463            Ok(())
464        } else {
465            Err(InsufficientCapacityErrorVal(value))
466        }
467    }
468
469    /// Appends an element to the back of the array-vector without spare capacity check.
470    ///
471    /// This method is useful when spare capacity check is already done by the caller.
472    ///
473    /// # Safety
474    ///
475    /// The caller must ensure that the array-vector has spare capacity to accommodate a new
476    /// element.
477    ///
478    /// # Example
479    /// ```rust
480    /// # use cds::array_vec;
481    /// let mut a = array_vec![3; usize; 1];
482    /// while a.has_spare_capacity() {
483    ///     unsafe { a.push_unchecked(0); }
484    /// }
485    /// assert_eq!(a, [1, 0, 0]);
486    /// ```
487    #[inline]
488    pub unsafe fn push_unchecked(&mut self, value: T) {
489        let len = self.len();
490        self.as_mut_ptr().add(len).write(value);
491        self.set_len(len + 1);
492    }
493
494    /// Removes the last element from an array-vector and returns it, or [`None`] if it is empty.
495    ///
496    /// # Examples
497    ///
498    /// ```rust
499    /// # use cds::array_vec;
500    /// let mut a = array_vec![3; 10];
501    /// assert_eq!(a.pop(), Some(10));
502    /// assert_eq!(a.pop(), None);
503    /// ```
504    #[inline]
505    pub fn pop(&mut self) -> Option<T> {
506        if self.len > 0 {
507            unsafe { Some(self.pop_unchecked()) }
508        } else {
509            None
510        }
511    }
512
513    /// Removes the last element from array-vector and returns it without checking the length.
514    ///
515    /// # Safety
516    ///
517    /// The caller must ensure that the array-vector is not empty.
518    ///
519    /// # Examples
520    /// ```rust
521    /// # use cds::array_vec;
522    /// let mut a = array_vec![3; 11, 12];
523    /// if !a.is_empty() {
524    ///     unsafe {
525    ///         assert_eq!(a.pop_unchecked(), 12);
526    ///     }
527    /// }
528    /// ```
529    #[inline]
530    pub unsafe fn pop_unchecked(&mut self) -> T {
531        self.len -= 1;
532        let p = self.as_mut_ptr().add(self.len.as_usize());
533        let e = p.read();
534        SM::init(p, 1);
535        e
536    }
537
538    /// Clears the array-vector, dropping all values.
539    ///
540    /// # Examples
541    /// ```rust
542    /// # use cds::array_vec;
543    /// let mut a = array_vec![16; 1, 2, 3];
544    /// assert_eq!(a, [1, 2, 3]);
545    /// a.clear();
546    /// assert_eq!(a, []);
547    /// ```
548    #[inline]
549    pub fn clear(&mut self) {
550        self.truncate(0)
551    }
552
553    /// Shortens the array-vector, keeping the first `len` elements and dropping the rest.
554    ///
555    /// If `len` is greater than array-vector's current length, this has no effect.
556    ///
557    /// # Safety
558    ///
559    /// Spare memory policy is invoked only if all truncated elements drop successfully. I.e, if
560    /// any of the truncated elements panics during drop, spare memory policy isn't invoked
561    /// at all, including on successfully dropped elements.
562    ///
563    /// # Examples
564    /// ```rust
565    /// # use cds::array_vec;
566    /// let mut a = array_vec![8; 1, 2, 3];
567    /// assert_eq!(a, [1, 2, 3]);
568    /// a.truncate(1);
569    /// assert_eq!(a, [1]);
570    /// a.truncate(2);
571    /// assert_eq!(a, [1]);
572    /// ```
573    #[inline]
574    pub fn truncate(&mut self, len: usize) {
575        let my_len = self.len.as_usize();
576
577        if len < my_len {
578            unsafe {
579                // `drop` of any of the truncated slots may panic, which may trigger destruction
580                // of `self`. Thus, update `self.len` *before* calling `drop_in_place` to avoid
581                // a possible double-drop of a truncated slot.
582                self.set_len(len);
583
584                // create a slice of truncated slots
585                let s = slice::from_raw_parts_mut(self.as_mut_ptr().add(len), my_len - len);
586
587                // `drop_in_place` drops every slot in the slice. If one slot panics, it will first
588                // try to drop the rest and only then re-raise the panic.
589                // If more than one slot panic, the program aborts.
590                ptr::drop_in_place(s);
591
592                // TODO: invoke SM-policy on every successfully dropped element, even if one panics
593
594                // invoke spare memory policy
595                SM::init(s.as_mut_ptr(), s.len());
596            }
597        }
598    }
599
600    /// Returns an iterator over the slice.
601    ///
602    /// # Examples
603    ///
604    /// ```rust
605    /// # use cds::array_vec;
606    /// let v = array_vec![3; 1, 2];
607    /// let mut iterator = v.iter();
608    /// assert_eq!(iterator.next(), Some(&1));
609    /// assert_eq!(iterator.next(), Some(&2));
610    /// assert_eq!(iterator.next(), None);
611    /// ```
612    #[inline]
613    pub fn iter(&self) -> slice::Iter<'_, T> {
614        self.as_slice().iter()
615    }
616
617    /// Returns an iterator over the slice that allows modifying each value.
618    ///
619    /// # Examples
620    ///
621    /// ```rust
622    /// # use cds::array_vec;
623    /// let mut v = array_vec![3; 1, 2];
624    /// for e in v.iter_mut() {
625    ///     *e *= 2;
626    /// }
627    /// assert_eq!(v, [2, 4]);
628    /// ```
629    #[inline]
630    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
631        self.as_mut_slice().iter_mut()
632    }
633
634    /// Creates an array-vector from an iterator.
635    ///
636    /// Returns [`InsufficientCapacityError`] if the iterator yields more than [`CAPACITY`]
637    /// elements.
638    ///
639    /// [`CAPACITY`]: ArrayVec::CAPACITY
640    ///
641    /// # Examples
642    ///
643    /// ```rust
644    /// # use cds::{
645    /// #     arrayvec::{ArrayVec, errors::InsufficientCapacityError},
646    /// #     len::U8, mem::Uninitialized
647    /// # };
648    /// # use std::error::Error;
649    /// # fn example() -> Result<(), InsufficientCapacityError> {
650    /// type A = ArrayVec<usize, 3, U8, Uninitialized>;
651    /// let a = [1, 2, 3];
652    /// let v = A::try_from_iter(a.iter().filter(|x| **x % 2 == 0).cloned())?;
653    /// assert_eq!(v, [2]);
654    /// # Ok(())
655    /// # }
656    /// ```
657    #[inline]
658    pub fn try_from_iter<I>(iter: I) -> Result<Self, InsufficientCapacityError>
659    where
660        I: IntoIterator<Item = T>,
661    {
662        let mut tmp = Self::new();
663        let mut p = tmp.as_mut_ptr();
664
665        for e in iter {
666            if tmp.len >= Self::CAPACITY {
667                return Err(InsufficientCapacityError {});
668            }
669            unsafe {
670                p.write(e);
671                p = p.add(1);
672                tmp.len += 1;
673            }
674        }
675
676        Ok(tmp)
677    }
678
679    /// Inserts an element at position `index` within the vector, shifting all elements after it to
680    /// the right.
681    ///
682    /// Note that the worst case performance of this operation is O(n), because all elements of the
683    /// array may be shifted right. If order of elements is not needed to be preserved, use [`push`]
684    /// instead.
685    ///
686    /// # Panics
687    ///
688    /// This method panics if any of the following conditions is met:
689    /// - `index > len()`
690    /// - there is no spare capacity in the array-vector
691    ///
692    /// # Examples
693    ///
694    /// ```rust
695    /// # use cds::array_vec;
696    /// let mut v = array_vec![3; u64; 1, 2];
697    /// assert_eq!(v, [1, 2]);
698    /// v.insert(1, 0);
699    /// assert_eq!(v, [1, 0, 2]);
700    /// ```
701    /// [`insert`] panics if `index > len()`:
702    ///
703    /// ```should_panic
704    /// # use cds::array_vec;
705    /// let mut v = array_vec![3; u64; 1];
706    /// assert_eq!(v.len(), 1);
707    /// v.insert(2, 1);  // <-- this panics because 2 > v.len()
708    /// ```
709    ///
710    /// [`insert`] also panics if there is no spare capacity:
711    ///
712    /// ```should_panic
713    /// # use cds::array_vec;
714    /// let mut v = array_vec![2; u64; 1, 2];
715    /// assert_eq!(v.has_spare_capacity(), false);
716    /// v.insert(0, 0);  // <-- this panics
717    /// ```
718    ///
719    /// [`insert`]: ArrayVec::insert
720    /// [`push`]: ArrayVec::push
721    #[inline]
722    pub fn insert(&mut self, index: usize, element: T) {
723        self.try_insert(index, element).expect("cannot insert")
724    }
725
726    /// Tries to insert an element at position `index` within the vector, shifting all elements
727    /// after it to the right.
728    ///
729    /// Returns [`InsertError`] if there is no spare capacity in the array vector, or if `index` is
730    /// out of bounds.
731    ///
732    /// Note that in case of an error `value` is lost if it is not [`Copy`]. Use [`try_insert_val`]
733    /// to receive the element back in case of an error.
734    ///
735    /// Note that the worst case performance of this operation is O(n), because all elements of the
736    /// array may be shifted right. If order of elements is not needed to be preserved,
737    /// use [`try_push`] instead.
738    ///
739    /// This is a non-panic version of [`insert`].
740    ///
741    /// # Examples
742    ///
743    /// ```rust
744    /// # use cds::{array_vec, arrayvec::errors::InsertError};
745    /// let mut v = array_vec![3; u64; 1, 2];
746    /// assert!(matches!(v.try_insert(3, 3), Err(InsertError::InvalidIndex)));
747    ///
748    /// assert!(v.try_insert(0, 0).is_ok());
749    /// assert_eq!(v, [0, 1, 2]);
750    /// assert!(matches!(v.try_insert(1, 3), Err(InsertError::InsufficientCapacity)));
751    /// ```
752    ///
753    /// [`try_push`]: ArrayVec::try_push
754    /// [`try_insert_val`]: ArrayVec::try_insert_val
755    /// [`insert`]: ArrayVec::insert
756    #[inline]
757    pub fn try_insert(&mut self, index: usize, value: T) -> Result<(), InsertError> {
758        let len = self.len();
759        if index > len {
760            return Err(InsertError::InvalidIndex);
761        }
762        if len >= Self::CAPACITY {
763            return Err(InsertError::InsufficientCapacity);
764        }
765        unsafe {
766            self.insert_unchecked(index, value);
767        }
768        Ok(())
769    }
770
771    /// Tries to insert an element at position `index` within the array-vector,
772    /// shifting all elements after it to the right.
773    ///
774    /// Returns [`InsertErrorVal`] if there is no spare capacity in the array vector,
775    /// or if `index` is out of bounds.
776    ///
777    /// The difference between this method and [`try_insert`], is that in case of an error
778    /// [`try_insert_val`] returns the element back to the caller.
779    ///
780    /// Note that the worst case performance of this operation is O(n), because all elements of the
781    /// array may be shifted right. If order of elements is not needed to be preserved,
782    /// use [`try_push_val`] instead.
783    ///
784    /// This is a non-panic version of [`insert`].
785    ///
786    /// # Examples
787    ///
788    /// ```rust
789    /// # use cds::{array_vec, arrayvec::errors::InsertErrorVal};
790    /// let mut v = array_vec![3; u64; 1, 2];
791    /// assert!(matches!(
792    ///     v.try_insert_val(5, 3),
793    ///     Err(InsertErrorVal::InvalidIndex(v)) if v == 3
794    /// ));
795    /// assert_eq!(v, [1, 2]);
796    ///
797    /// assert!(v.try_insert_val(0, 0).is_ok());
798    /// assert_eq!(v, [0, 1, 2]);
799    ///
800    /// assert!(matches!(
801    ///     v.try_insert_val(1, 5),
802    ///     Err(InsertErrorVal::InsufficientCapacity(v)) if v == 5
803    /// ));
804    /// assert_eq!(v, [0, 1, 2]);
805    /// ```
806    ///
807    /// [`try_insert_val`]: ArrayVec::try_insert_val
808    /// [`try_insert`]: ArrayVec::try_insert
809    /// [`try_push_val`]: ArrayVec::try_push_val
810    /// [`insert`]: ArrayVec::insert
811    #[inline]
812    pub fn try_insert_val(&mut self, index: usize, value: T) -> Result<(), InsertErrorVal<T>> {
813        if index > self.len.as_usize() {
814            return Err(InsertErrorVal::InvalidIndex(value));
815        }
816        if self.len >= Self::CAPACITY {
817            return Err(InsertErrorVal::InsufficientCapacity(value));
818        }
819        unsafe {
820            self.insert_unchecked(index, value);
821        }
822        Ok(())
823    }
824
825    /// Inserts an element at position `index` within the vector, shifting all elements after it
826    /// to the right.
827    ///
828    /// # Safety
829    ///
830    /// The caller must ensure the following conditions:
831    /// - `index <= len()`
832    /// - there is spare capacity in the array-vector
833    ///
834    /// # Examples
835    ///
836    /// ```rust
837    /// # use cds::array_vec;
838    /// let mut v = array_vec![3; u64; 1, 2];
839    /// assert_eq!(v, [1, 2]);
840    /// assert_eq!(v.has_spare_capacity(), true);
841    ///
842    /// unsafe { v.insert_unchecked(0, 0) };
843    /// assert_eq!(v, [0, 1, 2]);
844    ///
845    /// v.pop();
846    /// assert_eq!(v, [0, 1]);
847    /// assert_eq!(v.has_spare_capacity(), true);
848    ///
849    /// unsafe { v.insert_unchecked(2, 2) };
850    /// assert_eq!(v, [0, 1, 2]);
851    /// ```
852    #[inline]
853    pub unsafe fn insert_unchecked(&mut self, index: usize, value: T) {
854        let len = self.len();
855        let p = self.as_mut_ptr().add(index);
856        ptr::copy(p, p.add(1), len - index);
857        p.write(value);
858        self.set_len(len + 1);
859    }
860
861    /// Removes and returns the element at position `index` within the vector, shifting all elements
862    /// after it to the left.
863    ///
864    /// Note: Because this shifts over the remaining elements, it has a worst-case performance of
865    /// O(n). If you don’t need the order of elements to be preserved, use [`swap_remove`] instead.
866    ///
867    /// # Panics
868    ///
869    /// This method panics if `index >= len()`.
870    ///
871    /// # Examples
872    ///
873    /// ```rust
874    /// # use cds::array_vec;
875    /// let mut v = array_vec![3; u64; 1, 2, 3];
876    /// assert_eq!(v, [1, 2, 3]);
877    /// assert_eq!(v.remove(1), 2);
878    /// assert_eq!(v, [1, 3]);
879    /// ```
880    ///
881    /// [`remove`] panics if `index` is out of bounds:
882    ///
883    /// ```should_panic
884    /// # use cds::array_vec;
885    /// let mut v = array_vec![2; u64; 1];
886    /// assert_eq!(v, [1]);
887    /// v.remove(1);  // <-- this panics because index=1 is out of bounds
888    /// ```
889    ///
890    /// [`swap_remove`]: ArrayVec::swap_remove
891    /// [`remove`]: ArrayVec::remove
892    #[inline]
893    pub fn remove(&mut self, index: usize) -> T {
894        if index >= self.len.as_usize() {
895            panic!("index is out of bounds [0, {}): {}", self.len, index);
896        }
897        unsafe { self.remove_unchecked(index) }
898    }
899
900    /// Tries to remove and return the element at position `index` within the vector, shifting all
901    /// elements after it to the left.
902    ///
903    /// Returns `None` if `index` is out of bounds.
904    ///
905    /// Note: Because this shifts over the remaining elements, it has a worst-case performance of
906    /// O(n). If you don’t need the order of elements to be preserved, use [`try_swap_remove`]
907    /// instead.
908    ///
909    /// This is a non-panic version of [`remove`].
910    ///
911    /// # Examples
912    ///
913    /// ```rust
914    /// # use cds::array_vec;
915    /// let mut v = array_vec![3; u64; 1, 2, 3];
916    /// assert_eq!(v.try_remove(3), None);
917    /// assert_eq!(v.try_remove(0), Some(1));
918    /// assert_eq!(v, [2, 3]);
919    /// ```
920    ///
921    /// [`remove`]: ArrayVec::remove
922    /// [`try_swap_remove`]: ArrayVec::try_swap_remove
923    #[inline]
924    pub fn try_remove(&mut self, index: usize) -> Option<T> {
925        if index < self.len.as_usize() {
926            unsafe { Some(self.remove_unchecked(index)) }
927        } else {
928            None
929        }
930    }
931
932    /// Removes and returns the element at position `index` within the array-vector, shifting all
933    /// elements after it to the left.
934    ///
935    /// Note: Because this shifts over the remaining elements, it has a worst-case performance of
936    /// O(n). If you don’t need the order of elements to be preserved, use [`swap_remove_unchecked`]
937    /// instead.
938    ///
939    /// This is the unchecked version of [`remove`].
940    ///
941    /// # Safety
942    ///
943    /// The caller must ensure that `index < len()`.
944    ///
945    /// # Examples
946    ///
947    /// ```rust
948    /// # use cds::array_vec;
949    /// let mut v = array_vec![3; u64; 1, 2, 3];
950    /// assert_eq!(v, [1, 2, 3]);
951    /// assert_eq!(unsafe { v.remove_unchecked(0) }, 1);
952    /// assert_eq!(v, [2, 3]);
953    /// ```
954    ///
955    /// [`remove`]: ArrayVec::remove
956    /// [`swap_remove_unchecked`]: ArrayVec::swap_remove_unchecked
957    #[inline]
958    pub unsafe fn remove_unchecked(&mut self, index: usize) -> T {
959        let base = self.as_mut_ptr();
960        let p = base.add(index);
961        let tmp = p.read();
962        ptr::copy(p.add(1), p, self.len.as_usize() - index - 1);
963        self.len -= 1;
964        SM::init(base.add(self.len.as_usize()), 1);
965        tmp
966    }
967
968    /// Removes an element at position `index` from the array-vector and returns it.
969    ///
970    /// The removed element is replaced by the last element of the array-vector.
971    ///
972    /// This does not preserve ordering, but is O(1).
973    ///
974    /// # Panics
975    ///
976    /// This method panics of `index` is out of bounds.
977    ///
978    /// # Examples
979    ///
980    /// ```rust
981    /// # use cds::array_vec;
982    /// let mut v = array_vec![4; u64; 1, 2, 3, 4];
983    /// assert_eq!(v.swap_remove(1), 2);
984    /// assert_eq!(v, [1, 4, 3]);
985    /// ```
986    #[inline]
987    pub fn swap_remove(&mut self, index: usize) -> T {
988        let len = self.len();
989        if index >= len {
990            panic!("index is out of bounds [0, {}): {}", len, index);
991        }
992
993        unsafe { self.swap_remove_unchecked(index) }
994    }
995
996    /// Tries to remove an element at position `index` from the array-vector and returns it.
997    ///
998    /// The removed element is replaced by the last element of the array-vector.
999    ///
1000    /// This does not preserve ordering, but is O(1).
1001    ///
1002    /// Returns `None` if `index` is out of bounds.
1003    ///
1004    /// This is a non-panic version of [`swap_remove`].
1005    ///
1006    /// # Examples
1007    ///
1008    /// ```rust
1009    /// # use cds::array_vec;
1010    /// let mut v = array_vec![3; u64; 1, 2, 3];
1011    /// assert_eq!(v.try_swap_remove(3), None);
1012    /// assert_eq!(v.try_swap_remove(0), Some(1));
1013    /// assert_eq!(v, [3, 2]);
1014    /// ```
1015    ///
1016    /// [`swap_remove`]: ArrayVec::swap_remove
1017    #[inline]
1018    pub fn try_swap_remove(&mut self, index: usize) -> Option<T> {
1019        if index < self.len.as_usize() {
1020            unsafe { Some(self.swap_remove_unchecked(index)) }
1021        } else {
1022            None
1023        }
1024    }
1025
1026    /// Removes an element at position `index` from the array-vector and returns it, without
1027    /// bounds check.
1028    ///
1029    /// The removed element is replaced by the last element of the array-vector.
1030    /// This does not preserve ordering, but is O(1).
1031    ///
1032    /// # Safety
1033    ///
1034    /// The caller must ensure that `index < len()`.
1035    ///
1036    /// # Example
1037    ///
1038    /// ```rust
1039    /// # use cds::array_vec;
1040    /// let mut v = array_vec![4; u64; 1, 2, 3, 4];
1041    /// assert_eq!(v, [1, 2, 3, 4]);
1042    /// assert_eq!(unsafe { v.swap_remove_unchecked(2) }, 3);
1043    /// assert_eq!(v, [1, 2, 4]);
1044    /// ```
1045    #[inline]
1046    pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
1047        let base = self.as_mut_ptr();
1048        let p = base.add(index);
1049        let value = p.read();
1050        self.len -= 1;
1051        let last = base.add(self.len.as_usize());
1052        ptr::copy(last, p, 1);
1053        SM::init(last, 1);
1054        value
1055    }
1056
1057    /// Creates a draining iterator that removes the specified range in the array-vector
1058    /// and yields the removed items.
1059    ///
1060    /// When the iterator is dropped, all elements in the range are removed from the array-vector,
1061    /// even if the iterator was not fully consumed.
1062    /// If the iterator is not dropped (with [`mem::forget`] for example),
1063    /// it is unspecified how many elements are removed.
1064    ///
1065    /// # Panics
1066    ///
1067    /// Panics if the starting point is greater than the end point or if the end point is greater
1068    /// than the length of the vector.
1069    ///
1070    /// # Examples
1071    ///
1072    /// ```rust
1073    /// # use cds::array_vec;
1074    /// let mut a = array_vec![5; usize; 1, 2, 3, 4, 5];
1075    /// assert_eq!(a, [1, 2, 3, 4, 5]);
1076    /// for (index, i) in a.drain(0..3).enumerate() {
1077    ///     assert_eq!(index + 1, i);
1078    /// }
1079    /// assert_eq!(a, [4, 5]);
1080    /// ```
1081    ///
1082    /// [`mem::forget`]: core::mem::forget
1083    #[inline]
1084    pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, L, SM, C>
1085    where
1086        R: RangeBounds<usize>,
1087    {
1088        let end = match range.end_bound() {
1089            Bound::Included(e) => e
1090                .checked_add(1)
1091                .unwrap_or_else(|| panic!("end bound overflows")),
1092            Bound::Excluded(e) => *e,
1093            Bound::Unbounded => self.len(),
1094        };
1095
1096        if end > self.len() {
1097            panic!("invalid end bound");
1098        }
1099
1100        let start = match range.start_bound() {
1101            Bound::Included(s) => *s,
1102            Bound::Excluded(s) => s
1103                .checked_add(1)
1104                .unwrap_or_else(|| panic!("start bound overflows")),
1105            Bound::Unbounded => 0,
1106        };
1107
1108        if start > end {
1109            panic!("invalid range");
1110        }
1111
1112        unsafe {
1113            let len = self.len();
1114            let (iter, tail, tail_len) = if start < end {
1115                // set `len` to reflect the head only
1116                self.set_len(start);
1117
1118                (
1119                    slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start).iter(),
1120                    L::new(end),
1121                    L::new(len - end),
1122                )
1123            } else {
1124                // empty drained range, mark it with an impossible combination of `tail/tail_len`
1125                ([].iter(), L::new(L::MAX), L::new(L::MAX))
1126            };
1127
1128            Drain {
1129                av: ptr::NonNull::new_unchecked(self),
1130                iter,
1131                tail,
1132                tail_len,
1133            }
1134        }
1135    }
1136
1137    /// Retains only the elements specified by the predicate.
1138    ///
1139    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
1140    /// This method operates in place, visiting each element exactly once in the original order,
1141    /// and preserves the order of the retained elements.
1142    ///
1143    /// # Examples
1144    ///
1145    /// ```rust
1146    /// # use cds::array_vec;
1147    /// let mut a = array_vec![5; 0, 1, 2, 3, 4];
1148    /// assert_eq!(a, [0, 1, 2, 3, 4]);
1149    /// a.retain(|e| (*e & 1) != 0);
1150    /// assert_eq!(a, [1, 3]);
1151    /// ```
1152    #[inline]
1153    pub fn retain<F>(&mut self, mut f: F)
1154    where
1155        F: FnMut(&T) -> bool,
1156    {
1157        self.retain_mut(|e| f(e))
1158    }
1159
1160    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
1161    ///
1162    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
1163    /// This method operates in place, visiting each element exactly once in the original order,
1164    /// and preserves the order of the retained elements.
1165    ///
1166    /// # Examples
1167    ///
1168    /// ```rust
1169    /// # use cds::array_vec;
1170    /// let mut a = array_vec![5; 0, 1, 2, 3, 4];
1171    /// assert_eq!(a, [0, 1, 2, 3, 4]);
1172    /// a.retain_mut(|e| if (*e & 1) == 0 {
1173    ///    *e *= *e;
1174    ///    true
1175    /// } else {
1176    ///    false
1177    /// });
1178    /// assert_eq!(a, [0, 4, 16]);
1179    /// ```
1180    #[inline]
1181    pub fn retain_mut<F>(&mut self, mut f: F)
1182    where
1183        F: FnMut(&mut T) -> bool,
1184    {
1185        let len = self.len();
1186
1187        // set `len` to zero, to avoid double-drop of deleted items.
1188        // `len` is restored by RetainGuard.
1189        unsafe { self.set_len(0) };
1190
1191        let mut g = RetainGuard {
1192            av: self,
1193            len,
1194            deleted: 0,
1195            processed: 0,
1196        };
1197
1198        unsafe {
1199            // no empty slot found yet, so there is nothing to move
1200            while g.processed < len {
1201                let item_mut_ref = &mut *g.av.as_mut_ptr().add(g.processed);
1202                if !f(item_mut_ref) {
1203                    // update counters before drop_in_place, as it may panic
1204                    g.processed += 1;
1205                    g.deleted += 1;
1206                    ptr::drop_in_place(item_mut_ref);
1207                    break;
1208                }
1209                g.processed += 1;
1210            }
1211
1212            // If there are items left to process, there must be an empty slot.
1213            // Move every retained slot to an empty one.
1214            while g.processed < len {
1215                let base_p = g.av.as_mut_ptr();
1216                let item_mut_ref = &mut *base_p.add(g.processed);
1217                if !f(item_mut_ref) {
1218                    // update counters before drop_in_place, as it may panic
1219                    g.processed += 1;
1220                    g.deleted += 1;
1221                    ptr::drop_in_place(item_mut_ref);
1222                    continue;
1223                } else {
1224                    ptr::copy_nonoverlapping(
1225                        item_mut_ref as *mut _,
1226                        base_p.add(g.processed - g.deleted),
1227                        1,
1228                    );
1229                }
1230                g.processed += 1;
1231            }
1232        }
1233    }
1234
1235    /// Returns the remaining spare capacity of the array-vector as a slice of `MaybeUninit<T>`.
1236    ///
1237    /// The returned slice can be used to fill the array-vector with data (e.g. by reading from a
1238    /// file) before marking the data as initialized using the [`set_len`] method.
1239    ///
1240    /// # Examples
1241    /// ```rust
1242    /// # use cds::array_vec;
1243    /// let mut a = array_vec![32; 1, 2];   // <-- an array-vector for IO of 32 elements
1244    /// assert_eq!(a, [1, 2]);
1245    ///
1246    /// let spare_capacity = a.spare_capacity_mut();
1247    /// spare_capacity[0].write(3);         // <-- read another 2 elements into the array-vector
1248    /// spare_capacity[1].write(4);
1249    ///
1250    /// unsafe { a.set_len(a.len() + 2) };  // <-- reflect the new size
1251    ///
1252    /// assert_eq!(a, [1, 2, 3, 4]);
1253    /// ```
1254    ///
1255    /// [`set_len`]: ArrayVec::set_len
1256    #[inline]
1257    pub fn spare_capacity_mut(&mut self) -> &mut [mem::MaybeUninit<T>] {
1258        unsafe {
1259            slice::from_raw_parts_mut(self.arr.as_mut_ptr().add(self.len()), self.spare_capacity())
1260        }
1261    }
1262
1263    /// Returns array-vector content as a slice of `T`, along with the remaining spare capacity of
1264    /// the array-vector as a slice of `MaybeUninit<T>`.
1265    ///
1266    /// The returned spare capacity slice can be used to fill the array-vector with data
1267    /// (e.g. by reading from a file) before marking the data as initialized using the [`set_len`]
1268    /// method.
1269    ///
1270    /// # Examples
1271    /// ```rust
1272    /// # use cds::array_vec;
1273    /// let mut a = array_vec![32; 1, 2];   // <-- an array-vector for IO of 32 elements
1274    ///
1275    /// let (init, spare) = a.split_at_spare_mut();
1276    /// assert_eq!(init, &[1, 2]);
1277    ///
1278    /// assert_eq!(spare.len(), 30);        // <-- read another 2 elements into the array-vector
1279    /// spare[0].write(3);
1280    /// spare[1].write(4);
1281    ///
1282    /// unsafe { a.set_len(a.len() + 2) };  // <-- reflect the new size
1283    ///
1284    /// assert_eq!(a, [1, 2, 3, 4]);
1285    /// ```
1286    ///
1287    /// [`set_len`]: ArrayVec::set_len
1288    #[inline]
1289    pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [mem::MaybeUninit<T>]) {
1290        let len = self.len();
1291        let spare_capacity = self.spare_capacity();
1292        let p = self.as_mut_ptr();
1293
1294        unsafe {
1295            (
1296                slice::from_raw_parts_mut(p, len),
1297                slice::from_raw_parts_mut(p.add(len) as *mut mem::MaybeUninit<T>, spare_capacity),
1298            )
1299        }
1300    }
1301
1302    /// Resizes the array-vector in-place so that `len` is equal to `new_len`.
1303    ///
1304    /// If `new_len` is greater than `len`, the array-vector is extended by the difference,
1305    /// with each additional slot filled with the result of calling the closure `f`.
1306    /// The return values from `f` will end up in the array-vector in the order they have been
1307    /// generated.
1308    ///
1309    /// If `new_len` is less than `len`, the array-vector is simply truncated.
1310    ///
1311    /// This method uses a closure to create new values on every push.
1312    /// If you’d rather [`Clone`] a given value, use [`try_resize`].
1313    /// If you want to use the [`Default`] trait to generate values, you can pass
1314    /// [`Default::default`] as the second argument.
1315    ///
1316    /// # Panics
1317    ///
1318    /// This method panics of `new_len > CAPACITY`. To avoid panic use [`try_resize_with`] which
1319    /// returns [`InsufficientCapacityError`] instead.
1320    ///
1321    /// # Examples
1322    ///
1323    /// ```rust
1324    /// # use cds::array_vec;
1325    /// let mut a = array_vec![5; 1];
1326    /// assert_eq!(a, [1]);
1327    ///
1328    /// let mut g = 1;
1329    ///
1330    /// a.resize_with(3, || { g += 1; g });
1331    /// assert_eq!(a, [1, 2, 3]);
1332    ///
1333    /// a.resize_with(5, || { g *= 2; g });
1334    /// assert_eq!(a, [1, 2, 3, 6, 12]);
1335    ///
1336    /// a.resize_with(1, || 0);
1337    /// assert_eq!(a, [1]);
1338    /// ```
1339    ///
1340    /// [`try_resize`]: ArrayVec::try_resize
1341    /// [`try_resize_with`]: ArrayVec::try_resize_with
1342    /// [`resize_with`]: ArrayVec::resize_with
1343    /// [`Clone`]: core::clone::Clone
1344    /// [`Default`]: core::default::Default
1345    /// [`Default::default`]: core::default::Default::default
1346    #[inline]
1347    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1348    where
1349        F: FnMut() -> T,
1350    {
1351        self.try_resize_with(new_len, f)
1352            .expect("insufficient capacity")
1353    }
1354
1355    /// Tries to resize the array-vector in-place so that `len` is equal to `new_len`.
1356    ///
1357    /// This is a non-panic version of [`resize_with`].
1358    ///
1359    /// If `new_len` is greater than `len`, the array-vector is extended by the difference,
1360    /// with each additional slot filled with the result of calling the closure `f`.
1361    /// The return values from `f` will end up in the array-vector in the order they have been
1362    /// generated.
1363    ///
1364    /// If `new_len` is less than `len`, the array-vector is simply truncated.
1365    ///
1366    /// This method uses a closure to create new values on every push.
1367    /// If you’d rather [`Clone`] a given value, use [`try_resize`].
1368    /// If you want to use the [`Default`] trait to generate values, you can pass
1369    /// [`Default::default`] as the second argument.
1370    ///
1371    /// # Examples
1372    ///
1373    /// ```rust
1374    /// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityError};
1375    /// # fn foo() -> Result<(), InsufficientCapacityError> {
1376    /// let mut a = array_vec![5;];
1377    /// assert_eq!(a, []);
1378    ///
1379    /// a.try_resize_with(3, Default::default)?;
1380    /// assert_eq!(a, [0, 0, 0]);
1381    ///
1382    /// let mut g = 2;
1383    /// a.try_resize_with(5, move || { g += 1; g })?;
1384    /// assert_eq!(a, [0, 0, 0, 3, 4]);
1385    ///
1386    /// a.try_resize_with(1, || 1)?;
1387    /// assert_eq!(a, [0]);
1388    ///
1389    /// assert!(matches!(a.try_resize_with(10, || 7), Err(e) if e == InsufficientCapacityError));
1390    /// # Ok(())
1391    /// # }
1392    /// # foo();
1393    /// ```
1394    ///
1395    /// [`try_resize`]: ArrayVec::try_resize
1396    /// [`resize_with`]: ArrayVec::resize_with
1397    /// [`Clone`]: core::clone::Clone
1398    /// [`Default`]: core::default::Default
1399    /// [`Default::default`]: core::default::Default::default
1400    #[inline]
1401    pub fn try_resize_with<F>(
1402        &mut self,
1403        new_len: usize,
1404        mut f: F,
1405    ) -> Result<(), InsufficientCapacityError>
1406    where
1407        F: FnMut() -> T,
1408    {
1409        if new_len > Self::CAPACITY {
1410            return Err(InsufficientCapacityError {});
1411        }
1412
1413        if new_len < self.len() {
1414            self.truncate(new_len);
1415            return Ok(());
1416        }
1417
1418        while self.len() < new_len {
1419            unsafe { self.push_unchecked(f()) };
1420        }
1421
1422        Ok(())
1423    }
1424}
1425
1426impl<T, L, SM, const C: usize> ArrayVec<T, C, L, SM>
1427where
1428    T: Clone,
1429    L: LengthType,
1430    SM: SpareMemoryPolicy<T>,
1431{
1432    /// Resizes the array-vector in-place so that `len` is equal to `new_len`.
1433    ///
1434    /// If `new_len` is greater than `len`, the array-vector is extended by the difference,
1435    /// with each additional slot filled with `value`. If `new_len` is less than `len`,
1436    /// the array-vector is simply truncated.
1437    ///
1438    /// If you need only to resize to a smaller size, use [`truncate`].
1439    ///
1440    /// # Panics
1441    ///
1442    /// This method panics if `new_len > CAPACITY`. To avoid panic use [`try_resize`] which
1443    /// returns [`InsufficientCapacityError`] instead.
1444    ///
1445    /// # Examples
1446    ///
1447    /// ```rust
1448    /// # use cds::array_vec;
1449    /// let mut a = array_vec![5;];
1450    /// assert_eq!(a, []);
1451    ///
1452    /// a.resize(2, 1);
1453    /// assert_eq!(a, [1, 1]);
1454    ///
1455    /// a.resize(4, 5);
1456    /// assert_eq!(a, [1, 1, 5, 5]);
1457    ///
1458    /// a.resize(1, 7);
1459    /// assert_eq!(a, [1]);
1460    /// ```
1461    ///
1462    /// [`truncate`]: ArrayVec::truncate
1463    /// [`try_resize`]: ArrayVec::try_resize
1464    #[inline]
1465    pub fn resize(&mut self, new_len: usize, value: T) {
1466        self.try_resize(new_len, value)
1467            .expect("insufficient capacity");
1468    }
1469
1470    /// Tries to resize the array-vector in-place so that `len` is equal to `new_len`.
1471    ///
1472    /// This method returns [`InsufficientCapacityError`] if `new_len > CAPACITY`.
1473    ///
1474    /// This is a non-panic version of [`resize`].
1475    ///
1476    /// If `new_len` is greater than `len`, the array-vector is extended by the difference,
1477    /// with each additional slot filled with `value`. If `new_len` is less than `len`,
1478    /// the array-vector is simply truncated.
1479    ///
1480    /// If you need only to resize to a smaller size, use [`truncate`].
1481    ///
1482    /// # Examples
1483    ///
1484    /// ```rust
1485    /// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityError};
1486    /// # fn foo() -> Result<(), InsufficientCapacityError> {
1487    /// let mut a = array_vec![5; 1];
1488    /// assert_eq!(a, [1]);
1489    ///
1490    /// a.try_resize(5, 7)?;
1491    /// assert_eq!(a, [1, 7, 7, 7, 7]);
1492    ///
1493    /// a.try_resize(2, 0)?;
1494    /// assert_eq!(a, [1, 7]);
1495    ///
1496    /// assert!(matches!(a.try_resize(10, 7), Err(e) if e == InsufficientCapacityError));
1497    /// # Ok(())
1498    /// # }
1499    /// # foo();
1500    /// ```
1501    ///
1502    /// [`truncate`]: ArrayVec::truncate
1503    /// [`resize`]: ArrayVec::resize
1504    pub fn try_resize(
1505        &mut self,
1506        new_len: usize,
1507        value: T,
1508    ) -> Result<(), InsufficientCapacityError> {
1509        if new_len > Self::CAPACITY {
1510            return Err(InsufficientCapacityError {});
1511        }
1512
1513        if new_len < self.len() {
1514            self.truncate(new_len);
1515            return Ok(());
1516        }
1517
1518        while self.len() < new_len {
1519            unsafe { self.push_unchecked(value.clone()) };
1520        }
1521
1522        Ok(())
1523    }
1524
1525    #[inline]
1526    fn _clone_from(&mut self, other: &Self) {
1527        unsafe {
1528            self._clone_from_unchecked(other);
1529        }
1530    }
1531
1532    #[inline]
1533    unsafe fn _clone_from_unchecked(&mut self, s: &[T]) {
1534        debug_assert!(self.is_empty());
1535        let mut p = self.as_mut_ptr();
1536        // Clone every element in source and append to the back of `self`.
1537        // Update `len` one-by-one, as `clone()` may panic and `self.drop()` may be implicitly
1538        // invoked. This way we drop only successfully written slots.
1539        for e in s {
1540            p.write(e.clone());
1541            p = p.add(1);
1542            self.len += 1;
1543        }
1544    }
1545}
1546
1547impl<T, L, SM, const C: usize> ArrayVec<T, C, L, SM>
1548where
1549    T: Copy,
1550    L: LengthType,
1551    SM: SpareMemoryPolicy<T>,
1552{
1553    /// Extends the array-vector by copying elements from a slice.
1554    ///
1555    /// This is optimized for [`Copy`] types, elements are copied bytewise.
1556    ///
1557    /// # Panics
1558    ///
1559    /// This method panics if there is no enough spare capacity to accommodate
1560    /// all elements from `s`. See [`try_copy_from_slice`] for a method that returns
1561    /// [`InsufficientCapacityError`] instead.
1562    ///
1563    /// [`try_copy_from_slice`]: ArrayVec::try_copy_from_slice
1564    ///
1565    /// # Examples
1566    /// ```rust
1567    /// # use cds::array_vec;
1568    /// let mut a = array_vec![5; 1, 2];
1569    /// assert_eq!(a, [1, 2]);
1570    /// a.copy_from_slice(&[3, 4]);
1571    /// assert_eq!(a, [1, 2, 3, 4]);
1572    /// ```
1573    /// ```should_panic
1574    /// # use cds::array_vec;
1575    /// let mut a = array_vec![3; 1, 2];
1576    /// a.copy_from_slice(&[3, 4]);  // <-- this panics as there is only one spare slot
1577    /// ```
1578    #[inline]
1579    pub fn copy_from_slice(&mut self, s: &[T]) {
1580        if self.len() + s.len() > Self::CAPACITY {
1581            panic!("insufficient capacity");
1582        }
1583        unsafe { self.copy_from_slice_unchecked(s) };
1584    }
1585
1586    /// Tries to extend the array-vector by copying elements from a slice.
1587    ///
1588    /// This is optimized for [`Copy`] types, elements are copied bytewise.
1589    ///
1590    /// This method is a non-panic version of [`copy_from_slice`].
1591    ///
1592    /// It returns [`InsufficientCapacityError`] if there is no enough spare capacity to accommodate
1593    /// all elements from `s`.
1594    ///
1595    /// [`copy_from_slice`]: ArrayVec::copy_from_slice
1596    ///
1597    /// # Examples
1598    /// ```rust
1599    /// # use cds::{array_vec, arrayvec::errors::InsufficientCapacityError};
1600    /// # fn foo() -> Result<(), InsufficientCapacityError> {
1601    /// let mut a = array_vec![5; 1, 2];
1602    /// assert_eq!(a, [1, 2]);
1603    /// a.try_copy_from_slice(&[1, 2])?;
1604    /// assert_eq!(a, [1, 2, 1, 2]);
1605    /// assert!(matches!(a.try_copy_from_slice(&[3, 4]), Err(e) if e == InsufficientCapacityError));
1606    /// # Ok(())
1607    /// # }
1608    /// # foo().unwrap();
1609    /// ```
1610    pub fn try_copy_from_slice(&mut self, s: &[T]) -> Result<(), InsufficientCapacityError> {
1611        if self.len() + s.len() > Self::CAPACITY {
1612            return Err(InsufficientCapacityError {});
1613        }
1614        unsafe { self.copy_from_slice_unchecked(s) };
1615        Ok(())
1616    }
1617
1618    /// Extends the array-vector by copying elements from a slice.
1619    ///
1620    /// This is optimized for [`Copy`] types, elements are copied bytewise.
1621    ///
1622    /// # Safety
1623    ///
1624    /// The caller must ensure that there is enough spare capacity to accommodate all elements
1625    /// from `s`.
1626    ///
1627    /// # Panics
1628    ///
1629    /// This method uses debug assertions to ensure that array-vector's capacity is not exceeded.
1630    ///
1631    /// # Examples
1632    /// ```rust
1633    /// # use cds::array_vec;
1634    /// let mut a = array_vec![5; 1, 2];
1635    /// assert_eq!(a, [1, 2]);
1636    /// unsafe { a.copy_from_slice_unchecked(&[1, 2]) };
1637    /// assert_eq!(a, [1, 2, 1, 2]);
1638    /// ```
1639    #[inline]
1640    pub unsafe fn copy_from_slice_unchecked(&mut self, s: &[T]) {
1641        // SAFETY: it is impossible that regions overlap
1642        // as `self` cannot be borrowed as both mutable and immutable
1643        ptr::copy_nonoverlapping(s.as_ptr(), self.as_mut_ptr().add(self.len()), s.len());
1644        self.len += s.len();
1645    }
1646}
1647
1648mod macros;
1649mod traits;
1650
1651#[cfg(test)]
1652mod test_arrayvec;