/// A vector with a fixed capacity. /// /// The `ArrayVec` is a vector backed by a fixed size array. It keeps track of /// the number of initialized elements. The `ArrayVec<T, CAP>` is parameterized /// by `T` for the element type and `CAP` for the maximum capacity. /// /// `CAP` is of type `usize` but is range limited to `u32::MAX`; attempting to create larger /// arrayvecs with larger capacity will panic. /// /// The vector is a contiguous value (storing the elements inline) that you can store directly on /// the stack if needed. /// /// It offers a simple API but also dereferences to a slice, so that the full slice API is /// available. The ArrayVec can be converted into a by value iterator. #[repr(C)] pubstruct ArrayVec<T, const CAP: usize> {
len: LenUint, // the `len` first elements of the array are initialized
xs: [MaybeUninit<T>; CAP],
}
impl<T, const CAP: usize> Drop for ArrayVec<T, CAP> { fn drop(&mutself) { self.clear();
// MaybeUninit inhibits array's drop
}
}
macro_rules! panic_oob {
($method_name:expr, $index:expr, $len:expr) => {
panic!(concat!("ArrayVec::", $method_name, ": index {} is out of bounds in vector of length {}"),
$index, $len)
}
}
/// Create a new empty `ArrayVec`. /// /// The maximum capacity is given by the generic parameter `CAP`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 16>::new(); /// array.push(1); /// array.push(2); /// assert_eq!(&array[..], &[1, 2]); /// assert_eq!(array.capacity(), 16); /// ``` #[inline] #[track_caller] pubfn new() -> ArrayVec<T, CAP> {
assert_capacity_limit!(CAP); unsafe {
ArrayVec { xs: MaybeUninit::uninit().assume_init(), len: 0 }
}
}
/// Create a new empty `ArrayVec` (const fn). /// /// The maximum capacity is given by the generic parameter `CAP`. /// /// ``` /// use arrayvec::ArrayVec; /// /// static ARRAY: ArrayVec<u8, 1024> = ArrayVec::new_const(); /// ``` pubconstfn new_const() -> ArrayVec<T, CAP> {
assert_capacity_limit_const!(CAP);
ArrayVec { xs: MakeMaybeUninit::ARRAY, len: 0 }
}
/// Return the number of elements in the `ArrayVec`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// array.pop(); /// assert_eq!(array.len(), 2); /// ``` #[inline(always)] pubconstfn len(&self) -> usize { self.len as usize }
/// Returns whether the `ArrayVec` is empty. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1]); /// array.pop(); /// assert_eq!(array.is_empty(), true); /// ``` #[inline] pubconstfn is_empty(&self) -> bool { self.len() == 0 }
/// Return the capacity of the `ArrayVec`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let array = ArrayVec::from([1, 2, 3]); /// assert_eq!(array.capacity(), 3); /// ``` #[inline(always)] pubconstfn capacity(&self) -> usize { CAP }
/// Return true if the `ArrayVec` is completely filled to its capacity, false otherwise. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 1>::new(); /// assert!(!array.is_full()); /// array.push(1); /// assert!(array.is_full()); /// ``` pubconstfn is_full(&self) -> bool { self.len() == self.capacity() }
/// Returns the capacity left in the `ArrayVec`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// array.pop(); /// assert_eq!(array.remaining_capacity(), 1); /// ``` pubconstfn remaining_capacity(&self) -> usize { self.capacity() - self.len()
}
/// Push `element` to the end of the vector. /// /// ***Panics*** if the vector is already full. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// array.push(1); /// array.push(2); /// /// assert_eq!(&array[..], &[1, 2]); /// ``` #[track_caller] pubfn push(&mutself, element: T) {
ArrayVecImpl::push(self, element)
}
/// Push `element` to the end of the vector. /// /// Return `Ok` if the push succeeds, or return an error if the vector /// is already full. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// let push1 = array.try_push(1); /// let push2 = array.try_push(2); /// /// assert!(push1.is_ok()); /// assert!(push2.is_ok()); /// /// assert_eq!(&array[..], &[1, 2]); /// /// let overflow = array.try_push(3); /// /// assert!(overflow.is_err()); /// ``` pubfn try_push(&mutself, element: T) -> Result<(), CapacityError<T>> {
ArrayVecImpl::try_push(self, element)
}
/// Push `element` to the end of the vector without checking the capacity. /// /// It is up to the caller to ensure the capacity of the vector is /// sufficiently large. /// /// This method uses *debug assertions* to check that the arrayvec is not full. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// if array.len() + 2 <= array.capacity() { /// unsafe { /// array.push_unchecked(1); /// array.push_unchecked(2); /// } /// } /// /// assert_eq!(&array[..], &[1, 2]); /// ``` pubunsafefn push_unchecked(&mutself, element: T) {
ArrayVecImpl::push_unchecked(self, element)
}
/// Shortens the vector, keeping the first `len` elements and dropping /// the rest. /// /// If `len` is greater than the vector’s current length this has no /// effect. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3, 4, 5]); /// array.truncate(3); /// assert_eq!(&array[..], &[1, 2, 3]); /// array.truncate(4); /// assert_eq!(&array[..], &[1, 2, 3]); /// ``` pubfn truncate(&mutself, new_len: usize) {
ArrayVecImpl::truncate(self, new_len)
}
/// Remove all elements in the vector. pubfn clear(&mutself) {
ArrayVecImpl::clear(self)
}
/// Get pointer to where element at `index` would be unsafefn get_unchecked_ptr(&mutself, index: usize) -> *mut T { self.as_mut_ptr().add(index)
}
/// Insert `element` at position `index`. /// /// Shift up all elements after `index`. /// /// It is an error if the index is greater than the length or if the /// arrayvec is full. /// /// ***Panics*** if the array is full or the `index` is out of bounds. See /// `try_insert` for fallible version. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// array.insert(0, "x"); /// array.insert(0, "y"); /// assert_eq!(&array[..], &["y", "x"]); /// /// ``` #[track_caller] pubfn insert(&mutself, index: usize, element: T) { self.try_insert(index, element).unwrap()
}
/// Insert `element` at position `index`. /// /// Shift up all elements after `index`; the `index` must be less than /// or equal to the length. /// /// Returns an error if vector is already at full capacity. /// /// ***Panics*** `index` is out of bounds. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// assert!(array.try_insert(0, "x").is_ok()); /// assert!(array.try_insert(0, "y").is_ok()); /// assert!(array.try_insert(0, "z").is_err()); /// assert_eq!(&array[..], &["y", "x"]); /// /// ``` pubfn try_insert(&mutself, index: usize, element: T) -> Result<(), CapacityError<T>> { if index > self.len() {
panic_oob!("try_insert", index, self.len())
} ifself.len() == self.capacity() { return Err(CapacityError::new(element));
} let len = self.len();
// follows is just like Vec<T> unsafe { // infallible // The spot to put the new value
{ let p: *mut _ = self.get_unchecked_ptr(index); // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.)
ptr::copy(p, p.offset(1), len - index); // Write it in, overwriting the first copy of the `index`th // element.
ptr::write(p, element);
} self.set_len(len + 1);
}
Ok(())
}
/// Remove the last element in the vector and return it. /// /// Return `Some(` *element* `)` if the vector is non-empty, else `None`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::<_, 2>::new(); /// /// array.push(1); /// /// assert_eq!(array.pop(), Some(1)); /// assert_eq!(array.pop(), None); /// ``` pubfn pop(&mutself) -> Option<T> {
ArrayVecImpl::pop(self)
}
/// Remove the element at `index` and swap the last element into its place. /// /// This operation is O(1). /// /// Return the *element* if the index is in bounds, else panic. /// /// ***Panics*** if the `index` is out of bounds. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// assert_eq!(array.swap_remove(0), 1); /// assert_eq!(&array[..], &[3, 2]); /// /// assert_eq!(array.swap_remove(1), 2); /// assert_eq!(&array[..], &[3]); /// ``` pubfn swap_remove(&mutself, index: usize) -> T { self.swap_pop(index)
.unwrap_or_else(|| {
panic_oob!("swap_remove", index, self.len())
})
}
/// Remove the element at `index` and swap the last element into its place. /// /// This is a checked version of `.swap_remove`. /// This operation is O(1). /// /// Return `Some(` *element* `)` if the index is in bounds, else `None`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// assert_eq!(array.swap_pop(0), Some(1)); /// assert_eq!(&array[..], &[3, 2]); /// /// assert_eq!(array.swap_pop(10), None); /// ``` pubfn swap_pop(&mutself, index: usize) -> Option<T> { let len = self.len(); if index >= len { return None;
} self.swap(index, len - 1); self.pop()
}
/// Remove the element at `index` and shift down the following elements. /// /// The `index` must be strictly less than the length of the vector. /// /// ***Panics*** if the `index` is out of bounds. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// let removed_elt = array.remove(0); /// assert_eq!(removed_elt, 1); /// assert_eq!(&array[..], &[2, 3]); /// ``` pubfn remove(&mutself, index: usize) -> T { self.pop_at(index)
.unwrap_or_else(|| {
panic_oob!("remove", index, self.len())
})
}
/// Remove the element at `index` and shift down the following elements. /// /// This is a checked version of `.remove(index)`. Returns `None` if there /// is no element at `index`. Otherwise, return the element inside `Some`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// assert!(array.pop_at(0).is_some()); /// assert_eq!(&array[..], &[2, 3]); /// /// assert!(array.pop_at(2).is_none()); /// assert!(array.pop_at(10).is_none()); /// ``` pubfn pop_at(&mutself, index: usize) -> Option<T> { if index >= self.len() {
None
} else { self.drain(index..index + 1).next()
}
}
/// Retains only the elements specified by the predicate. /// /// In other words, remove all elements `e` such that `f(&mut e)` returns false. /// This method operates in place and preserves the order of the retained /// elements. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3, 4]); /// array.retain(|x| *x & 1 != 0 ); /// assert_eq!(&array[..], &[1, 3]); /// ``` pubfn retain<F>(&mutself, mut f: F) where F: FnMut(&mut T) -> bool
{ // Check the implementation of // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain // for safety arguments (especially regarding panics in f and when // dropping elements). Implementation closely mirrored here.
let original_len = self.len(); unsafe { self.set_len(0) };
// Stage 1: Nothing was deleted. while g.processed_len != original_len { if !process_one::<F, T, CAP, false>(&mut f, &>mut g) { break;
}
}
// Stage 2: Some elements were deleted. while g.processed_len != original_len {
process_one::<F, T, CAP, true>(&mut f, &mutg);
}
drop(g);
}
/// Set the vector’s length without dropping or moving out elements /// /// This method is `unsafe` because it changes the notion of the /// number of “valid” elements in the vector. Use with care. /// /// This method uses *debug assertions* to check that `length` is /// not greater than the capacity. pubunsafefn set_len(&mutself, length: usize) { // type invariant that capacity always fits in LenUint
debug_assert!(length <= self.capacity()); self.len = length as LenUint;
}
/// Copy all elements from the slice and append to the `ArrayVec`. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut vec: ArrayVec<usize, 10> = ArrayVec::new(); /// vec.push(1); /// vec.try_extend_from_slice(&[2, 3]).unwrap(); /// assert_eq!(&vec[..], &[1, 2, 3]); /// ``` /// /// # Errors /// /// This method will return an error if the capacity left (see /// [`remaining_capacity`]) is smaller then the length of the provided /// slice. /// /// [`remaining_capacity`]: #method.remaining_capacity pubfn try_extend_from_slice(&mutself, other: &[T]) -> Result<(), CapacityError> where T: Copy,
{ ifself.remaining_capacity() < other.len() { return Err(CapacityError::new(()));
}
let self_len = self.len(); let other_len = other.len();
/// Create a draining iterator that removes the specified range in the vector /// and yields the removed items from start to end. The element range is /// removed even if the iterator is not consumed until the end. /// /// Note: It is unspecified how many elements are removed from the vector, /// if the `Drain` value is leaked. /// /// **Panics** if the starting point is greater than the end point or if /// the end point is greater than the length of the vector. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut v1 = ArrayVec::from([1, 2, 3]); /// let v2: ArrayVec<_, 3> = v1.drain(0..2).collect(); /// assert_eq!(&v1[..], &[3]); /// assert_eq!(&v2[..], &[1, 2]); /// ``` pubfn drain<R>(&mutself, range: R) -> Drain<T, CAP> where R: RangeBounds<usize>
{ // Memory safety // // When the Drain is first created, it shortens the length of // the source vector to make sure no uninitialized or moved-from elements // are accessible at all if the Drain's destructor never gets to run. // // Drain will ptr::read out the values to remove. // When finished, remaining tail of the vec is copied back to cover // the hole, and the vector length is restored to the new length. // let len = self.len(); let start = match range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&i) => i,
Bound::Excluded(&i) => i.saturating_add(1),
}; let end = match range.end_bound() {
Bound::Excluded(&j) => j,
Bound::Included(&j) => j.saturating_add(1),
Bound::Unbounded => len,
}; self.drain_range(start, end)
}
fn drain_range(&mutself, start: usize, end: usize) -> Drain<T, CAP>
{ let len = self.len();
// bounds check happens here (before length is changed!) let range_slice: *const _ = &self[start..end];
// Calling `set_len` creates a fresh and thus unique mutable references, making all // older aliases we created invalid. So we cannot call that function. self.len = start as LenUint;
/// Return the inner fixed size array, if it is full to its capacity. /// /// Return an `Ok` value with the array if length equals capacity, /// return an `Err` with self otherwise. pubfn into_inner(self) -> Result<[T; CAP], Self> { ifself.len() < self.capacity() {
Err(self)
} else { unsafe { Ok(self.into_inner_unchecked()) }
}
}
/// Return the inner fixed size array. /// /// Safety: /// This operation is safe if and only if length equals capacity. pubunsafefn into_inner_unchecked(self) -> [T; CAP] {
debug_assert_eq!(self.len(), self.capacity()); let self_ = ManuallyDrop::new(self); let array = ptr::read(self_.as_ptr() as *const [T; CAP]);
array
}
/// Returns the ArrayVec, replacing the original with a new empty ArrayVec. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut v = ArrayVec::from([0, 1, 2, 3]); /// assert_eq!([0, 1, 2, 3], v.take().into_inner().unwrap()); /// assert!(v.is_empty()); /// ``` pubfn take(&mutself) -> Self {
mem::replace(self, Self::new())
}
/// Return a slice containing all elements of the vector. pubfn as_slice(&self) -> &[T] {
ArrayVecImpl::as_slice(self)
}
/// Return a mutable slice containing all elements of the vector. pubfn as_mut_slice(&mutself) -> &mut [T] {
ArrayVecImpl::as_mut_slice(self)
}
/// Return a raw pointer to the vector's buffer. pubfn as_ptr(&self) -> *const T {
ArrayVecImpl::as_ptr(self)
}
/// Return a raw mutable pointer to the vector's buffer. pubfn as_mut_ptr(&mutself) -> *mut T {
ArrayVecImpl::as_mut_ptr(self)
}
}
impl<T, const CAP: usize> ArrayVecImpl for ArrayVec<T, CAP> { type Item = T; const CAPACITY: usize = CAP;
/// Create an `ArrayVec` from an array. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 3); /// ``` impl<T, const CAP: usize> From<[T; CAP]> for ArrayVec<T, CAP> { #[track_caller] fn from(array: [T; CAP]) -> Self { let array = ManuallyDrop::new(array); letmut vec = <ArrayVec<T, CAP>>::new(); unsafe {
(&*array as *const [T; CAP] as *const [MaybeUninit<T>; CAP])
.copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<T>; CAP], 1);
vec.set_len(CAP);
}
vec
}
}
/// Try to create an `ArrayVec` from a slice. This will return an error if the slice was too big to /// fit. /// /// ``` /// use arrayvec::ArrayVec; /// use std::convert::TryInto as _; /// /// let array: ArrayVec<_, 4> = (&[1, 2, 3] as &[_]).try_into().unwrap(); /// assert_eq!(array.len(), 3); /// assert_eq!(array.capacity(), 4); /// ``` impl<T, const CAP: usize> std::convert::TryFrom<&[T]> for ArrayVec<T, CAP> where T: Clone,
{ type Error = CapacityError;
/// Iterate the `ArrayVec` with references to each element. /// /// ``` /// use arrayvec::ArrayVec; /// /// let array = ArrayVec::from([1, 2, 3]); /// /// for elt in &array { /// // ... /// } /// ``` impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec<T, CAP> { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter() }
}
/// Iterate the `ArrayVec` with mutable references to each element. /// /// ``` /// use arrayvec::ArrayVec; /// /// let mut array = ArrayVec::from([1, 2, 3]); /// /// for elt in &mut array { /// // ... /// } /// ``` impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec<T, CAP> { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() }
}
/// Iterate the `ArrayVec` with each element by value. /// /// The vector is consumed by this operation. /// /// ``` /// use arrayvec::ArrayVec; /// /// for elt in ArrayVec::from([1, 2, 3]) { /// // ... /// } /// ``` impl<T, const CAP: usize> IntoIterator for ArrayVec<T, CAP> { type Item = T; type IntoIter = IntoIter<T, CAP>; fn into_iter(self) -> IntoIter<T, CAP> {
IntoIter { index: 0, v: self, }
}
}
#[cfg(feature = "zeroize")] /// "Best efforts" zeroing of the `ArrayVec`'s buffer when the `zeroize` feature is enabled. /// /// The length is set to 0, and the buffer is dropped and zeroized. /// Cannot ensure that previous moves of the `ArrayVec` did not leave values on the stack. /// /// ``` /// use arrayvec::ArrayVec; /// use zeroize::Zeroize; /// let mut array = ArrayVec::from([1, 2, 3]); /// array.zeroize(); /// assert_eq!(array.len(), 0); /// let data = unsafe { core::slice::from_raw_parts(array.as_ptr(), array.capacity()) }; /// assert_eq!(data, [0, 0, 0]); /// ``` impl<Z: zeroize::Zeroize, const CAP: usize> zeroize::Zeroize for ArrayVec<Z, CAP> { fn zeroize(&mutself) { // Zeroize all the contained elements. self.iter_mut().zeroize(); // Drop all the elements and set the length to 0. self.clear(); // Zeroize the backing array. self.xs.zeroize();
}
}
/// By-value iterator for `ArrayVec`. pubstruct IntoIter<T, const CAP: usize> {
index: usize,
v: ArrayVec<T, CAP>,
} impl<T, const CAP: usize> IntoIter<T, CAP> { /// Returns the remaining items of this iterator as a slice. pubfn as_slice(&self) -> &[T] {
&self.v[self.index..]
}
/// Returns the remaining items of this iterator as a mutable slice. pubfn as_mut_slice(&mutself) -> &mut [T] {
&mutself.v[self.index..]
}
}
impl<T, const CAP: usize> Iterator for IntoIter<T, CAP> { type Item = T;
fn next(&mutself) -> Option<Self::Item> { ifself.index == self.v.len() {
None
} else { unsafe { let index = self.index; self.index = index + 1;
Some(ptr::read(self.v.get_unchecked_ptr(index)))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) { let len = self.v.len() - self.index;
(len, Some(len))
}
}
impl<T, const CAP: usize> ExactSizeIterator for IntoIter<T, CAP> { }
impl<T, const CAP: usize> Drop for IntoIter<T, CAP> { fn drop(&mutself) { // panic safety: Set length to 0 before dropping elements. let index = self.index; let len = self.v.len(); unsafe { self.v.set_len(0); let elements = slice::from_raw_parts_mut( self.v.get_unchecked_ptr(index),
len - index);
ptr::drop_in_place(elements);
}
}
}
impl<T, const CAP: usize> Clone for IntoIter<T, CAP> where T: Clone,
{ fn clone(&self) -> IntoIter<T, CAP> { letmut v = ArrayVec::new();
v.extend_from_slice(&self.v[self.index..]);
v.into_iter()
}
}
/// A draining iterator for `ArrayVec`. pubstruct Drain<'a, T: 'a, const CAP: usize> { /// Index of tail to preserve
tail_start: usize, /// Length of tail
tail_len: usize, /// Current remaining range to remove
iter: slice::Iter<'a, T>,
vec: *mut ArrayVec<T, CAP>,
}
impl<'a, T: 'a, const CAP: usize> Drop for Drain<'a, T, CAP> { fn drop(&mutself) { // len is currently 0 so panicking while dropping will not cause a double drop.
// exhaust self first whilelet Some(_) = self.next() { }
ifself.tail_len > 0 { unsafe { let source_vec = &mut *self.vec; // memmove back untouched tail, update to new length let start = source_vec.len(); let tail = self.tail_start; let ptr = source_vec.as_mut_ptr();
ptr::copy(ptr.add(tail), ptr.add(start), self.tail_len);
source_vec.set_len(start + self.tail_len);
}
}
}
}
impl<T, Data, F> Drop for ScopeExitGuard<T, Data, F> where F: FnMut(&Data, &mut T)
{ fn drop(&mutself) {
(self.f)(&self.data, &mutself.value)
}
}
/// Extend the `ArrayVec` with an iterator. /// /// ***Panics*** if extending the vector exceeds its capacity. impl<T, const CAP: usize> Extend<T> for ArrayVec<T, CAP> { /// Extend the `ArrayVec` with an iterator. /// /// ***Panics*** if extending the vector exceeds its capacity. #[track_caller] fn extend<I: IntoIterator<Item=T>>(&mutself, iter: I) { unsafe { self.extend_from_iter::<_, true>(iter)
}
}
}
impl<T, const CAP: usize> ArrayVec<T, CAP> { /// Extend the arrayvec from the iterable. /// /// ## Safety /// /// Unsafe because if CHECK is false, the length of the input is not checked. /// The caller must ensure the length of the input fits in the capacity. #[track_caller] pub(crate) unsafefn extend_from_iter<I, const CHECK: bool>(&mutself, iterable: I) where I: IntoIterator<Item = T>
{ let take = self.capacity() - self.len(); let len = self.len(); letmut ptr = raw_ptr_add(self.as_mut_ptr(), len); let end_ptr = raw_ptr_add(ptr, take); // Keep the length in a separate variable, write it back on scope // exit. To help the compiler with alias analysis and stuff. // We update the length to handle panic in the iteration of the // user's iterator, without dropping any elements on the floor. letmut guard = ScopeExitGuard {
value: &mutself.len,
data: len,
f: move |&len, self_len| {
**self_len = len as LenUint;
}
}; letmut iter = iterable.into_iter(); loop { iflet Some(elt) = iter.next() { if ptr == end_ptr && CHECK { extend_panic(); }
debug_assert_ne!(ptr, end_ptr); if mem::size_of::<T>() != 0 {
ptr.write(elt);
}
ptr = raw_ptr_add(ptr, 1);
guard.data += 1;
} else { return; // success
}
}
}
/// Extend the ArrayVec with clones of elements from the slice; /// the length of the slice must be <= the remaining capacity in the arrayvec. pub(crate) fn extend_from_slice(&mutself, slice: &[T]) where T: Clone
{ let take = self.capacity() - self.len();
debug_assert!(slice.len() <= take); unsafe { let slice = if take < slice.len() { &slice[..take] } else { slice }; self.extend_from_iter::<_, false>(slice.iter().cloned());
}
}
}
/// Rawptr add but uses arithmetic distance for ZST unsafefn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T { if mem::size_of::<T>() == 0 { // Special case for ZST
ptr.cast::<u8>().wrapping_add(offset).cast::<T>()
} else {
ptr.add(offset)
}
}
/// Create an `ArrayVec` from an iterator. /// /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. impl<T, const CAP: usize> iter::FromIterator<T> for ArrayVec<T, CAP> { /// Create an `ArrayVec` from an iterator. /// /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self { letmut array = ArrayVec::new();
array.extend(iter);
array
}
}
impl<T, const CAP: usize> Clone for ArrayVec<T, CAP> where T: Clone
{ fn clone(&self) -> Self { self.iter().cloned().collect()
}
fn clone_from(&mutself, rhs: &Self) { // recursive case for the common prefix let prefix = cmp::min(self.len(), rhs.len()); self[..prefix].clone_from_slice(&rhs[..prefix]);
if prefix < self.len() { // rhs was shorter self.truncate(prefix);
} else { let rhs_elems = &rhs[self.len()..]; self.extend_from_slice(rhs_elems);
}
}
}
impl<T, const CAP: usize> Ord for ArrayVec<T, CAP> where T: Ord { fn cmp(&self, other: &Self) -> cmp::Ordering {
(**self).cmp(other)
}
}
#[cfg(feature="std")] /// `Write` appends written data to the end of the vector. /// /// Requires `features="std"`. impl<const CAP: usize> io::Write for ArrayVec<u8, CAP> { fn write(&mutself, data: &[u8]) -> io::Result<usize> { let len = cmp::min(self.remaining_capacity(), data.len()); let _result = self.try_extend_from_slice(&data[..len]);
debug_assert!(_result.is_ok());
Ok(len)
} fn flush(&mutself) -> io::Result<()> { Ok(()) }
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.