This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/heapless/src/vec.rs
T
swaitsandClaude Opus 4.6 3102fc747a feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:42:54 -06:00

1582 lines
43 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use core::{cmp::Ordering, fmt, hash, iter::FromIterator, mem::MaybeUninit, ops, ptr, slice};
/// 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);
/// vec.push(2);
///
/// 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]);
/// ```
pub struct Vec<T, const N: usize> {
// NOTE order is important for optimizations. the `len` first layout lets the compiler optimize
// `new` to: reserve stack space and zero the first word. With the fields in the reverse order
// the compiler optimizes `new` to `memclr`-ing the *entire* stack space, including the `buffer`
// field which should be left uninitialized. Optimizations were last checked with Rust 1.60
len: usize,
buffer: [MaybeUninit<T>; N],
}
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();
/// ```
/// `Vec` `const` constructor; wrap the returned value in [`Vec`].
pub const fn new() -> Self {
Self {
len: 0,
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();
/// ```
#[inline]
pub fn from_slice(other: &[T]) -> Result<Self, ()>
where
T: Clone,
{
let mut v = Vec::new();
v.extend_from_slice(other)?;
Ok(v)
}
/// 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
}
/// Returns a raw pointer to the vector’s buffer.
pub fn as_ptr(&self) -> *const T {
self.buffer.as_ptr() as *const 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.as_mut_ptr() as *mut 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.as_ptr() as *const T, self.len) }
}
/// 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 { (&self.buffer as *const _ as *const [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)
}
}
/// 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();
/// buffer[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.as_mut_ptr() as *mut T, self.len) }
}
/// Returns the maximum number of elements the vector can hold.
pub const fn capacity(&self) -> usize {
N
}
/// 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<(), ()>
where
T: Clone,
{
if self.len + other.len() > self.capacity() {
// won't fit in the `Vec`; don't modify anything and return an error
Err(())
} else {
for elem in other {
unsafe {
self.push_unchecked(elem.clone());
}
}
Ok(())
}
}
/// 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.get_unchecked_mut(self.len).as_ptr() as *const T).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.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<(), ()>
where
T: Clone,
{
if new_len > self.capacity() {
return Err(());
}
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<(), ()>
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;
///// use heapless::consts::*;
///
/// 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
#[inline]
pub fn is_full(&self) -> bool {
self.len == self.capacity()
}
/// Returns true if the vec is empty
#[inline]
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);
/// ```
#[inline]
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);
/// ```
#[inline]
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, const N: usize> {
v: &'a mut Vec<T, N>,
processed_len: usize,
deleted_cnt: usize,
original_len: usize,
}
impl<T, const N: usize> Drop for BackshiftOnDrop<'_, T, N> {
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, const N: usize, const DELETED: bool>(
original_len: usize,
f: &mut F,
g: &mut BackshiftOnDrop<'_, T, N>,
) 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, N, false>(original_len, &mut f, &mut g);
// Stage 2: Some elements were deleted.
process_loop::<F, T, N, true>(original_len, &mut f, &mut g);
// All item are processed. This can be optimized to `set_len` by LLVM.
drop(g);
}
}
// Trait implementations
impl<T, const N: usize> Default for Vec<T, N> {
fn default() -> Self {
Self::new()
}
}
impl<T, const N: usize> fmt::Debug for Vec<T, N>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<[T] as fmt::Debug>::fmt(self, f)
}
}
impl<const N: usize> fmt::Write for Vec<u8, N> {
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> Drop for Vec<T, N> {
fn drop(&mut self) {
// We drop each element used in the vector by turning into a &mut[T]
unsafe {
ptr::drop_in_place(self.as_mut_slice());
}
}
}
impl<'a, T: Clone, const N: usize> TryFrom<&'a [T]> for Vec<T, N> {
type Error = ();
fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> {
Vec::from_slice(slice)
}
}
impl<T, const N: usize> Extend<T> for Vec<T, N> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
self.extend(iter)
}
}
impl<'a, T, const N: usize> Extend<&'a T> for Vec<T, N>
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, const N: usize> hash::Hash for Vec<T, N>
where
T: core::hash::Hash,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
<[T] as hash::Hash>::hash(self, state)
}
}
impl<'a, T, const N: usize> IntoIterator for &'a Vec<T, N> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, const N: usize> IntoIterator for &'a mut Vec<T, N> {
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 = Vec::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.get_unchecked_mut(self.next).as_ptr() as *const T).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.as_ptr() as *const 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, const N1: usize, const N2: usize> PartialEq<Vec<B, N2>> for Vec<A, N1>
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<B, N2>) -> bool {
<[A]>::eq(self, &**other)
}
}
// Vec<A, N> == [B]
impl<A, B, const N: usize> PartialEq<[B]> for Vec<A, N>
where
A: PartialEq<B>,
{
fn eq(&self, other: &[B]) -> bool {
<[A]>::eq(self, &other[..])
}
}
// [B] == Vec<A, N>
impl<A, B, const N: usize> PartialEq<Vec<A, N>> for [B]
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..])
}
}
// Vec<A, N> == &[B]
impl<A, B, const N: usize> PartialEq<&[B]> for Vec<A, N>
where
A: PartialEq<B>,
{
fn eq(&self, other: &&[B]) -> bool {
<[A]>::eq(self, &other[..])
}
}
// &[B] == Vec<A, N>
impl<A, B, const N: usize> PartialEq<Vec<A, N>> for &[B]
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..])
}
}
// Vec<A, N> == &mut [B]
impl<A, B, const N: usize> PartialEq<&mut [B]> for Vec<A, N>
where
A: PartialEq<B>,
{
fn eq(&self, other: &&mut [B]) -> bool {
<[A]>::eq(self, &other[..])
}
}
// &mut [B] == Vec<A, N>
impl<A, B, const N: usize> PartialEq<Vec<A, N>> for &mut [B]
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..])
}
}
// Vec<A, N> == [B; M]
// Equality does not require equal capacity
impl<A, B, const N: usize, const M: usize> PartialEq<[B; M]> for Vec<A, N>
where
A: PartialEq<B>,
{
fn eq(&self, other: &[B; M]) -> bool {
<[A]>::eq(self, &other[..])
}
}
// [B; M] == Vec<A, N>
// Equality does not require equal capacity
impl<A, B, const N: usize, const M: usize> PartialEq<Vec<A, N>> for [B; M]
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..])
}
}
// Vec<A, N> == &[B; M]
// Equality does not require equal capacity
impl<A, B, const N: usize, const M: usize> PartialEq<&[B; M]> for Vec<A, N>
where
A: PartialEq<B>,
{
fn eq(&self, other: &&[B; M]) -> bool {
<[A]>::eq(self, &other[..])
}
}
// &[B; M] == Vec<A, N>
// Equality does not require equal capacity
impl<A, B, const N: usize, const M: usize> PartialEq<Vec<A, N>> for &[B; M]
where
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<A, N>) -> bool {
<[A]>::eq(other, &self[..])
}
}
// Implements Eq if underlying data is Eq
impl<T, const N: usize> Eq for Vec<T, N> where T: Eq {}
impl<T, const N1: usize, const N2: usize> PartialOrd<Vec<T, N2>> for Vec<T, N1>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Vec<T, N2>) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<T, const N: usize> Ord for Vec<T, N>
where
T: Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<T, const N: usize> ops::Deref for Vec<T, N> {
type Target = [T];
fn deref(&self) -> &[T] {
self.as_slice()
}
}
impl<T, const N: usize> ops::DerefMut for Vec<T, N> {
fn deref_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
impl<T, const N: usize> AsRef<Vec<T, N>> for Vec<T, N> {
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl<T, const N: usize> AsMut<Vec<T, N>> for Vec<T, N> {
#[inline]
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T, const N: usize> AsRef<[T]> for Vec<T, N> {
#[inline]
fn as_ref(&self) -> &[T] {
self
}
}
impl<T, const N: usize> AsMut<[T]> for Vec<T, N> {
#[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 crate::Vec;
use core::fmt::Write;
#[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 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).err().expect("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 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());
}
}