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
///
/// ```ignore
///
///
/// // 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> {
buffer: [MaybeUninit<T>; N],
len: usize,
}
impl<T, const N: usize> Vec<T, N> {
const INIT: MaybeUninit<T> = MaybeUninit::uninit();
/// Constructs a new, empty vector with a fixed capacity of `N`
///
/// # Examples
///
/// ```ignore
///
/// // 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`](../struct.Vec.html)
pub const fn new() -> Self {
// Const assert N > 0
super::greater_than_0::<N>();
Self {
buffer: [Self::INIT; N],
len: 0,
}
}
/// Constructs a new vector with a fixed capacity of `N` and fills it
/// with the provided slice.
///
/// This is equivalent to the following code:
///
/// ```ignore
///
/// 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();
new.extend_from_slice(self.as_slice()).unwrap();
new
}
/// Extracts a slice containing the entire vector.
///
/// Equivalent to `&s[..]`.
///
/// # Examples
///
/// ```ignore
/// 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
///
/// ```ignore
/// 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 `&s[..]`.
///
/// # Examples
///
/// ```ignore
/// 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(crate) 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
///
/// ```ignore
///
/// 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) {
// drop any extra elements
while len < self.len {
// decrement len before the drop_in_place(), so a panic on Drop
// doesn't re-drop the just-failed value.
self.len -= 1;
let len = self.len;
unsafe { ptr::drop_in_place(self.as_mut_slice().get_unchecked_mut(len)) };
}
}
/// 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`](struct.Vec.html#method.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`](struct.Vec.html#method.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`]: #method.truncate
/// [`resize`]: #method.resize
/// [`extend`]: https://doc.rust-lang.org/stable/core/iter/trait.Extend.html#tymethod.extend
/// [`clear`]: #method.clear
///
/// # Safety
///
/// - `new_len` must be less than or equal to [`capacity()`].
/// - The elements at `old_len..new_len` must be initialized.
///
/// [`capacity()`]: #method.capacity
///
/// # Examples
///
/// This method can be useful for situations in which the vector
/// is serving as a buffer for other code, particularly over FFI:
///
/// ```ignore
/// # #![allow(dead_code)]
///
/// # // 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:
///
/// ```ignore
/// use core::iter::FromIterator;
///
/// 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
///
/// ```ignore
///
/// 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
///
/// ```ignore
///
/// 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);
ptr::swap(
self.as_mut_slice().get_unchecked_mut(index),
self.as_mut_slice().get_unchecked_mut(length - 1),
);
self.pop_unchecked()
}
/// 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
///
/// ```ignore
///
/// 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
///
/// ```ignore
///
/// 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..]
}
}
// 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<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`].
///
/// [`Vec`]: (https://doc.rust-lang.org/std/vec/struct.Vec.html)
///
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)
}
}
// 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[..])
}
}
// 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[..])
}
}
// 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[..])
}
}
// 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[..])
}
}
// 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 super::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());
}
macro_rules! droppable {
() => {
struct Droppable;
impl Droppable {
fn new() -> Self {
unsafe {
COUNT += 1;
}
Droppable
}
}
impl Drop for Droppable {
fn drop(&mut self) {
unsafe {
COUNT -= 1;
}
}
}
static mut COUNT: i32 = 0;
};
}
#[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!(unsafe { COUNT }, 0);
{
let mut v: Vec<Droppable, 2> = Vec::new();
v.push(Droppable::new()).ok().unwrap();
v.push(Droppable::new()).ok().unwrap();
}
assert_eq!(unsafe { 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 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!(unsafe { 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!(unsafe { 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!(unsafe { 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 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"));
}
}