use alloc::boxed::Box;
use alloc::format;
use alloc::vec::Vec;
use bumpish::BumpVec;
use core::sync::atomic::{AtomicUsize, Ordering};
use pretty_assertions::{assert_eq, assert_ne};
type BumpVec0<T> = BumpVec<T, 0>;
#[test]
fn vec_ctor() {
let v = BumpVec0::<i32>::new();
assert_eq!(v.capacity(), 0);
assert_eq!(v.len(), 0);
let v = BumpVec0::<i32>::default();
assert_eq!(v.capacity(), 0);
assert_eq!(v.len(), 0);
let v = BumpVec0::<()>::default();
assert_eq!(v.capacity(), usize::MAX);
assert_eq!(v.len(), 0);
let v = BumpVec0::<i32>::with_capacity(10);
assert!(v.capacity() >= 10);
assert_eq!(v.len(), 0);
let v = BumpVec0::<()>::with_capacity(10);
assert_eq!(v.capacity(), usize::MAX);
assert_eq!(v.len(), 0);
let v = BumpVec0::from([Box::new(1), Box::new(2), Box::new(4)]);
assert!(v.capacity() >= 3);
assert_eq!(v.len(), 3);
let v = BumpVec0::from(&[1, 2, 4]);
assert!(v.capacity() >= 3);
assert_eq!(v.len(), 3);
let v = BumpVec0::from(&mut [1, 2, 4]);
assert!(v.capacity() >= 3);
assert_eq!(v.len(), 3);
let v = BumpVec0::from([1, 2, 4].as_slice());
assert!(v.capacity() >= 3);
assert_eq!(v.len(), 3);
let v = BumpVec0::from([1, 2, 4].as_mut_slice());
assert!(v.capacity() >= 3);
assert_eq!(v.len(), 3);
let v = BumpVec::<i32, 0>::new();
assert_eq!(v.len(), 0);
assert_eq!(v.capacity(), 0);
let v = BumpVec::<i32, 1>::new();
assert_eq!(v.len(), 0);
assert_eq!(v.capacity(), 1);
let v = BumpVec::<i32, 20>::new();
assert_eq!(v.len(), 0);
assert_eq!(v.capacity(), 20);
let v = BumpVec::<(), 20>::new();
assert_eq!(v.len(), 0);
assert_eq!(v.capacity(), usize::MAX);
}
#[test]
fn vec_push_pop() {
let mut vec = BumpVec0::default();
const MAX: usize = 1 << 10;
for i in 0..MAX {
assert_eq!(vec.len(), i);
vec.push(i);
}
for i in (0..MAX).rev() {
assert_eq!(vec.pop(), Some(i));
}
assert_eq!(vec.len(), 0);
assert!(vec.len() < vec.capacity());
let vec = BumpVec0::default();
vec.push(42);
let mut vec = BumpVec0::<u8>::default();
assert_eq!(vec.pop(), None);
}
#[test]
fn vec_push_mut() {
let mut vec = BumpVec0::from([1, 2]);
let last = vec.push_mut(3);
assert_eq!(*last, 3);
assert_eq!(vec, [1, 2, 3]);
let last = vec.push_mut(3);
*last += 1;
assert_eq!(vec, [1, 2, 3, 4]);
}
#[test]
fn vec_push_mut_zst() {
let mut vec = BumpVec0::from([(), ()]);
let last = vec.push_mut(());
assert_eq!(*last, ());
*last = ();
assert_eq!(vec, [(), (), ()]);
}
#[test]
fn vec_push_pop_zst() {
let mut vec = BumpVec0::default();
assert_eq!(vec.capacity(), usize::MAX);
const MAX: usize = 1 << 8;
for i in 0..MAX {
assert_eq!(vec.len(), i);
vec.push(());
}
for i in (0..MAX).rev() {
assert_eq!(vec.len(), i + 1);
assert_eq!(vec.pop(), Some(()));
}
assert_eq!(vec.len(), 0);
let vec = BumpVec0::default();
vec.push(());
}
#[test]
fn vec_push_pop_if() {
let mut vec = BumpVec0::from([1, 2, 3, 4]);
let pred = |x: &mut i32| *x % 2 == 0;
assert_eq!(vec.pop_if(pred), Some(4));
assert_eq!(vec, [1, 2, 3]);
assert_eq!(vec.pop_if(pred), None);
vec.clear();
assert_eq!(vec.pop_if(|_| true), None);
}
#[test]
fn vec_swap_remove() {
let mut v = BumpVec::<&str, 0>::from(["foo", "bar", "baz", "qux"]);
assert_eq!(v.swap_remove(1), "bar");
assert_eq!(v[1], "qux");
assert_eq!(v.swap_remove(0), "foo");
assert_eq!(v, ["baz", "qux"]);
let mut v = BumpVec::<(), 0>::from([(), (), (), ()]);
assert_eq!(v.swap_remove(1), ());
assert_eq!(v[1], ());
assert_eq!(v.swap_remove(0), ());
assert_eq!(v, [(), ()]);
}
#[test]
#[should_panic(expected = "swap_remove index (is 3) should be less than len (is 3)")]
fn vec_swap_remove_fails() {
let mut vec = BumpVec0::from([1, 2, 3]);
vec.swap_remove(3);
}
#[test]
fn vec_clear() {
let mut vec = BumpVec0::from([1, 3, 4]);
assert!(!vec.is_empty());
assert_eq!(vec.len(), 3);
assert!(vec.capacity() >= 3);
vec.clear();
assert!(vec.is_empty());
assert_eq!(vec.len(), 0);
assert!(vec.capacity() >= 3);
let mut vec = BumpVec::<_, 2>::from([1, 3, 4]);
assert!(!vec.is_empty());
assert_eq!(vec.len(), 3);
assert!(vec.capacity() >= 3);
vec.clear();
assert!(vec.is_empty());
assert_eq!(vec.len(), 0);
assert!(vec.capacity() >= 3);
let mut vec = BumpVec0::from([(), (), ()]);
assert!(!vec.is_empty());
assert_eq!(vec.len(), 3);
assert!(vec.capacity() >= 3);
vec.clear();
assert!(vec.is_empty());
assert_eq!(vec.len(), 0);
assert!(vec.capacity() >= 3);
}
#[test]
fn vec_clear_zst() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
struct Zst;
impl core::ops::Drop for Zst {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
let mut core = BumpVec::<Zst, 4>::new();
core.push(Zst);
assert_eq!(core.len(), 1);
core.clear();
assert_eq!(core.len(), 0);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 1);
for _ in 0..5 {
core.push(Zst);
}
assert_eq!(core.len(), 5);
core.clear();
assert_eq!(core.len(), 0);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 1 + 5);
}
#[test]
fn vec_contains() {
let mut vec = BumpVec::<_, 1>::new();
assert!(!vec.contains(&5));
vec.push(5);
assert!(vec.contains(&5));
vec.push(10);
assert!(vec.contains(&5));
assert!(vec.contains(&10));
vec.pop();
assert!(vec.contains(&5));
assert!(!vec.contains(&10));
vec.pop();
assert!(!vec.contains(&5));
assert!(!vec.contains(&10));
}
#[test]
fn vec0_first() {
let mut vec = BumpVec0::default();
assert_eq!(vec.first(), None);
vec.push(42);
assert_eq!(vec.first(), Some(&42));
vec.push(24);
assert_eq!(vec.first_mut(), Some(&mut 42));
vec.pop();
assert_eq!(vec.first(), Some(&42));
vec.pop();
assert_eq!(vec.first(), None);
vec.pop();
assert_eq!(vec.first_mut(), None);
}
#[test]
fn vec_n_first() {
let mut vec = BumpVec::<_, 4>::default();
assert_eq!(vec.first(), None);
vec.push(42);
assert_eq!(vec.first(), Some(&42));
vec.push(24);
assert_eq!(vec.first_mut(), Some(&mut 42));
vec.pop();
assert_eq!(vec.first(), Some(&42));
vec.pop();
assert_eq!(vec.first(), None);
vec.pop();
assert_eq!(vec.first_mut(), None);
}
#[test]
fn vec_first_zst() {
let mut vec = BumpVec0::<()>::default();
assert_eq!(vec.first(), None);
vec.push(());
assert_eq!(vec.first(), Some(&()));
vec.push(());
assert_eq!(vec.first(), Some(&()));
vec.pop();
assert_eq!(vec.first(), Some(&()));
vec.pop();
assert_eq!(vec.first(), None);
vec.pop();
assert_eq!(vec.first(), None);
}
#[test]
fn vec_first_mut() {
let mut vec = BumpVec0::default();
assert_eq!(vec.first_mut(), None);
vec.push(42);
assert_eq!(vec.first_mut(), Some(&mut 42));
if let Some(first) = vec.first_mut() {
assert_eq!(first, &mut 42);
*first = 24;
}
assert_eq!(vec.first_mut(), Some(&mut 24));
}
#[test]
fn vec_last() {
let mut vec = BumpVec0::default();
assert_eq!(vec.last(), None);
vec.push(0);
let capacity = vec.capacity();
for i in 1..capacity + 1 {
vec.push(i);
assert_eq!(vec.last(), Some(&i));
}
for i in (0..capacity + 1).rev() {
assert_eq!(vec.last(), Some(&i));
vec.pop();
}
assert_eq!(vec.last(), None);
let mut vec = BumpVec::<_, 3>::default();
assert_eq!(vec.last(), None);
vec.push(0);
let capacity = vec.capacity();
for i in 1..capacity + 1 {
vec.push(i);
assert_eq!(vec.last(), Some(&i));
}
for i in (0..capacity + 1).rev() {
assert_eq!(vec.last(), Some(&i));
vec.pop();
}
assert_eq!(vec.last(), None);
}
#[test]
fn vec_last_zst() {
let mut vec = BumpVec0::<()>::default();
assert_eq!(vec.last(), None);
vec.push(());
assert_eq!(vec.last(), Some(&()));
vec.pop();
assert_eq!(vec.last(), None);
}
#[test]
fn vec_last_mut() {
let mut vec = BumpVec0::new();
assert_eq!(None, vec.last_mut());
vec.push(5);
assert_eq!(Some(&mut 5), vec.last_mut());
if let Some(last) = vec.last_mut() {
*last = 10;
}
assert_eq!(Some(&mut 10), vec.last_mut());
vec.pop();
assert_eq!(None, vec.last_mut());
let mut capacity = vec.capacity();
for mut i in 0..capacity + 1 {
vec.push(i);
assert_eq!(vec.last_mut(), Some(&mut i));
}
assert_eq!(vec.last_mut(), Some(&mut capacity));
vec.pop();
assert_eq!(vec.last_mut(), Some(&mut (capacity - 1)));
}
#[test]
fn vec_get() {
let mut vec = BumpVec::<_, 2>::from([1, 2, 3]);
assert_eq!(vec.get(0), Some(&1));
assert_eq!(vec.get(1), Some(&2));
assert_eq!(vec.get(2), Some(&3));
*vec.get_mut(0).unwrap() *= 2;
*vec.get_mut(1).unwrap() *= 2;
*vec.get_mut(2).unwrap() *= 2;
assert_eq!(vec.get(0), Some(&2));
assert_eq!(vec.get(1), Some(&4));
assert_eq!(vec.get(2), Some(&6));
assert_eq!(vec.get(3), None);
let capacity = vec.capacity();
for i in vec.len()..=capacity {
assert_eq!(vec.push(i), &i);
}
assert!(capacity < vec.capacity());
assert_eq!(vec.get(vec.len() - 1), Some(&capacity));
let mut vec = BumpVec::<(), 2>::new();
assert_eq!(vec.push(()), &());
assert_eq!(vec.get_mut(0), Some(&mut ()));
assert_eq!(vec.get_mut(2), None);
}
#[test]
fn vec0_iter() {
let vec = BumpVec0::new();
vec.push(0);
let capacity_1 = vec.capacity();
for i in 1..capacity_1 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_1);
assert_eq!(
vec.iter().fold(0, |len, elem| {
assert_eq!(*elem, len);
len + 1
}),
vec.len(),
);
let mut len = vec.len();
for elem in vec.iter().rev() {
assert_eq!(*elem, len - 1);
len -= 1;
}
assert_eq!(len, 0);
vec.push(capacity_1);
let mut iter = vec.iter();
for _ in 0..capacity_1 {
iter.next();
}
assert_eq!(iter.next_back(), Some(&capacity_1));
assert_eq!(iter.next_back(), None);
let capacity_12 = vec.capacity();
for i in capacity_1 + 1..capacity_12 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_12);
assert_eq!(
vec.iter().fold(0, |len, elem| {
assert_eq!(*elem, len);
len + 1
}),
vec.len(),
);
let mut len = vec.len();
for elem in vec.iter().rev() {
assert_eq!(*elem, len - 1);
len -= 1;
}
assert_eq!(len, 0);
let mut iter = vec.iter();
for _ in 0..capacity_12 - capacity_1 {
iter.next();
}
for _ in 0..capacity_1 {
iter.next_back();
}
assert_eq!(iter.next_back(), None);
let len_before = vec.len();
for elem in vec.iter().rev() {
vec.push(*elem);
}
let len_after = vec.len();
assert_eq!(2 * len_before, len_after);
let mut count = 0;
let mut iter = vec.iter();
while let Some(l_elem) = iter.next()
&& let Some(r_elem) = iter.next_back()
{
assert_eq!(l_elem, r_elem);
count += 1;
}
assert_eq!(iter.next(), None);
assert_eq!(iter.next_back(), None);
assert_eq!(iter.next_back(), None);
assert_eq!(count, vec.len() / 2);
}
#[test]
fn vec_n_iter() {
let vec = BumpVec::<_, 3>::new();
vec.push(0);
let capacity_1 = vec.capacity();
for i in 1..capacity_1 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_1);
assert_eq!(
vec.iter().fold(0, |len, elem| {
assert_eq!(*elem, len);
len + 1
}),
vec.len(),
);
let mut len = vec.len();
for elem in vec.iter().rev() {
assert_eq!(*elem, len - 1);
len -= 1;
}
assert_eq!(len, 0);
vec.push(capacity_1);
let mut iter = vec.iter();
for _ in 0..capacity_1 {
iter.next();
}
assert_eq!(iter.next_back(), Some(&capacity_1));
assert_eq!(iter.next_back(), None);
let capacity_12 = vec.capacity();
for i in capacity_1 + 1..capacity_12 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_12);
assert_eq!(
vec.iter().fold(0, |len, elem| {
assert_eq!(*elem, len);
len + 1
}),
vec.len(),
);
let mut len = vec.len();
for elem in vec.iter().rev() {
assert_eq!(*elem, len - 1);
len -= 1;
}
assert_eq!(len, 0);
let mut iter = vec.iter();
for _ in 0..capacity_12 - capacity_1 {
iter.next();
}
for _ in 0..capacity_1 {
iter.next_back();
}
assert_eq!(iter.next_back(), None);
let len_before = vec.len();
for elem in vec.iter().rev() {
vec.push(*elem);
}
let len_after = vec.len();
assert_eq!(2 * len_before, len_after);
let mut count = 0;
let mut iter = vec.iter();
while let Some(l_elem) = iter.next()
&& let Some(r_elem) = iter.next_back()
{
assert_eq!(l_elem, r_elem);
count += 1;
}
assert_eq!(iter.next(), None);
assert_eq!(iter.next_back(), None);
assert_eq!(count, vec.len() / 2);
}
#[test]
fn vec_iter_zst() {
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
let count = vec.iter().fold(0, |count, _| count + 1);
assert_eq!(vec.len(), count);
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
let count = vec.iter().rev().fold(0, |count, _| count + 1);
assert_eq!(vec.len(), count);
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
let mut iter = vec.iter();
assert_eq!((4, Some(4)), iter.size_hint());
iter.next_back();
assert_eq!((3, Some(3)), iter.size_hint());
iter.next();
assert_eq!((2, Some(2)), iter.size_hint());
iter.next_back();
assert_eq!((1, Some(1)), iter.size_hint());
iter.next();
assert_eq!((0, Some(0)), iter.size_hint());
iter.next_back();
assert_eq!((0, Some(0)), iter.size_hint());
}
#[test]
fn vec_iter_count() {
let vec = BumpVec::<_, 0>::from([1, 2, 4, 7]);
for i in 0..vec.capacity() {
vec.push(i);
}
assert_eq!(vec.len(), vec.iter().count());
let mut iter = vec.iter();
iter.next();
iter.next_back();
assert_eq!(vec.len() - 2, iter.count());
let vec = BumpVec::<_, 3>::from([1, 2, 4, 7]);
for i in 0..vec.capacity() {
vec.push(i);
}
assert_eq!(vec.len(), vec.iter().count());
let mut iter = vec.iter();
iter.next();
assert_eq!(vec.len() - 1, iter.count());
let vec = BumpVec::<_, 0>::new();
vec.push(());
vec.push(());
vec.push(());
vec.push(());
assert_eq!(4, vec.iter().count());
}
#[test]
fn vec_iter_size_hint() {
let vec = BumpVec::<_, 4>::from([1, 2, 4, 7]);
assert_eq!((0, None), vec.iter().size_hint());
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
assert_eq!((4, Some(4)), vec.iter().size_hint());
}
#[test]
fn vec_iter_last() {
let vec = BumpVec::<_, 0>::from(&[1, 2, 3]);
assert_eq!(vec.iter().last(), Some(&3));
let vec = BumpVec::<_, 1>::from(&[(), (), ()]);
assert_eq!(vec.iter().last(), Some(&()));
let vec = BumpVec::<u8, 1>::from(&[]);
assert_eq!(vec.iter().last(), None);
let vec = BumpVec::<(), 0>::from(&[]);
assert_eq!(vec.iter().last(), None);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn vec_iter_nth_zst() {
let vec = BumpVec::<(), 2>::new();
vec.push(());
vec.push(());
vec.push(());
vec.push(());
let mut iter = vec.iter();
assert_eq!(iter.nth(1), Some(&()));
assert_eq!(iter.nth(1), Some(&()));
assert_eq!(iter.nth(0), None);
let vec = BumpVec::<(), 0>::new();
vec.push(());
vec.push(());
vec.push(());
vec.push(());
let mut iter = vec.iter();
assert_eq!(iter.nth(1), Some(&()));
assert_eq!(iter.nth(1), Some(&()));
assert_eq!(iter.nth(0), None);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn vec_iter_nth() {
let mut vec = BumpVec::<_, 5>::new();
let capacity = vec.capacity();
vec.push(0);
for i in 1..capacity {
vec.push(i);
}
{
let mut iter = vec.iter();
assert_eq!(iter.nth(1), Some(&1));
assert_eq!(iter.nth(1), Some(&3));
assert_eq!(iter.nth(capacity), None);
let mut iter = vec.iter();
assert_eq!(iter.nth(capacity - 1), Some(&(capacity - 1)));
let mut iter = vec.iter();
assert_eq!(iter.nth(capacity), None);
vec.push(capacity);
assert!(vec.capacity() > capacity);
let mut iter = vec.iter();
assert_eq!(iter.nth(1), Some(&(1)));
assert_eq!(iter.nth(1), Some(&(3)));
assert_eq!(iter.nth(capacity), None);
let mut iter = vec.iter();
assert_eq!(iter.nth(capacity), Some(&(capacity)));
assert_eq!(iter.nth(0), None);
}
vec.pop();
assert_eq!(vec.len(), capacity);
assert_ne!(vec.capacity(), capacity);
let mut iter = vec.iter();
assert_eq!(iter.nth(1), Some(&1));
assert_eq!(iter.nth(1), Some(&3));
assert_eq!(iter.nth(capacity - 4), None);
}
#[test]
#[allow(clippy::iter_nth_zero)]
fn vec_iter_rev_nth() {
let mut vec = BumpVec::<_, 0>::new();
vec.push(0);
let capacity = vec.capacity();
for i in 1..capacity {
vec.push(i);
}
{
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(1), Some(&(capacity - 2)));
assert_eq!(iter.nth(1), Some(&(capacity - 4)));
assert_eq!(iter.nth(capacity), None);
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(capacity - 1), Some(&0));
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(capacity), None);
vec.push(capacity);
assert!(vec.capacity() > capacity);
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(1), Some(&(capacity - 1)));
assert_eq!(iter.nth(1), Some(&(capacity - 3)));
assert_eq!(iter.nth(capacity), None);
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(capacity), Some(&0));
assert_eq!(iter.nth(0), None);
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(0), Some(&capacity));
assert_eq!(iter.nth(0), Some(&(capacity - 1)));
}
vec.pop();
assert_eq!(vec.len(), capacity);
assert_ne!(vec.capacity(), capacity);
let mut iter = vec.iter().rev();
assert_eq!(iter.nth(1), Some(&(capacity - 2)));
assert_eq!(iter.nth(1), Some(&(capacity - 4)));
assert_eq!(iter.nth(capacity - 4), None);
}
#[test]
fn vec_iter_mut() {
let mut vec = BumpVec::<_, 3>::from([1, 2, 4]);
for elem in &mut vec {
*elem *= 2;
}
assert_eq!(&vec, &[2, 4, 8]);
for elem in vec.iter_mut().rev() {
*elem *= 2;
}
assert_eq!(&vec, &[4, 8, 16]);
}
#[test]
fn vec_chunks_zst() {
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
let mut iter = vec.chunks();
assert_eq!(iter.next(), Some([(), (), (), ()].as_slice()));
assert_eq!(iter.next(), None);
let mut iter = vec.chunks();
assert_eq!(iter.next_back(), Some([(), (), (), ()].as_slice()));
assert_eq!(iter.next_back(), None);
}
#[test]
fn vec0_chunks() {
let mut vec = BumpVec::<_, 0>::new();
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 0);
vec.push(0);
let capacity_1 = vec.capacity();
for i in 1..capacity_1 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_1);
let slice = vec.chunks().next().unwrap();
assert_eq!(slice.len(), capacity_1);
let slice = vec.chunks().next_back().unwrap();
assert_eq!(slice.len(), capacity_1);
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
for slice in vec.chunks() {
vec.push(slice.last().unwrap() + 1);
}
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 2);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 1);
assert_eq!(slices[1], [capacity_1]);
let slices = vec.chunks().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 2);
assert_eq!(slices[0], [capacity_1]);
assert_eq!(*slices[1].last().unwrap(), capacity_1 - 1);
vec.pop();
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(slices[0], (0..capacity_1).collect::<Vec<_>>());
let slices = vec.chunks().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 1);
vec.pop();
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 2);
let slices = vec.chunks().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 2);
}
#[test]
fn vec_n_chunks_mut() {
let mut vec = BumpVec::<_, 3>::new();
let slices = vec.chunks().collect::<Vec<_>>();
assert_eq!(slices.len(), 0);
vec.push(0);
let capacity_1 = vec.capacity();
for i in 1..capacity_1 {
vec.push(i);
}
assert_eq!(vec.len(), capacity_1);
let slice = vec.chunks_mut().next().unwrap();
assert_eq!(slice.len(), capacity_1);
let slice = vec.chunks_mut().next_back().unwrap();
assert_eq!(slice.len(), capacity_1);
let slices = vec.chunks_mut().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
for slice in vec.chunks() {
vec.push(*slice.last().unwrap() + 1);
}
let slices = vec.chunks_mut().collect::<Vec<_>>();
assert_eq!(slices.len(), 2);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 1);
assert_eq!(slices[1], [capacity_1]);
let slices = vec.chunks_mut().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 2);
assert_eq!(slices[0], [capacity_1]);
assert_eq!(*slices[1].last().unwrap(), capacity_1 - 1);
vec.pop();
let slices = vec.chunks_mut().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 1);
let slices = vec.chunks_mut().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 1);
vec.pop();
let slices = vec.chunks_mut().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 2);
let slices = vec.chunks_mut().rev().collect::<Vec<_>>();
assert_eq!(slices.len(), 1);
assert_eq!(*slices[0].last().unwrap(), capacity_1 - 2);
}
#[test]
fn vec_clone() {
let vec = BumpVec::<_, 2>::from([1, 2, 3, 4]);
assert_eq!(vec, [1, 2, 3, 4]);
assert_eq!(vec.clone(), [1, 2, 3, 4]);
assert_eq!(&vec.clone(), &vec);
}
#[test]
fn vec_from_iter() {
let vec = BumpVec::<_, 1>::from_iter([10, 40, 30]);
assert_eq!(vec, [10, 40, 30]);
}
macro_rules! def_item {
() => {
static NEW_COUNTER: AtomicUsize = AtomicUsize::new(0);
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
struct Item(usize);
impl Item {
fn new() -> Self {
Self(NEW_COUNTER.fetch_add(1, Ordering::Relaxed))
}
}
impl core::ops::Drop for Item {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
};
}
#[test]
fn vec_into_iter_inlined_0() {
def_item!();
let vec = BumpVec::<Item, 3>::new();
vec.push(Item::new());
vec.push(Item::new());
assert_eq!(vec.last().unwrap().0, 1);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 2);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let mut i = 0;
for item in vec {
assert_eq!(item.0, i);
assert_eq!(i, DROP_COUNTER.load(Ordering::Relaxed));
i += 1;
drop(item);
}
assert_eq!(i, 2);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 2);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 2);
}
#[test]
fn vec_into_iter_inlined_1() {
def_item!();
let vec = BumpVec::<Item, 3>::new();
vec.push(Item::new());
vec.push(Item::new());
assert_eq!(vec.last().unwrap().0, 1);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 2);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
drop(vec.into_iter());
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 2);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 2);
}
#[test]
fn vec0_into_iter_0() {
def_item!();
let vec = BumpVec::<Item, 0>::new();
vec.push(Item::new());
let capacity0 = vec.capacity();
assert!(1 <= capacity0);
for _ in 1..=capacity0 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity0);
let capacity01 = vec.capacity();
for _ in capacity0 + 1..=capacity01 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity01);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity01 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let mut i = 0;
for item in vec {
assert_eq!(item.0, i);
assert_eq!(i, DROP_COUNTER.load(Ordering::Relaxed));
i += 1;
}
assert_eq!(i, capacity01 + 1);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity01 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), capacity01 + 1);
}
#[test]
fn vec_into_iter_0() {
def_item!();
let vec = BumpVec::<Item, 3>::new();
let capacity0 = vec.capacity();
assert_eq!(capacity0, 3);
for _ in 0..=capacity0 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity0);
let capacity01 = vec.capacity();
for _ in capacity0 + 1..=capacity01 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity01);
let capacity012 = vec.capacity();
for _ in capacity01 + 1..=capacity012 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity012);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let mut i = 0;
for item in vec {
assert_eq!(item.0, i);
assert_eq!(i, DROP_COUNTER.load(Ordering::Relaxed));
i += 1;
drop(item);
}
assert_eq!(i, capacity012 + 1);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
}
#[test]
fn vec_into_iter_1() {
def_item!();
let vec = BumpVec::<Item, 3>::new();
let capacity0 = vec.capacity();
assert_eq!(capacity0, 3);
for _ in 0..=capacity0 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity0);
let capacity01 = vec.capacity();
for _ in capacity0 + 1..capacity01 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity01 - 1);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity01);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
drop(vec.into_iter());
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity01);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), capacity01);
}
#[test]
fn vec_into_iter_2() {
def_item!();
let vec = BumpVec::<Item, 3>::new();
let capacity0 = vec.capacity();
assert_eq!(capacity0, 3);
for _ in 0..=capacity0 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity0);
let capacity01 = vec.capacity();
for _ in capacity0 + 1..=capacity01 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity01);
let capacity012 = vec.capacity();
for _ in capacity01 + 1..=capacity012 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity012);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let iter = vec.into_iter();
assert_eq!(iter.size_hint(), (0, None));
drop(iter);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
}
#[test]
fn vec_into_iter_back() {
static NEW_COUNTER: AtomicUsize = AtomicUsize::new(0);
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
struct Item(usize);
impl Item {
fn new() -> Self {
Self(NEW_COUNTER.fetch_add(1, Ordering::Relaxed))
}
}
impl core::ops::Drop for Item {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
let vec = BumpVec::<Item, 3>::new();
let capacity0 = vec.capacity();
assert_eq!(capacity0, 3);
for _ in 0..=capacity0 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity0);
let capacity01 = vec.capacity();
for _ in capacity0 + 1..=capacity01 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity01);
let capacity012 = vec.capacity();
for _ in capacity01 + 1..=capacity012 {
vec.push(Item::new());
}
assert_eq!(vec.last().unwrap().0, capacity012);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), capacity012 + 1);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let len = vec.len();
let mut i = 0;
for item in vec.into_iter().rev() {
assert_eq!(item.0, len - i - 1);
assert_eq!(i, DROP_COUNTER.load(Ordering::Relaxed));
i += 1;
drop(item);
}
assert_eq!(i, capacity012 + 1);
assert_eq!(
NEW_COUNTER.load(Ordering::Relaxed),
DROP_COUNTER.load(Ordering::Relaxed)
);
}
#[test]
fn vec_into_iter_zst() {
static NEW_COUNTER: AtomicUsize = AtomicUsize::new(0);
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, PartialEq)]
struct Zst;
impl Zst {
fn new() -> Self {
NEW_COUNTER.fetch_add(1, Ordering::Relaxed);
Self
}
}
impl Drop for Zst {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
let vec = BumpVec::<_, 4>::from([(), (), (), ()]);
let mut iter = vec.into_iter();
assert_eq!(iter.size_hint(), (4, Some(4)));
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.size_hint(), (3, Some(3)));
assert_eq!(iter.next_back(), Some(()));
assert_eq!(iter.size_hint(), (2, Some(2)));
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.size_hint(), (1, Some(1)));
assert_eq!(iter.next_back(), Some(()));
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next(), None);
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next_back(), None);
assert_eq!(iter.size_hint(), (0, Some(0)));
NEW_COUNTER.store(0, Ordering::Relaxed);
DROP_COUNTER.store(0, Ordering::Relaxed);
let vec = BumpVec::<Zst, 4>::new();
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let iter = vec.into_iter();
drop(iter);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 4);
NEW_COUNTER.store(0, Ordering::Relaxed);
DROP_COUNTER.store(0, Ordering::Relaxed);
let vec = BumpVec::<Zst, 4>::new();
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let mut iter = vec.into_iter();
let _ = iter.next();
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 1);
drop(iter);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 4);
NEW_COUNTER.store(0, Ordering::Relaxed);
DROP_COUNTER.store(0, Ordering::Relaxed);
let vec = BumpVec::<Zst, 4>::new();
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
vec.push(Zst::new());
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
let mut iter = vec.into_iter();
let _ = iter.next();
let _ = iter.next();
let _ = iter.next();
let _ = iter.next();
assert_eq!(iter.next(), None);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 4);
drop(iter);
assert_eq!(NEW_COUNTER.load(Ordering::Relaxed), 4);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 4);
}
#[test]
fn vec_partial_eq() {
let vec = BumpVec::<_, 2>::from(&[1, 2, 3]);
assert_eq!(vec, [1, 2, 3]);
assert_eq!(vec, &[1, 2, 3]);
assert_eq!(vec, &mut [1, 2, 3]);
assert_eq!([1, 2, 3], vec);
assert_eq!(&[1, 2, 3], vec);
assert_eq!(&mut [1, 2, 3], vec);
assert_eq!(vec, [1, 2, 3].as_slice());
assert_eq!(vec, [1, 2, 3].as_mut_slice());
assert_ne!(vec, [1, 2, 5]);
assert_ne!(vec, &[1, 2, 5]);
assert_ne!(vec, &mut [1, 2, 5]);
assert_ne!([1, 2, 5], vec);
assert_ne!(&[1, 2, 5], vec);
assert_ne!(&mut [1, 2, 5], vec);
assert_ne!(vec, [1, 2, 3, 4]);
assert_ne!(vec, &[1, 2, 3, 4]);
assert_ne!(vec, &mut [1, 2, 3, 4]);
assert_ne!([1, 2, 3, 4], vec);
assert_ne!(&[1, 2, 3, 4], vec);
assert_ne!(&mut [1, 2, 3, 4], vec);
let vec2 = BumpVec::<_, 0>::from(&[1, 2, 3]);
assert_eq!(vec, vec2);
}
#[test]
fn vec_debug_fmt() {
let mut vec = BumpVec::<_, 2>::from(&[1, 2, 3]);
assert_eq!(format!("{vec:?}"), "[1, 2, 3]");
vec.push(4);
assert_eq!(format!("{vec:?}"), "[1, 2, 3, 4]");
vec.push(5);
assert_eq!(format!("{vec:?}"), "[1, 2, 3, 4, 5]");
vec.pop();
assert_eq!(format!("{vec:?}"), "[1, 2, 3, 4]");
vec.pop();
assert_eq!(format!("{vec:?}"), "[1, 2, 3]");
}
#[test]
fn vec_index() {
let mut vec = BumpVec::<_, 2>::from([1, 2, 3]);
assert_eq!(vec[0], 1);
assert_eq!(vec[1], 2);
assert_eq!(vec[2], 3);
vec[0] *= 2;
vec[1] *= 2;
vec[2] *= 2;
assert_eq!(vec[0], 2);
assert_eq!(vec[1], 4);
assert_eq!(vec[2], 6);
let capacity = vec.capacity();
for i in vec.len()..=capacity {
assert_eq!(vec.push(i), &i);
}
assert!(capacity < vec.capacity());
assert_eq!(vec[vec.len() - 1], capacity);
let vec = BumpVec::<(), 2>::new();
assert_eq!(vec.push(()), &());
assert_eq!(vec[0], ());
}
#[test]
#[should_panic]
fn vec_index_panics() {
let vec = BumpVec::<_, 2>::from([1, 2, 3]);
_ = vec[3];
}
#[test]
#[should_panic]
fn vec_index_mut_panics() {
let mut vec = BumpVec::<_, 2>::from([1, 2, 3]);
vec[3] = 4;
}