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;