mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 06:50:32 +00:00
2181 lines
63 KiB
Rust
2181 lines
63 KiB
Rust
//! A fixed capacity [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html).
|
||
|
||
use core::borrow;
|
||
use core::marker::PhantomData;
|
||
use core::{
|
||
cmp::Ordering,
|
||
fmt, hash,
|
||
mem::{self, ManuallyDrop, MaybeUninit},
|
||
ops::{self, Range, RangeBounds},
|
||
ptr::{self, NonNull},
|
||
slice,
|
||
};
|
||
|
||
use crate::CapacityError;
|
||
|
||
mod drain;
|
||
|
||
mod storage {
|
||
use core::mem::MaybeUninit;
|
||
|
||
use crate::{
|
||
binary_heap::{BinaryHeapInner, BinaryHeapView},
|
||
deque::{DequeInner, DequeView},
|
||
};
|
||
|
||
use super::{VecInner, VecView};
|
||
|
||
/// Trait defining how data for a container is stored.
|
||
///
|
||
/// There's two implementations available:
|
||
///
|
||
/// - [`OwnedVecStorage`]: stores the data in an array `[T; N]` whose size is known at compile time.
|
||
/// - [`ViewVecStorage`]: stores the data in an unsized `[T]`.
|
||
///
|
||
/// This allows [`Vec`] to be generic over either sized or unsized storage. The [`vec`](super)
|
||
/// module contains a [`VecInner`] struct that's generic on [`VecStorage`],
|
||
/// and two type aliases for convenience:
|
||
///
|
||
/// - [`Vec<T, N>`](crate::vec::Vec) = `VecInner<T, OwnedStorage<T, N>>`
|
||
/// - [`VecView<T>`](crate::vec::VecView) = `VecInner<T, ViewStorage<T>>`
|
||
///
|
||
/// `Vec` can be unsized into `VecView`, either by unsizing coercions such as `&mut Vec -> &mut VecView` or
|
||
/// `Box<Vec> -> Box<VecView>`, or explicitly with [`.as_view()`](crate::vec::Vec::as_view) or [`.as_mut_view()`](crate::vec::Vec::as_mut_view).
|
||
///
|
||
/// This trait is sealed, so you cannot implement it for your own types. You can only use
|
||
/// the implementations provided by this crate.
|
||
///
|
||
/// [`VecInner`]: super::VecInner
|
||
/// [`Vec`]: super::Vec
|
||
/// [`VecView`]: super::VecView
|
||
#[allow(private_bounds)]
|
||
pub trait VecStorage<T>: VecSealedStorage<T> {}
|
||
|
||
pub trait VecSealedStorage<T> {
|
||
// part of the sealed trait so that no trait is publicly implemented by `OwnedVecStorage` besides `Storage`
|
||
fn borrow(&self) -> &[MaybeUninit<T>];
|
||
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>];
|
||
|
||
fn as_vec_view(this: &VecInner<T, Self>) -> &VecView<T>
|
||
where
|
||
Self: VecStorage<T>;
|
||
fn as_vec_mut_view(this: &mut VecInner<T, Self>) -> &mut VecView<T>
|
||
where
|
||
Self: VecStorage<T>;
|
||
|
||
fn as_binary_heap_view<K>(this: &BinaryHeapInner<T, K, Self>) -> &BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>;
|
||
fn as_binary_heap_mut_view<K>(
|
||
this: &mut BinaryHeapInner<T, K, Self>,
|
||
) -> &mut BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>;
|
||
|
||
fn as_deque_view(this: &DequeInner<T, Self>) -> &DequeView<T>
|
||
where
|
||
Self: VecStorage<T>;
|
||
fn as_deque_mut_view(this: &mut DequeInner<T, Self>) -> &mut DequeView<T>
|
||
where
|
||
Self: VecStorage<T>;
|
||
}
|
||
|
||
// One sealed layer of indirection to hide the internal details (The MaybeUninit).
|
||
pub struct VecStorageInner<T: ?Sized> {
|
||
pub(crate) buffer: T,
|
||
}
|
||
|
||
/// Implementation of [`VecStorage`] that stores the data in an array `[T; N]` whose size is known at compile time.
|
||
pub type OwnedVecStorage<T, const N: usize> = VecStorageInner<[MaybeUninit<T>; N]>;
|
||
/// Implementation of [`VecStorage`] that stores the data in an unsized `[T]`.
|
||
pub type ViewVecStorage<T> = VecStorageInner<[MaybeUninit<T>]>;
|
||
|
||
impl<T, const N: usize> VecSealedStorage<T> for OwnedVecStorage<T, N> {
|
||
fn borrow(&self) -> &[MaybeUninit<T>] {
|
||
&self.buffer
|
||
}
|
||
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
|
||
&mut self.buffer
|
||
}
|
||
|
||
fn as_vec_view(this: &VecInner<T, Self>) -> &VecView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_vec_mut_view(this: &mut VecInner<T, Self>) -> &mut VecView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
|
||
fn as_binary_heap_view<K>(this: &BinaryHeapInner<T, K, Self>) -> &BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_binary_heap_mut_view<K>(
|
||
this: &mut BinaryHeapInner<T, K, Self>,
|
||
) -> &mut BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_deque_view(this: &DequeInner<T, Self>) -> &DequeView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_deque_mut_view(this: &mut DequeInner<T, Self>) -> &mut DequeView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
}
|
||
impl<T, const N: usize> VecStorage<T> for OwnedVecStorage<T, N> {}
|
||
|
||
impl<T> VecSealedStorage<T> for ViewVecStorage<T> {
|
||
fn borrow(&self) -> &[MaybeUninit<T>] {
|
||
&self.buffer
|
||
}
|
||
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
|
||
&mut self.buffer
|
||
}
|
||
|
||
fn as_vec_view(this: &VecInner<T, Self>) -> &VecView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_vec_mut_view(this: &mut VecInner<T, Self>) -> &mut VecView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
|
||
fn as_binary_heap_view<K>(this: &BinaryHeapInner<T, K, Self>) -> &BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_binary_heap_mut_view<K>(
|
||
this: &mut BinaryHeapInner<T, K, Self>,
|
||
) -> &mut BinaryHeapView<T, K>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_deque_view(this: &DequeInner<T, Self>) -> &DequeView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
fn as_deque_mut_view(this: &mut DequeInner<T, Self>) -> &mut DequeView<T>
|
||
where
|
||
Self: VecStorage<T>,
|
||
{
|
||
this
|
||
}
|
||
}
|
||
impl<T> VecStorage<T> for ViewVecStorage<T> {}
|
||
}
|
||
pub use storage::{OwnedVecStorage, VecStorage, ViewVecStorage};
|
||
|
||
pub(crate) use storage::VecStorageInner;
|
||
|
||
pub use drain::Drain;
|
||
|
||
/// Base struct for [`Vec`] and [`VecView`], generic over the [`VecStorage`].
|
||
///
|
||
/// In most cases you should use [`Vec`] or [`VecView`] directly. Only use this
|
||
/// struct if you want to write code that's generic over both.
|
||
pub struct VecInner<T, S: VecStorage<T> + ?Sized> {
|
||
phantom: PhantomData<T>,
|
||
len: usize,
|
||
buffer: S,
|
||
}
|
||
|
||
/// A fixed capacity [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html).
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// // A vector with a fixed capacity of 8 elements allocated on the stack
|
||
/// let mut vec = Vec::<_, 8>::new();
|
||
/// vec.push(1).unwrap();
|
||
/// vec.push(2).unwrap();
|
||
///
|
||
/// assert_eq!(vec.len(), 2);
|
||
/// assert_eq!(vec[0], 1);
|
||
///
|
||
/// assert_eq!(vec.pop(), Some(2));
|
||
/// assert_eq!(vec.len(), 1);
|
||
///
|
||
/// vec[0] = 7;
|
||
/// assert_eq!(vec[0], 7);
|
||
///
|
||
/// vec.extend([1, 2, 3].iter().cloned());
|
||
///
|
||
/// for x in &vec {
|
||
/// println!("{}", x);
|
||
/// }
|
||
/// assert_eq!(*vec, [7, 1, 2, 3]);
|
||
/// ```
|
||
///
|
||
/// In some cases, the const-generic might be cumbersome. `Vec` can coerce into a [`VecView`] to remove the need for the const-generic:
|
||
///
|
||
/// ```rust
|
||
/// use heapless::{Vec, VecView};
|
||
///
|
||
/// let vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &VecView<_> = &vec;
|
||
/// ```
|
||
pub type Vec<T, const N: usize> = VecInner<T, OwnedVecStorage<T, N>>;
|
||
|
||
/// A [`Vec`] with dynamic capacity
|
||
///
|
||
/// [`Vec`] coerces to `VecView`. `VecView` is `!Sized`, meaning it can only ever be used by reference.
|
||
///
|
||
/// Unlike [`Vec`], `VecView` does not have an `N` const-generic parameter.
|
||
/// This has the ergonomic advantage of making it possible to use functions without needing to know at
|
||
/// compile-time the size of the buffers used, for example for use in `dyn` traits.
|
||
///
|
||
/// `VecView<T>` is to `Vec<T, N>` what `[T]` is to `[T; N]`.
|
||
///
|
||
/// ```rust
|
||
/// use heapless::{Vec, VecView};
|
||
///
|
||
/// let mut vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &VecView<_> = &vec;
|
||
/// assert_eq!(view, &[1, 2, 3, 4]);
|
||
///
|
||
/// let mut_view: &mut VecView<_> = &mut vec;
|
||
/// mut_view.push(5);
|
||
/// assert_eq!(vec, [1, 2, 3, 4, 5]);
|
||
/// ```
|
||
pub type VecView<T> = VecInner<T, ViewVecStorage<T>>;
|
||
|
||
impl<T, const N: usize> Vec<T, N> {
|
||
const ELEM: MaybeUninit<T> = MaybeUninit::uninit();
|
||
const INIT: [MaybeUninit<T>; N] = [Self::ELEM; N]; // important for optimization of `new`
|
||
|
||
/// Constructs a new, empty vector with a fixed capacity of `N`
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// // allocate the vector on the stack
|
||
/// let mut x: Vec<u8, 16> = Vec::new();
|
||
///
|
||
/// // allocate the vector in a static variable
|
||
/// static mut X: Vec<u8, 16> = Vec::new();
|
||
/// ```
|
||
pub const fn new() -> Self {
|
||
Self {
|
||
phantom: PhantomData,
|
||
len: 0,
|
||
buffer: VecStorageInner { buffer: Self::INIT },
|
||
}
|
||
}
|
||
|
||
/// Constructs a new vector with a fixed capacity of `N` and fills it
|
||
/// with the provided slice.
|
||
///
|
||
/// This is equivalent to the following code:
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut v: Vec<u8, 16> = Vec::new();
|
||
/// v.extend_from_slice(&[1, 2, 3]).unwrap();
|
||
/// ```
|
||
pub fn from_slice(other: &[T]) -> Result<Self, CapacityError>
|
||
where
|
||
T: Clone,
|
||
{
|
||
let mut v = Self::new();
|
||
v.extend_from_slice(other)?;
|
||
Ok(v)
|
||
}
|
||
|
||
/// Constructs a new vector with a fixed capacity of `N`, initializing
|
||
/// it with the provided array.
|
||
///
|
||
/// The length of the provided array, `M` may be equal to _or_ less than
|
||
/// the capacity of the vector, `N`.
|
||
///
|
||
/// If the length of the provided array is greater than the capacity of the
|
||
/// vector a compile-time error will be produced.
|
||
pub fn from_array<const M: usize>(src: [T; M]) -> Self {
|
||
const {
|
||
assert!(N >= M);
|
||
}
|
||
|
||
// We've got to copy `src`, but we're functionally moving it. Don't run
|
||
// any Drop code for T.
|
||
let src = ManuallyDrop::new(src);
|
||
|
||
if N == M {
|
||
Self {
|
||
phantom: PhantomData,
|
||
len: N,
|
||
// NOTE(unsafe) ManuallyDrop<[T; M]> and [MaybeUninit<T>; N]
|
||
// have the same layout when N == M.
|
||
buffer: unsafe { mem::transmute_copy(&src) },
|
||
}
|
||
} else {
|
||
let mut v = Self::new();
|
||
|
||
for (src_elem, dst_elem) in src.iter().zip(v.buffer.buffer.iter_mut()) {
|
||
// NOTE(unsafe) src element is not going to drop as src itself
|
||
// is wrapped in a ManuallyDrop.
|
||
dst_elem.write(unsafe { ptr::read(src_elem) });
|
||
}
|
||
|
||
v.len = M;
|
||
v
|
||
}
|
||
}
|
||
|
||
/// Returns the contents of the vector as an array of length `M` if the length
|
||
/// of the vector is exactly `M`, otherwise returns `Err(self)`.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
/// let buffer: Vec<u8, 42> = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap();
|
||
/// let array: [u8; 5] = buffer.into_array().unwrap();
|
||
/// assert_eq!(array, [1, 2, 3, 5, 8]);
|
||
/// ```
|
||
pub fn into_array<const M: usize>(self) -> Result<[T; M], Self> {
|
||
if self.len() == M {
|
||
// This is how the unstable `MaybeUninit::array_assume_init` method does it
|
||
let array = unsafe { (core::ptr::from_ref(&self.buffer).cast::<[T; M]>()).read() };
|
||
|
||
// We don't want `self`'s destructor to be called because that would drop all the
|
||
// items in the array
|
||
core::mem::forget(self);
|
||
|
||
Ok(array)
|
||
} else {
|
||
Err(self)
|
||
}
|
||
}
|
||
|
||
/// Clones a vec into a new vec
|
||
pub(crate) fn clone(&self) -> Self
|
||
where
|
||
T: Clone,
|
||
{
|
||
let mut new = Self::new();
|
||
// avoid `extend_from_slice` as that introduces a runtime check/panicking branch
|
||
for elem in self {
|
||
unsafe {
|
||
new.push_unchecked(elem.clone());
|
||
}
|
||
}
|
||
new
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> VecInner<T, S> {
|
||
/// Removes the specified range from the vector in bulk, returning all
|
||
/// removed elements as an iterator. If the iterator is dropped before
|
||
/// being fully consumed, it drops the remaining removed elements.
|
||
///
|
||
/// The returned iterator keeps a mutable borrow on the vector to optimize
|
||
/// its implementation.
|
||
///
|
||
/// # Panics
|
||
///
|
||
/// Panics if the starting point is greater than the end point or if
|
||
/// the end point is greater than the length of the vector.
|
||
///
|
||
/// # Leaking
|
||
///
|
||
/// If the returned iterator goes out of scope without being dropped (due to
|
||
/// [`mem::forget`], for example), the vector may have lost and leaked
|
||
/// elements arbitrarily, including elements outside the range.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut v = Vec::<_, 8>::from_array([1, 2, 3]);
|
||
/// let u: Vec<_, 8> = v.drain(1..).collect();
|
||
/// assert_eq!(v, &[1]);
|
||
/// assert_eq!(u, &[2, 3]);
|
||
///
|
||
/// // A full range clears the vector, like `clear()` does.
|
||
/// v.drain(..);
|
||
/// assert_eq!(v, &[]);
|
||
/// ```
|
||
pub fn drain<R>(&mut self, range: R) -> Drain<'_, T>
|
||
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 Range { start, end } = crate::slice::range(range, ..len);
|
||
|
||
unsafe {
|
||
// Set `self.vec` length's to `start`, to be safe in case `Drain` is leaked.
|
||
self.set_len(start);
|
||
let vec = NonNull::from(self.as_mut_view());
|
||
let range_slice = slice::from_raw_parts(vec.as_ref().as_ptr().add(start), end - start);
|
||
Drain {
|
||
tail_start: end,
|
||
tail_len: len - end,
|
||
iter: range_slice.iter(),
|
||
vec,
|
||
}
|
||
}
|
||
}
|
||
|
||
/// Get a reference to the `Vec`, erasing the `N` const-generic.
|
||
///
|
||
///
|
||
/// ```rust
|
||
/// # use heapless::{Vec, VecView};
|
||
/// let vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &VecView<u8> = vec.as_view();
|
||
/// ```
|
||
///
|
||
/// It is often preferable to do the same through type coerction, since `Vec<T, N>` implements `Unsize<VecView<T>>`:
|
||
///
|
||
/// ```rust
|
||
/// # use heapless::{Vec, VecView};
|
||
/// let vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &VecView<u8> = &vec;
|
||
/// ```
|
||
#[inline]
|
||
pub fn as_view(&self) -> &VecView<T> {
|
||
S::as_vec_view(self)
|
||
}
|
||
|
||
/// Get a mutable reference to the `Vec`, erasing the `N` const-generic.
|
||
///
|
||
/// ```rust
|
||
/// # use heapless::{Vec, VecView};
|
||
/// let mut vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &mut VecView<u8> = vec.as_mut_view();
|
||
/// ```
|
||
///
|
||
/// It is often preferable to do the same through type coerction, since `Vec<T, N>` implements `Unsize<VecView<T>>`:
|
||
///
|
||
/// ```rust
|
||
/// # use heapless::{Vec, VecView};
|
||
/// let mut vec: Vec<u8, 10> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// let view: &mut VecView<u8> = &mut vec;
|
||
/// ```
|
||
#[inline]
|
||
pub fn as_mut_view(&mut self) -> &mut VecView<T> {
|
||
S::as_vec_mut_view(self)
|
||
}
|
||
|
||
/// Returns a raw pointer to the vector’s buffer.
|
||
pub fn as_ptr(&self) -> *const T {
|
||
self.buffer.borrow().as_ptr().cast::<T>()
|
||
}
|
||
|
||
/// Returns a raw pointer to the vector’s buffer, which may be mutated through.
|
||
pub fn as_mut_ptr(&mut self) -> *mut T {
|
||
self.buffer.borrow_mut().as_mut_ptr().cast::<T>()
|
||
}
|
||
|
||
/// Extracts a slice containing the entire vector.
|
||
///
|
||
/// Equivalent to `&s[..]`.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
/// let buffer: Vec<u8, 5> = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap();
|
||
/// assert_eq!(buffer.as_slice(), &[1, 2, 3, 5, 8]);
|
||
/// ```
|
||
pub fn as_slice(&self) -> &[T] {
|
||
// NOTE(unsafe) avoid bound checks in the slicing operation
|
||
// &buffer[..self.len]
|
||
unsafe { slice::from_raw_parts(self.buffer.borrow().as_ptr().cast::<T>(), self.len) }
|
||
}
|
||
|
||
/// Extracts a mutable slice containing the entire vector.
|
||
///
|
||
/// Equivalent to `&mut s[..]`.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
/// let mut buffer: Vec<u8, 5> = Vec::from_slice(&[1, 2, 3, 5, 8]).unwrap();
|
||
/// let buffer_slice = buffer.as_mut_slice();
|
||
/// buffer_slice[0] = 9;
|
||
/// assert_eq!(buffer.as_slice(), &[9, 2, 3, 5, 8]);
|
||
/// ```
|
||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||
// NOTE(unsafe) avoid bound checks in the slicing operation
|
||
// &mut buffer[..self.len]
|
||
unsafe {
|
||
slice::from_raw_parts_mut(self.buffer.borrow_mut().as_mut_ptr().cast::<T>(), self.len)
|
||
}
|
||
}
|
||
|
||
/// Returns the maximum number of elements the vector can hold.
|
||
pub fn capacity(&self) -> usize {
|
||
self.buffer.borrow().len()
|
||
}
|
||
|
||
/// Clears the vector, removing all values.
|
||
pub fn clear(&mut self) {
|
||
self.truncate(0);
|
||
}
|
||
|
||
/// Extends the vec from an iterator.
|
||
///
|
||
/// # Panic
|
||
///
|
||
/// Panics if the vec cannot hold all elements of the iterator.
|
||
pub fn extend<I>(&mut self, iter: I)
|
||
where
|
||
I: IntoIterator<Item = T>,
|
||
{
|
||
for elem in iter {
|
||
self.push(elem).ok().unwrap();
|
||
}
|
||
}
|
||
|
||
/// Clones and appends all elements in a slice to the `Vec`.
|
||
///
|
||
/// Iterates over the slice `other`, clones each element, and then appends
|
||
/// it to this `Vec`. The `other` vector is traversed in-order.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec = Vec::<u8, 8>::new();
|
||
/// vec.push(1).unwrap();
|
||
/// vec.extend_from_slice(&[2, 3, 4]).unwrap();
|
||
/// assert_eq!(*vec, [1, 2, 3, 4]);
|
||
/// ```
|
||
pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError>
|
||
where
|
||
T: Clone,
|
||
{
|
||
pub fn extend_from_slice_inner<T>(
|
||
len: &mut usize,
|
||
buf: &mut [MaybeUninit<T>],
|
||
other: &[T],
|
||
) -> Result<(), CapacityError>
|
||
where
|
||
T: Clone,
|
||
{
|
||
if *len + other.len() > buf.len() {
|
||
// won't fit in the `Vec`; don't modify anything and return an error
|
||
Err(CapacityError)
|
||
} else {
|
||
for elem in other {
|
||
unsafe { *buf.get_unchecked_mut(*len) = MaybeUninit::new(elem.clone()) }
|
||
*len += 1;
|
||
}
|
||
Ok(())
|
||
}
|
||
}
|
||
|
||
extend_from_slice_inner(&mut self.len, self.buffer.borrow_mut(), other)
|
||
}
|
||
|
||
/// Removes the last element from a vector and returns it, or `None` if it's empty
|
||
pub fn pop(&mut self) -> Option<T> {
|
||
if self.len != 0 {
|
||
Some(unsafe { self.pop_unchecked() })
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
|
||
/// Appends an `item` to the back of the collection
|
||
///
|
||
/// Returns back the `item` if the vector is full.
|
||
pub fn push(&mut self, item: T) -> Result<(), T> {
|
||
if self.len < self.capacity() {
|
||
unsafe { self.push_unchecked(item) }
|
||
Ok(())
|
||
} else {
|
||
Err(item)
|
||
}
|
||
}
|
||
|
||
/// Removes the last element from a vector and returns it
|
||
///
|
||
/// # Safety
|
||
///
|
||
/// This assumes the vec to have at least one element.
|
||
pub unsafe fn pop_unchecked(&mut self) -> T {
|
||
debug_assert!(!self.is_empty());
|
||
|
||
self.len -= 1;
|
||
self.buffer
|
||
.borrow_mut()
|
||
.get_unchecked_mut(self.len)
|
||
.as_ptr()
|
||
.read()
|
||
}
|
||
|
||
/// Appends an `item` to the back of the collection
|
||
///
|
||
/// # Safety
|
||
///
|
||
/// This assumes the vec is not full.
|
||
pub unsafe fn push_unchecked(&mut self, item: T) {
|
||
// NOTE(ptr::write) the memory slot that we are about to write to is uninitialized. We
|
||
// use `ptr::write` to avoid running `T`'s destructor on the uninitialized memory
|
||
debug_assert!(!self.is_full());
|
||
|
||
*self.buffer.borrow_mut().get_unchecked_mut(self.len) = MaybeUninit::new(item);
|
||
|
||
self.len += 1;
|
||
}
|
||
|
||
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
|
||
pub fn truncate(&mut self, len: usize) {
|
||
// This is safe because:
|
||
//
|
||
// * the slice passed to `drop_in_place` is valid; the `len > self.len`
|
||
// case avoids creating an invalid slice, and
|
||
// * the `len` of the vector is shrunk before calling `drop_in_place`,
|
||
// such that no value will be dropped twice in case `drop_in_place`
|
||
// were to panic once (if it panics twice, the program aborts).
|
||
unsafe {
|
||
// Note: It's intentional that this is `>` and not `>=`.
|
||
// Changing it to `>=` has negative performance
|
||
// implications in some cases. See rust-lang/rust#78884 for more.
|
||
if len > self.len {
|
||
return;
|
||
}
|
||
let remaining_len = self.len - len;
|
||
let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
|
||
self.len = len;
|
||
ptr::drop_in_place(s);
|
||
}
|
||
}
|
||
|
||
/// Resizes the Vec in-place so that len is equal to `new_len`.
|
||
///
|
||
/// If `new_len` is greater than len, the Vec is extended by the
|
||
/// difference, with each additional slot filled with value. If
|
||
/// `new_len` is less than len, the Vec is simply truncated.
|
||
///
|
||
/// See also [`resize_default`](Self::resize_default).
|
||
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), CapacityError>
|
||
where
|
||
T: Clone,
|
||
{
|
||
if new_len > self.capacity() {
|
||
return Err(CapacityError);
|
||
}
|
||
|
||
if new_len > self.len {
|
||
while self.len < new_len {
|
||
self.push(value.clone()).ok();
|
||
}
|
||
} else {
|
||
self.truncate(new_len);
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
|
||
///
|
||
/// If `new_len` is greater than `len`, the `Vec` is extended by the
|
||
/// difference, with each additional slot filled with `Default::default()`.
|
||
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
|
||
///
|
||
/// See also [`resize`](Self::resize).
|
||
pub fn resize_default(&mut self, new_len: usize) -> Result<(), CapacityError>
|
||
where
|
||
T: Clone + Default,
|
||
{
|
||
self.resize(new_len, T::default())
|
||
}
|
||
|
||
/// Forces the length of the vector to `new_len`.
|
||
///
|
||
/// This is a low-level operation that maintains none of the normal
|
||
/// invariants of the type. Normally changing the length of a vector
|
||
/// is done using one of the safe operations instead, such as
|
||
/// [`truncate`], [`resize`], [`extend`], or [`clear`].
|
||
///
|
||
/// [`truncate`]: Self::truncate
|
||
/// [`resize`]: Self::resize
|
||
/// [`extend`]: core::iter::Extend
|
||
/// [`clear`]: Self::clear
|
||
///
|
||
/// # Safety
|
||
///
|
||
/// - `new_len` must be less than or equal to [`capacity()`].
|
||
/// - The elements at `old_len..new_len` must be initialized.
|
||
///
|
||
/// [`capacity()`]: Self::capacity
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// This method can be useful for situations in which the vector
|
||
/// is serving as a buffer for other code, particularly over FFI:
|
||
///
|
||
/// ```no_run
|
||
/// # #![allow(dead_code)]
|
||
/// use heapless::Vec;
|
||
///
|
||
/// # // This is just a minimal skeleton for the doc example;
|
||
/// # // don't use this as a starting point for a real library.
|
||
/// # pub struct StreamWrapper { strm: *mut core::ffi::c_void }
|
||
/// # const Z_OK: i32 = 0;
|
||
/// # extern "C" {
|
||
/// # fn deflateGetDictionary(
|
||
/// # strm: *mut core::ffi::c_void,
|
||
/// # dictionary: *mut u8,
|
||
/// # dictLength: *mut usize,
|
||
/// # ) -> i32;
|
||
/// # }
|
||
/// # impl StreamWrapper {
|
||
/// pub fn get_dictionary(&self) -> Option<Vec<u8, 32768>> {
|
||
/// // Per the FFI method's docs, "32768 bytes is always enough".
|
||
/// let mut dict = Vec::new();
|
||
/// let mut dict_length = 0;
|
||
/// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
|
||
/// // 1. `dict_length` elements were initialized.
|
||
/// // 2. `dict_length` <= the capacity (32_768)
|
||
/// // which makes `set_len` safe to call.
|
||
/// unsafe {
|
||
/// // Make the FFI call...
|
||
/// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
|
||
/// if r == Z_OK {
|
||
/// // ...and update the length to what was initialized.
|
||
/// dict.set_len(dict_length);
|
||
/// Some(dict)
|
||
/// } else {
|
||
/// None
|
||
/// }
|
||
/// }
|
||
/// }
|
||
/// # }
|
||
/// ```
|
||
///
|
||
/// While the following example is sound, there is a memory leak since
|
||
/// the inner vectors were not freed prior to the `set_len` call:
|
||
///
|
||
/// ```
|
||
/// use core::iter::FromIterator;
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec = Vec::<Vec<u8, 3>, 3>::from_iter(
|
||
/// [
|
||
/// Vec::from_iter([1, 0, 0].iter().cloned()),
|
||
/// Vec::from_iter([0, 1, 0].iter().cloned()),
|
||
/// Vec::from_iter([0, 0, 1].iter().cloned()),
|
||
/// ]
|
||
/// .iter()
|
||
/// .cloned(),
|
||
/// );
|
||
/// // SAFETY:
|
||
/// // 1. `old_len..0` is empty so no elements need to be initialized.
|
||
/// // 2. `0 <= capacity` always holds whatever `capacity` is.
|
||
/// unsafe {
|
||
/// vec.set_len(0);
|
||
/// }
|
||
/// ```
|
||
///
|
||
/// Normally, here, one would use [`clear`] instead to correctly drop
|
||
/// the contents and thus not leak memory.
|
||
pub unsafe fn set_len(&mut self, new_len: usize) {
|
||
debug_assert!(new_len <= self.capacity());
|
||
|
||
self.len = new_len;
|
||
}
|
||
|
||
/// Removes an element from the vector and returns it.
|
||
///
|
||
/// The removed element is replaced by the last element of the vector.
|
||
///
|
||
/// This does not preserve ordering, but is *O*(1).
|
||
///
|
||
/// # Panics
|
||
///
|
||
/// Panics if `index` is out of bounds.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut v: Vec<_, 8> = Vec::new();
|
||
/// v.push("foo").unwrap();
|
||
/// v.push("bar").unwrap();
|
||
/// v.push("baz").unwrap();
|
||
/// v.push("qux").unwrap();
|
||
///
|
||
/// assert_eq!(v.swap_remove(1), "bar");
|
||
/// assert_eq!(&*v, ["foo", "qux", "baz"]);
|
||
///
|
||
/// assert_eq!(v.swap_remove(0), "foo");
|
||
/// assert_eq!(&*v, ["baz", "qux"]);
|
||
/// ```
|
||
pub fn swap_remove(&mut self, index: usize) -> T {
|
||
assert!(index < self.len);
|
||
unsafe { self.swap_remove_unchecked(index) }
|
||
}
|
||
|
||
/// Removes an element from the vector and returns it.
|
||
///
|
||
/// The removed element is replaced by the last element of the vector.
|
||
///
|
||
/// This does not preserve ordering, but is *O*(1).
|
||
///
|
||
/// # Safety
|
||
///
|
||
/// Assumes `index` within bounds.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut v: Vec<_, 8> = Vec::new();
|
||
/// v.push("foo").unwrap();
|
||
/// v.push("bar").unwrap();
|
||
/// v.push("baz").unwrap();
|
||
/// v.push("qux").unwrap();
|
||
///
|
||
/// assert_eq!(unsafe { v.swap_remove_unchecked(1) }, "bar");
|
||
/// assert_eq!(&*v, ["foo", "qux", "baz"]);
|
||
///
|
||
/// assert_eq!(unsafe { v.swap_remove_unchecked(0) }, "foo");
|
||
/// assert_eq!(&*v, ["baz", "qux"]);
|
||
/// ```
|
||
pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
|
||
let length = self.len();
|
||
debug_assert!(index < length);
|
||
let value = ptr::read(self.as_ptr().add(index));
|
||
let base_ptr = self.as_mut_ptr();
|
||
ptr::copy(base_ptr.add(length - 1), base_ptr.add(index), 1);
|
||
self.len -= 1;
|
||
value
|
||
}
|
||
|
||
/// Returns true if the vec is full
|
||
pub fn is_full(&self) -> bool {
|
||
self.len == self.capacity()
|
||
}
|
||
|
||
/// Returns true if the vec is empty
|
||
pub fn is_empty(&self) -> bool {
|
||
self.len == 0
|
||
}
|
||
|
||
/// Returns `true` if `needle` is a prefix of the Vec.
|
||
///
|
||
/// Always returns `true` if `needle` is an empty slice.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap();
|
||
/// assert_eq!(v.starts_with(b""), true);
|
||
/// assert_eq!(v.starts_with(b"ab"), true);
|
||
/// assert_eq!(v.starts_with(b"bc"), false);
|
||
/// ```
|
||
pub fn starts_with(&self, needle: &[T]) -> bool
|
||
where
|
||
T: PartialEq,
|
||
{
|
||
let n = needle.len();
|
||
self.len >= n && needle == &self[..n]
|
||
}
|
||
|
||
/// Returns `true` if `needle` is a suffix of the Vec.
|
||
///
|
||
/// Always returns `true` if `needle` is an empty slice.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let v: Vec<_, 8> = Vec::from_slice(b"abc").unwrap();
|
||
/// assert_eq!(v.ends_with(b""), true);
|
||
/// assert_eq!(v.ends_with(b"ab"), false);
|
||
/// assert_eq!(v.ends_with(b"bc"), true);
|
||
/// ```
|
||
pub fn ends_with(&self, needle: &[T]) -> bool
|
||
where
|
||
T: PartialEq,
|
||
{
|
||
let (v, n) = (self.len(), needle.len());
|
||
v >= n && needle == &self[v - n..]
|
||
}
|
||
|
||
/// Inserts an element at position `index` within the vector, shifting all
|
||
/// elements after it to the right.
|
||
///
|
||
/// Returns back the `element` if the vector is full.
|
||
///
|
||
/// # Panics
|
||
///
|
||
/// Panics if `index > len`.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap();
|
||
/// vec.insert(1, 4);
|
||
/// assert_eq!(vec, [1, 4, 2, 3]);
|
||
/// vec.insert(4, 5);
|
||
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
|
||
/// ```
|
||
pub fn insert(&mut self, index: usize, element: T) -> Result<(), T> {
|
||
let len = self.len();
|
||
if index > len {
|
||
panic!(
|
||
"insertion index (is {}) should be <= len (is {})",
|
||
index, len
|
||
);
|
||
}
|
||
|
||
// check there's space for the new element
|
||
if self.is_full() {
|
||
return Err(element);
|
||
}
|
||
|
||
unsafe {
|
||
// infallible
|
||
// The spot to put the new value
|
||
{
|
||
let p = self.as_mut_ptr().add(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(())
|
||
}
|
||
|
||
/// Removes and returns the element at position `index` within the vector,
|
||
/// shifting all elements after it to the left.
|
||
///
|
||
/// Note: Because this shifts over the remaining elements, it has a
|
||
/// worst-case performance of *O*(n). If you don't need the order of
|
||
/// elements to be preserved, use [`swap_remove`] instead. If you'd like to
|
||
/// remove elements from the beginning of the `Vec`, consider using
|
||
/// [`Deque::pop_front`] instead.
|
||
///
|
||
/// [`swap_remove`]: Vec::swap_remove
|
||
/// [`Deque::pop_front`]: crate::Deque::pop_front
|
||
///
|
||
/// # Panics
|
||
///
|
||
/// Panics if `index` is out of bounds.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut v: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap();
|
||
/// assert_eq!(v.remove(1), 2);
|
||
/// assert_eq!(v, [1, 3]);
|
||
/// ```
|
||
pub fn remove(&mut self, index: usize) -> T {
|
||
let len = self.len();
|
||
if index >= len {
|
||
panic!("removal index (is {}) should be < len (is {})", index, len);
|
||
}
|
||
unsafe {
|
||
// infallible
|
||
let ret;
|
||
{
|
||
// the place we are taking from.
|
||
let ptr = self.as_mut_ptr().add(index);
|
||
// copy it out, unsafely having a copy of the value on
|
||
// the stack and in the vector at the same time.
|
||
ret = ptr::read(ptr);
|
||
|
||
// Shift everything down to fill in that spot.
|
||
ptr::copy(ptr.offset(1), ptr, len - index - 1);
|
||
}
|
||
self.set_len(len - 1);
|
||
ret
|
||
}
|
||
}
|
||
|
||
/// Retains only the elements specified by the predicate.
|
||
///
|
||
/// In other words, remove all elements `e` for which `f(&e)` returns `false`.
|
||
/// This method operates in place, visiting each element exactly once in the
|
||
/// original order, and preserves the order of the retained elements.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// vec.retain(|&x| x % 2 == 0);
|
||
/// assert_eq!(vec, [2, 4]);
|
||
/// ```
|
||
///
|
||
/// Because the elements are visited exactly once in the original order,
|
||
/// external state may be used to decide which elements to keep.
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4, 5]).unwrap();
|
||
/// let keep = [false, true, true, false, true];
|
||
/// let mut iter = keep.iter();
|
||
/// vec.retain(|_| *iter.next().unwrap());
|
||
/// assert_eq!(vec, [2, 3, 5]);
|
||
/// ```
|
||
pub fn retain<F>(&mut self, mut f: F)
|
||
where
|
||
F: FnMut(&T) -> bool,
|
||
{
|
||
self.retain_mut(|elem| f(elem));
|
||
}
|
||
|
||
/// Retains only the elements specified by the predicate, passing a mutable reference to it.
|
||
///
|
||
/// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
|
||
/// This method operates in place, visiting each element exactly once in the
|
||
/// original order, and preserves the order of the retained elements.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
|
||
/// vec.retain_mut(|x| {
|
||
/// if *x <= 3 {
|
||
/// *x += 1;
|
||
/// true
|
||
/// } else {
|
||
/// false
|
||
/// }
|
||
/// });
|
||
/// assert_eq!(vec, [2, 3, 4]);
|
||
/// ```
|
||
pub fn retain_mut<F>(&mut self, mut f: F)
|
||
where
|
||
F: FnMut(&mut T) -> bool,
|
||
{
|
||
let original_len = self.len();
|
||
// Avoid double drop if the drop guard is not executed,
|
||
// since we may make some holes during the process.
|
||
unsafe { self.set_len(0) };
|
||
|
||
// Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
|
||
// |<- processed len ->| ^- next to check
|
||
// |<- deleted cnt ->|
|
||
// |<- original_len ->|
|
||
// Kept: Elements which predicate returns true on.
|
||
// Hole: Moved or dropped element slot.
|
||
// Unchecked: Unchecked valid elements.
|
||
//
|
||
// This drop guard will be invoked when predicate or `drop` of element panicked.
|
||
// It shifts unchecked elements to cover holes and `set_len` to the correct length.
|
||
// In cases when predicate and `drop` never panick, it will be optimized out.
|
||
struct BackshiftOnDrop<'a, T, S: VecStorage<T> + ?Sized> {
|
||
v: &'a mut VecInner<T, S>,
|
||
processed_len: usize,
|
||
deleted_cnt: usize,
|
||
original_len: usize,
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> Drop for BackshiftOnDrop<'_, T, S> {
|
||
fn drop(&mut self) {
|
||
if self.deleted_cnt > 0 {
|
||
// SAFETY: Trailing unchecked items must be valid since we never touch them.
|
||
unsafe {
|
||
ptr::copy(
|
||
self.v.as_ptr().add(self.processed_len),
|
||
self.v
|
||
.as_mut_ptr()
|
||
.add(self.processed_len - self.deleted_cnt),
|
||
self.original_len - self.processed_len,
|
||
);
|
||
}
|
||
}
|
||
// SAFETY: After filling holes, all items are in contiguous memory.
|
||
unsafe {
|
||
self.v.set_len(self.original_len - self.deleted_cnt);
|
||
}
|
||
}
|
||
}
|
||
|
||
let mut g = BackshiftOnDrop {
|
||
v: self,
|
||
processed_len: 0,
|
||
deleted_cnt: 0,
|
||
original_len,
|
||
};
|
||
|
||
fn process_loop<F, T, S: VecStorage<T> + ?Sized, const DELETED: bool>(
|
||
original_len: usize,
|
||
f: &mut F,
|
||
g: &mut BackshiftOnDrop<'_, T, S>,
|
||
) where
|
||
F: FnMut(&mut T) -> bool,
|
||
{
|
||
while g.processed_len != original_len {
|
||
let p = g.v.as_mut_ptr();
|
||
// SAFETY: Unchecked element must be valid.
|
||
let cur = unsafe { &mut *p.add(g.processed_len) };
|
||
if !f(cur) {
|
||
// Advance early to avoid double drop if `drop_in_place` panicked.
|
||
g.processed_len += 1;
|
||
g.deleted_cnt += 1;
|
||
// SAFETY: We never touch this element again after dropped.
|
||
unsafe { ptr::drop_in_place(cur) };
|
||
// We already advanced the counter.
|
||
if DELETED {
|
||
continue;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
if DELETED {
|
||
// SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
|
||
// We use copy for move, and never touch this element again.
|
||
unsafe {
|
||
let hole_slot = p.add(g.processed_len - g.deleted_cnt);
|
||
ptr::copy_nonoverlapping(cur, hole_slot, 1);
|
||
}
|
||
}
|
||
g.processed_len += 1;
|
||
}
|
||
}
|
||
|
||
// Stage 1: Nothing was deleted.
|
||
process_loop::<F, T, S, false>(original_len, &mut f, &mut g);
|
||
|
||
// Stage 2: Some elements were deleted.
|
||
process_loop::<F, T, S, true>(original_len, &mut f, &mut g);
|
||
|
||
// All item are processed. This can be optimized to `set_len` by LLVM.
|
||
drop(g);
|
||
}
|
||
|
||
/// Returns the remaining spare capacity of the vector as a slice of `MaybeUninit<T>`.
|
||
///
|
||
/// The returned slice can be used to fill the vector with data before marking the data as
|
||
/// initialized using the `set_len` method.
|
||
///
|
||
/// # Examples
|
||
///
|
||
/// ```
|
||
/// use heapless::Vec;
|
||
///
|
||
/// // Allocate vector big enough for 10 elements.
|
||
/// let mut v: Vec<_, 10> = Vec::new();
|
||
///
|
||
/// // Fill in the first 3 elements.
|
||
/// let uninit = v.spare_capacity_mut();
|
||
/// uninit[0].write(0);
|
||
/// uninit[1].write(1);
|
||
/// uninit[2].write(2);
|
||
///
|
||
/// // Mark the first 3 elements of the vector as being initialized.
|
||
/// unsafe {
|
||
/// v.set_len(3);
|
||
/// }
|
||
///
|
||
/// assert_eq!(&v, &[0, 1, 2]);
|
||
/// ```
|
||
#[inline]
|
||
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
|
||
&mut self.buffer.borrow_mut()[self.len..]
|
||
}
|
||
}
|
||
|
||
// Trait implementations
|
||
|
||
impl<T, const N: usize> Default for Vec<T, N> {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> fmt::Debug for VecInner<T, S>
|
||
where
|
||
T: fmt::Debug,
|
||
{
|
||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
<[T] as fmt::Debug>::fmt(self, f)
|
||
}
|
||
}
|
||
|
||
impl<S: VecStorage<u8> + ?Sized> fmt::Write for VecInner<u8, S> {
|
||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||
match self.extend_from_slice(s.as_bytes()) {
|
||
Ok(()) => Ok(()),
|
||
Err(_) => Err(fmt::Error),
|
||
}
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize, const M: usize> From<[T; M]> for Vec<T, N> {
|
||
fn from(array: [T; M]) -> Self {
|
||
Self::from_array(array)
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> Drop for VecInner<T, S> {
|
||
fn drop(&mut self) {
|
||
let mut_slice = self.as_mut_slice();
|
||
// We drop each element used in the vector by turning into a `&mut [T]`.
|
||
// SAFETY: the buffer contains initialized data for the range 0..self.len
|
||
unsafe { ptr::drop_in_place(mut_slice) }
|
||
}
|
||
}
|
||
|
||
#[cfg(feature = "alloc")]
|
||
/// Converts the given `alloc::vec::Vec<T>` into a `Vec<T, N>`.
|
||
impl<T, const N: usize> TryFrom<alloc::vec::Vec<T>> for Vec<T, N> {
|
||
type Error = CapacityError;
|
||
|
||
/// Converts the given `alloc::vec::Vec<T>` into a `Vec<T, N>`.
|
||
///
|
||
/// # Errors
|
||
///
|
||
/// Returns `Err` if the length of the `alloc::vec::Vec<T>` is greater than `N`.
|
||
fn try_from(alloc_vec: alloc::vec::Vec<T>) -> Result<Self, Self::Error> {
|
||
let mut vec = Vec::new();
|
||
|
||
for e in alloc_vec {
|
||
// Push each element individually to allow handling capacity errors.
|
||
vec.push(e).map_err(|_| CapacityError {})?;
|
||
}
|
||
|
||
Ok(vec)
|
||
}
|
||
}
|
||
|
||
#[cfg(feature = "alloc")]
|
||
/// Converts the given `Vec<T, N>` into an `alloc::vec::Vec<T>`.
|
||
impl<T, const N: usize> TryFrom<Vec<T, N>> for alloc::vec::Vec<T> {
|
||
type Error = alloc::collections::TryReserveError;
|
||
|
||
/// Converts the given `Vec<T, N>` into an `alloc::vec::Vec<T>`.
|
||
///
|
||
/// # Errors
|
||
///
|
||
/// Returns `Err` if the `alloc::vec::Vec` fails to allocate memory.
|
||
fn try_from(vec: Vec<T, N>) -> Result<Self, Self::Error> {
|
||
let mut alloc_vec = alloc::vec::Vec::new();
|
||
|
||
// Allocate enough space for the elements, return an error if the
|
||
// allocation fails.
|
||
alloc_vec.try_reserve_exact(vec.len())?;
|
||
|
||
// Transfer the elements, since we reserved enough space above, this
|
||
// should not fail due to OOM.
|
||
alloc_vec.extend(vec);
|
||
|
||
Ok(alloc_vec)
|
||
}
|
||
}
|
||
|
||
impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec<T, N> {
|
||
type Error = CapacityError;
|
||
|
||
fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> {
|
||
Self::from_slice(slice)
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> Extend<T> for VecInner<T, S> {
|
||
fn extend<I>(&mut self, iter: I)
|
||
where
|
||
I: IntoIterator<Item = T>,
|
||
{
|
||
self.extend(iter);
|
||
}
|
||
}
|
||
|
||
impl<'a, T, S: VecStorage<T> + ?Sized> Extend<&'a T> for VecInner<T, S>
|
||
where
|
||
T: 'a + Copy,
|
||
{
|
||
fn extend<I>(&mut self, iter: I)
|
||
where
|
||
I: IntoIterator<Item = &'a T>,
|
||
{
|
||
self.extend(iter.into_iter().cloned());
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> hash::Hash for VecInner<T, S>
|
||
where
|
||
T: core::hash::Hash,
|
||
{
|
||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||
<[T] as hash::Hash>::hash(self, state);
|
||
}
|
||
}
|
||
|
||
impl<'a, T, S: VecStorage<T> + ?Sized> IntoIterator for &'a VecInner<T, S> {
|
||
type Item = &'a T;
|
||
type IntoIter = slice::Iter<'a, T>;
|
||
|
||
fn into_iter(self) -> Self::IntoIter {
|
||
self.iter()
|
||
}
|
||
}
|
||
|
||
impl<'a, T, S: VecStorage<T> + ?Sized> IntoIterator for &'a mut VecInner<T, S> {
|
||
type Item = &'a mut T;
|
||
type IntoIter = slice::IterMut<'a, T>;
|
||
|
||
fn into_iter(self) -> Self::IntoIter {
|
||
self.iter_mut()
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize> FromIterator<T> for Vec<T, N> {
|
||
fn from_iter<I>(iter: I) -> Self
|
||
where
|
||
I: IntoIterator<Item = T>,
|
||
{
|
||
let mut vec = Self::new();
|
||
for i in iter {
|
||
vec.push(i).ok().expect("Vec::from_iter overflow");
|
||
}
|
||
vec
|
||
}
|
||
}
|
||
|
||
/// An iterator that moves out of an [`Vec`][`Vec`].
|
||
///
|
||
/// This struct is created by calling the `into_iter` method on [`Vec`][`Vec`].
|
||
pub struct IntoIter<T, const N: usize> {
|
||
vec: Vec<T, N>,
|
||
next: usize,
|
||
}
|
||
|
||
impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
||
type Item = T;
|
||
fn next(&mut self) -> Option<Self::Item> {
|
||
if self.next < self.vec.len() {
|
||
let item = unsafe {
|
||
self.vec
|
||
.buffer
|
||
.buffer
|
||
.get_unchecked_mut(self.next)
|
||
.as_ptr()
|
||
.read()
|
||
};
|
||
self.next += 1;
|
||
Some(item)
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize> Clone for IntoIter<T, N>
|
||
where
|
||
T: Clone,
|
||
{
|
||
fn clone(&self) -> Self {
|
||
let mut vec = Vec::new();
|
||
|
||
if self.next < self.vec.len() {
|
||
let s = unsafe {
|
||
slice::from_raw_parts(
|
||
self.vec.buffer.buffer.as_ptr().cast::<T>().add(self.next),
|
||
self.vec.len() - self.next,
|
||
)
|
||
};
|
||
vec.extend_from_slice(s).ok();
|
||
}
|
||
|
||
Self { vec, next: 0 }
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize> Drop for IntoIter<T, N> {
|
||
fn drop(&mut self) {
|
||
unsafe {
|
||
// Drop all the elements that have not been moved out of vec
|
||
ptr::drop_in_place(&mut self.vec.as_mut_slice()[self.next..]);
|
||
// Prevent dropping of other elements
|
||
self.vec.len = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize> IntoIterator for Vec<T, N> {
|
||
type Item = T;
|
||
type IntoIter = IntoIter<T, N>;
|
||
|
||
fn into_iter(self) -> Self::IntoIter {
|
||
IntoIter { vec: self, next: 0 }
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized, SB: VecStorage<B> + ?Sized> PartialEq<VecInner<B, SB>>
|
||
for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
self.as_slice().eq(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<A, B, const M: usize, SB: VecStorage<B> + ?Sized> PartialEq<VecInner<B, SB>> for [A; M]
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
self.eq(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<A, B, SB: VecStorage<B> + ?Sized, const M: usize> PartialEq<VecInner<B, SB>> for &[A; M]
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
(*self).eq(other)
|
||
}
|
||
}
|
||
|
||
impl<A, B, SB: VecStorage<B> + ?Sized> PartialEq<VecInner<B, SB>> for [A]
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
self.eq(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<A, B, SB: VecStorage<B> + ?Sized> PartialEq<VecInner<B, SB>> for &[A]
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
(*self).eq(other)
|
||
}
|
||
}
|
||
|
||
impl<A, B, SB: VecStorage<B> + ?Sized> PartialEq<VecInner<B, SB>> for &mut [A]
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
fn eq(&self, other: &VecInner<B, SB>) -> bool {
|
||
(**self).eq(other)
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized, const N: usize> PartialEq<[B; N]> for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
#[inline]
|
||
fn eq(&self, other: &[B; N]) -> bool {
|
||
self.as_slice().eq(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized, const N: usize> PartialEq<&[B; N]> for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
#[inline]
|
||
fn eq(&self, other: &&[B; N]) -> bool {
|
||
self.as_slice().eq(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized> PartialEq<[B]> for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
#[inline]
|
||
fn eq(&self, other: &[B]) -> bool {
|
||
self.as_slice().eq(other)
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized> PartialEq<&[B]> for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
#[inline]
|
||
fn eq(&self, other: &&[B]) -> bool {
|
||
self.as_slice().eq(*other)
|
||
}
|
||
}
|
||
|
||
impl<A, B, SA: VecStorage<A> + ?Sized> PartialEq<&mut [B]> for VecInner<A, SA>
|
||
where
|
||
A: PartialEq<B>,
|
||
{
|
||
#[inline]
|
||
fn eq(&self, other: &&mut [B]) -> bool {
|
||
self.as_slice().eq(*other)
|
||
}
|
||
}
|
||
|
||
// Implements Eq if underlying data is Eq
|
||
impl<T, S: VecStorage<T> + ?Sized> Eq for VecInner<T, S> where T: Eq {}
|
||
|
||
impl<T, SA: VecStorage<T> + ?Sized, SB: VecStorage<T> + ?Sized> PartialOrd<VecInner<T, SA>>
|
||
for VecInner<T, SB>
|
||
where
|
||
T: PartialOrd,
|
||
{
|
||
fn partial_cmp(&self, other: &VecInner<T, SA>) -> Option<Ordering> {
|
||
self.as_slice().partial_cmp(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> Ord for VecInner<T, S>
|
||
where
|
||
T: Ord,
|
||
{
|
||
#[inline]
|
||
fn cmp(&self, other: &Self) -> Ordering {
|
||
self.as_slice().cmp(other.as_slice())
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> ops::Deref for VecInner<T, S> {
|
||
type Target = [T];
|
||
|
||
fn deref(&self) -> &Self::Target {
|
||
self.as_slice()
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> ops::DerefMut for VecInner<T, S> {
|
||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||
self.as_mut_slice()
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> borrow::Borrow<[T]> for VecInner<T, S> {
|
||
fn borrow(&self) -> &[T] {
|
||
self.as_slice()
|
||
}
|
||
}
|
||
impl<T, S: VecStorage<T> + ?Sized> borrow::BorrowMut<[T]> for VecInner<T, S> {
|
||
fn borrow_mut(&mut self) -> &mut [T] {
|
||
self.as_mut_slice()
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> AsRef<Self> for VecInner<T, S> {
|
||
#[inline]
|
||
fn as_ref(&self) -> &Self {
|
||
self
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> AsMut<Self> for VecInner<T, S> {
|
||
#[inline]
|
||
fn as_mut(&mut self) -> &mut Self {
|
||
self
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> AsRef<[T]> for VecInner<T, S> {
|
||
#[inline]
|
||
fn as_ref(&self) -> &[T] {
|
||
self
|
||
}
|
||
}
|
||
|
||
impl<T, S: VecStorage<T> + ?Sized> AsMut<[T]> for VecInner<T, S> {
|
||
#[inline]
|
||
fn as_mut(&mut self) -> &mut [T] {
|
||
self
|
||
}
|
||
}
|
||
|
||
impl<T, const N: usize> Clone for Vec<T, N>
|
||
where
|
||
T: Clone,
|
||
{
|
||
fn clone(&self) -> Self {
|
||
self.clone()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use core::fmt::Write;
|
||
|
||
use static_assertions::assert_not_impl_any;
|
||
|
||
use super::{Vec, VecView};
|
||
|
||
// Ensure a `Vec` containing `!Send` values stays `!Send` itself.
|
||
assert_not_impl_any!(Vec<*const (), 4>: Send);
|
||
|
||
#[test]
|
||
fn static_new() {
|
||
static mut _V: Vec<i32, 4> = Vec::new();
|
||
}
|
||
|
||
#[test]
|
||
fn stack_new() {
|
||
let mut _v: Vec<i32, 4> = Vec::new();
|
||
}
|
||
|
||
#[test]
|
||
fn is_full_empty() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
|
||
assert!(v.is_empty());
|
||
assert!(!v.is_full());
|
||
|
||
v.push(1).unwrap();
|
||
assert!(!v.is_empty());
|
||
assert!(!v.is_full());
|
||
|
||
v.push(1).unwrap();
|
||
assert!(!v.is_empty());
|
||
assert!(!v.is_full());
|
||
|
||
v.push(1).unwrap();
|
||
assert!(!v.is_empty());
|
||
assert!(!v.is_full());
|
||
|
||
v.push(1).unwrap();
|
||
assert!(!v.is_empty());
|
||
assert!(v.is_full());
|
||
}
|
||
|
||
#[test]
|
||
fn drop() {
|
||
droppable!();
|
||
|
||
{
|
||
let mut v: Vec<Droppable, 2> = Vec::new();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
v.pop().unwrap();
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
|
||
{
|
||
let mut v: Vec<Droppable, 2> = Vec::new();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn drop_vecview() {
|
||
droppable!();
|
||
|
||
{
|
||
let v: Vec<Droppable, 2> = Vec::new();
|
||
let v: Box<Vec<Droppable, 2>> = Box::new(v);
|
||
let mut v: Box<VecView<Droppable>> = v;
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
assert_eq!(Droppable::count(), 2);
|
||
v.pop().unwrap();
|
||
assert_eq!(Droppable::count(), 1);
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
|
||
{
|
||
let v: Vec<Droppable, 2> = Vec::new();
|
||
let v: Box<Vec<Droppable, 2>> = Box::new(v);
|
||
let mut v: Box<VecView<Droppable>> = v;
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
v.push(Droppable::new()).ok().unwrap();
|
||
assert_eq!(Droppable::count(), 2);
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn eq() {
|
||
let mut xs: Vec<i32, 4> = Vec::new();
|
||
let mut ys: Vec<i32, 8> = Vec::new();
|
||
|
||
assert_eq!(xs, ys);
|
||
|
||
xs.push(1).unwrap();
|
||
ys.push(1).unwrap();
|
||
|
||
assert_eq!(xs, ys);
|
||
}
|
||
|
||
#[test]
|
||
fn cmp() {
|
||
let mut xs: Vec<i32, 4> = Vec::new();
|
||
let mut ys: Vec<i32, 4> = Vec::new();
|
||
|
||
assert_eq!(xs, ys);
|
||
|
||
xs.push(1).unwrap();
|
||
ys.push(2).unwrap();
|
||
|
||
assert!(xs < ys);
|
||
}
|
||
|
||
#[test]
|
||
fn cmp_heterogenous_size() {
|
||
let mut xs: Vec<i32, 4> = Vec::new();
|
||
let mut ys: Vec<i32, 8> = Vec::new();
|
||
|
||
assert_eq!(xs, ys);
|
||
|
||
xs.push(1).unwrap();
|
||
ys.push(2).unwrap();
|
||
|
||
assert!(xs < ys);
|
||
}
|
||
|
||
#[test]
|
||
fn cmp_with_arrays_and_slices() {
|
||
let mut xs: Vec<i32, 12> = Vec::new();
|
||
xs.push(1).unwrap();
|
||
|
||
let array = [1];
|
||
|
||
assert_eq!(xs, array);
|
||
assert_eq!(array, xs);
|
||
|
||
assert_eq!(xs, array.as_slice());
|
||
assert_eq!(array.as_slice(), xs);
|
||
|
||
assert_eq!(xs, &array);
|
||
assert_eq!(&array, xs);
|
||
|
||
let longer_array = [1; 20];
|
||
|
||
assert_ne!(xs, longer_array);
|
||
assert_ne!(longer_array, xs);
|
||
}
|
||
|
||
#[test]
|
||
fn full() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
|
||
v.push(0).unwrap();
|
||
v.push(1).unwrap();
|
||
v.push(2).unwrap();
|
||
v.push(3).unwrap();
|
||
|
||
assert!(v.push(4).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn iter() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
|
||
v.push(0).unwrap();
|
||
v.push(1).unwrap();
|
||
v.push(2).unwrap();
|
||
v.push(3).unwrap();
|
||
|
||
let mut items = v.iter();
|
||
|
||
assert_eq!(items.next(), Some(&0));
|
||
assert_eq!(items.next(), Some(&1));
|
||
assert_eq!(items.next(), Some(&2));
|
||
assert_eq!(items.next(), Some(&3));
|
||
assert_eq!(items.next(), None);
|
||
}
|
||
|
||
#[test]
|
||
fn iter_mut() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
|
||
v.push(0).unwrap();
|
||
v.push(1).unwrap();
|
||
v.push(2).unwrap();
|
||
v.push(3).unwrap();
|
||
|
||
let mut items = v.iter_mut();
|
||
|
||
assert_eq!(items.next(), Some(&mut 0));
|
||
assert_eq!(items.next(), Some(&mut 1));
|
||
assert_eq!(items.next(), Some(&mut 2));
|
||
assert_eq!(items.next(), Some(&mut 3));
|
||
assert_eq!(items.next(), None);
|
||
}
|
||
|
||
#[test]
|
||
fn collect_from_iter() {
|
||
let slice = &[1, 2, 3];
|
||
let vec: Vec<i32, 4> = slice.iter().cloned().collect();
|
||
assert_eq!(&vec, slice);
|
||
}
|
||
|
||
#[test]
|
||
#[should_panic]
|
||
fn collect_from_iter_overfull() {
|
||
let slice = &[1, 2, 3];
|
||
let _vec = slice.iter().cloned().collect::<Vec<_, 2>>();
|
||
}
|
||
|
||
#[test]
|
||
fn iter_move() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
v.push(0).unwrap();
|
||
v.push(1).unwrap();
|
||
v.push(2).unwrap();
|
||
v.push(3).unwrap();
|
||
|
||
let mut items = v.into_iter();
|
||
|
||
assert_eq!(items.next(), Some(0));
|
||
assert_eq!(items.next(), Some(1));
|
||
assert_eq!(items.next(), Some(2));
|
||
assert_eq!(items.next(), Some(3));
|
||
assert_eq!(items.next(), None);
|
||
}
|
||
|
||
#[test]
|
||
fn iter_move_drop() {
|
||
droppable!();
|
||
|
||
{
|
||
let mut vec: Vec<Droppable, 2> = Vec::new();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
let mut items = vec.into_iter();
|
||
// Move all
|
||
let _ = items.next();
|
||
let _ = items.next();
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
|
||
{
|
||
let mut vec: Vec<Droppable, 2> = Vec::new();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
let _items = vec.into_iter();
|
||
// Move none
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
|
||
{
|
||
let mut vec: Vec<Droppable, 2> = Vec::new();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
vec.push(Droppable::new()).ok().unwrap();
|
||
let mut items = vec.into_iter();
|
||
let _ = items.next(); // Move partly
|
||
}
|
||
|
||
assert_eq!(Droppable::count(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn push_and_pop() {
|
||
let mut v: Vec<i32, 4> = Vec::new();
|
||
assert_eq!(v.len(), 0);
|
||
|
||
assert_eq!(v.pop(), None);
|
||
assert_eq!(v.len(), 0);
|
||
|
||
v.push(0).unwrap();
|
||
assert_eq!(v.len(), 1);
|
||
|
||
assert_eq!(v.pop(), Some(0));
|
||
assert_eq!(v.len(), 0);
|
||
|
||
assert_eq!(v.pop(), None);
|
||
assert_eq!(v.len(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn resize_size_limit() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
|
||
v.resize(0, 0).unwrap();
|
||
v.resize(4, 0).unwrap();
|
||
v.resize(5, 0).expect_err("full");
|
||
}
|
||
|
||
#[test]
|
||
fn resize_length_cases() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
|
||
assert_eq!(v.len(), 0);
|
||
|
||
// Grow by 1
|
||
v.resize(1, 0).unwrap();
|
||
assert_eq!(v.len(), 1);
|
||
|
||
// Grow by 2
|
||
v.resize(3, 0).unwrap();
|
||
assert_eq!(v.len(), 3);
|
||
|
||
// Resize to current size
|
||
v.resize(3, 0).unwrap();
|
||
assert_eq!(v.len(), 3);
|
||
|
||
// Shrink by 1
|
||
v.resize(2, 0).unwrap();
|
||
assert_eq!(v.len(), 2);
|
||
|
||
// Shrink by 2
|
||
v.resize(0, 0).unwrap();
|
||
assert_eq!(v.len(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn resize_contents() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
|
||
// New entries take supplied value when growing
|
||
v.resize(1, 17).unwrap();
|
||
assert_eq!(v[0], 17);
|
||
|
||
// Old values aren't changed when growing
|
||
v.resize(2, 18).unwrap();
|
||
assert_eq!(v[0], 17);
|
||
assert_eq!(v[1], 18);
|
||
|
||
// Old values aren't changed when length unchanged
|
||
v.resize(2, 0).unwrap();
|
||
assert_eq!(v[0], 17);
|
||
assert_eq!(v[1], 18);
|
||
|
||
// Old values aren't changed when shrinking
|
||
v.resize(1, 0).unwrap();
|
||
assert_eq!(v[0], 17);
|
||
}
|
||
|
||
#[test]
|
||
fn resize_default() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
|
||
// resize_default is implemented using resize, so just check the
|
||
// correct value is being written.
|
||
v.resize_default(1).unwrap();
|
||
assert_eq!(v[0], 0);
|
||
}
|
||
|
||
#[test]
|
||
fn write() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
write!(v, "{:x}", 1234).unwrap();
|
||
assert_eq!(&v[..], b"4d2");
|
||
}
|
||
|
||
#[test]
|
||
fn extend_from_slice() {
|
||
let mut v: Vec<u8, 4> = Vec::new();
|
||
assert_eq!(v.len(), 0);
|
||
v.extend_from_slice(&[1, 2]).unwrap();
|
||
assert_eq!(v.len(), 2);
|
||
assert_eq!(v.as_slice(), &[1, 2]);
|
||
v.extend_from_slice(&[3]).unwrap();
|
||
assert_eq!(v.len(), 3);
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
assert!(v.extend_from_slice(&[4, 5]).is_err());
|
||
assert_eq!(v.len(), 3);
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
}
|
||
|
||
#[test]
|
||
fn from_slice() {
|
||
// Successful construction
|
||
let v: Vec<u8, 4> = Vec::from_slice(&[1, 2, 3]).unwrap();
|
||
assert_eq!(v.len(), 3);
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
|
||
// Slice too large
|
||
assert!(Vec::<u8, 2>::from_slice(&[1, 2, 3]).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn from_array() {
|
||
// Successful construction, N == M
|
||
let v: Vec<u8, 3> = Vec::from_array([1, 2, 3]);
|
||
assert_eq!(v, Vec::<u8, 3>::from([1, 2, 3]));
|
||
assert_eq!(v.len(), 3);
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
|
||
// Successful construction, N > M
|
||
let v: Vec<u8, 4> = Vec::from_array([1, 2, 3]);
|
||
assert_eq!(v, Vec::<u8, 4>::from([1, 2, 3]));
|
||
assert_eq!(v.len(), 3);
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
}
|
||
|
||
#[test]
|
||
fn from_array_no_drop() {
|
||
struct Drops(Option<u8>);
|
||
|
||
impl Drop for Drops {
|
||
fn drop(&mut self) {
|
||
self.0 = None;
|
||
}
|
||
}
|
||
|
||
let v: Vec<Drops, 3> = Vec::from([Drops(Some(1)), Drops(Some(2)), Drops(Some(3))]);
|
||
|
||
assert_eq!(v[0].0, Some(1));
|
||
assert_eq!(v[1].0, Some(2));
|
||
assert_eq!(v[2].0, Some(3));
|
||
}
|
||
|
||
#[test]
|
||
fn starts_with() {
|
||
let v: Vec<_, 8> = Vec::from_slice(b"ab").unwrap();
|
||
assert!(v.starts_with(&[]));
|
||
assert!(v.starts_with(b""));
|
||
assert!(v.starts_with(b"a"));
|
||
assert!(v.starts_with(b"ab"));
|
||
assert!(!v.starts_with(b"abc"));
|
||
assert!(!v.starts_with(b"ba"));
|
||
assert!(!v.starts_with(b"b"));
|
||
}
|
||
|
||
#[test]
|
||
fn ends_with() {
|
||
let v: Vec<_, 8> = Vec::from_slice(b"ab").unwrap();
|
||
assert!(v.ends_with(&[]));
|
||
assert!(v.ends_with(b""));
|
||
assert!(v.ends_with(b"b"));
|
||
assert!(v.ends_with(b"ab"));
|
||
assert!(!v.ends_with(b"abc"));
|
||
assert!(!v.ends_with(b"ba"));
|
||
assert!(!v.ends_with(b"a"));
|
||
}
|
||
|
||
#[test]
|
||
fn zero_capacity() {
|
||
let mut v: Vec<u8, 0> = Vec::new();
|
||
// Validate capacity
|
||
assert_eq!(v.capacity(), 0);
|
||
|
||
// Make sure there is no capacity
|
||
assert!(v.push(1).is_err());
|
||
|
||
// Validate length
|
||
assert_eq!(v.len(), 0);
|
||
|
||
// Validate pop
|
||
assert_eq!(v.pop(), None);
|
||
|
||
// Validate slice
|
||
assert_eq!(v.as_slice(), &[]);
|
||
|
||
// Validate empty
|
||
assert!(v.is_empty());
|
||
|
||
// Validate full
|
||
assert!(v.is_full());
|
||
}
|
||
|
||
#[test]
|
||
fn spare_capacity_mut() {
|
||
let mut v: Vec<_, 4> = Vec::new();
|
||
let uninit = v.spare_capacity_mut();
|
||
assert_eq!(uninit.len(), 4);
|
||
uninit[0].write(1);
|
||
uninit[1].write(2);
|
||
uninit[2].write(3);
|
||
unsafe { v.set_len(3) };
|
||
assert_eq!(v.as_slice(), &[1, 2, 3]);
|
||
|
||
let uninit = v.spare_capacity_mut();
|
||
assert_eq!(uninit.len(), 1);
|
||
uninit[0].write(4);
|
||
unsafe { v.set_len(4) };
|
||
assert_eq!(v.as_slice(), &[1, 2, 3, 4]);
|
||
|
||
assert!(v.spare_capacity_mut().is_empty());
|
||
}
|
||
|
||
#[test]
|
||
#[cfg(feature = "alloc")]
|
||
fn heapless_to_alloc() {
|
||
let mut hv: Vec<u8, 4> = Vec::new();
|
||
hv.push(0).unwrap();
|
||
hv.push(1).unwrap();
|
||
|
||
let av: alloc::vec::Vec<u8> = hv.clone().try_into().unwrap();
|
||
assert_eq!(av.as_slice(), hv.as_slice());
|
||
}
|
||
|
||
#[test]
|
||
#[cfg(feature = "alloc")]
|
||
fn alloc_to_heapless() {
|
||
let mut av: alloc::vec::Vec<u8> = alloc::vec::Vec::new();
|
||
av.push(0);
|
||
av.push(1);
|
||
|
||
let hv: Vec<u8, 2> = av.clone().try_into().unwrap();
|
||
assert_eq!(hv.as_slice(), av.as_slice());
|
||
|
||
let _: crate::CapacityError =
|
||
<alloc::vec::Vec<u8> as TryInto<Vec<u8, 1>>>::try_into(av.clone()).unwrap_err();
|
||
}
|
||
|
||
fn _test_variance<'a: 'b, 'b>(x: Vec<&'a (), 42>) -> Vec<&'b (), 42> {
|
||
x
|
||
}
|
||
fn _test_variance_view<'a: 'b, 'b, 'c>(x: &'c VecView<&'a ()>) -> &'c VecView<&'b ()> {
|
||
x
|
||
}
|
||
}
|