bumpish 0.4.1

A set of collections using bump allocations
Documentation
use super::*;
use pretty_assertions::assert_eq;

fn clct<T>(iter: impl Iterator<Item = T>) -> Vec<T> {
    iter.collect::<Vec<T>>()
}

#[test]
fn iter_n_eq_0() {
    unsafe {
        let mut bump = RawBump::<usize, 0>::new();
        let iter = bump.iter();
        assert!(iter.first_chunk.is_dead());
        assert!(iter.last_chunk.is_dead());

        assert_eq!(clct(bump.iter()), &[]);
        assert_eq!(bump.iter().count(), 0);

        bump.push_ptr(0);
        let iter = bump.iter();
        assert!(!iter.first_chunk.is_dead());
        assert!(!iter.last_chunk.is_dead());
        assert!(iter.first_chunk.is(iter.last_chunk));

        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), &[0]);
        assert_eq!(bump.iter().count(), 1);

        let cap = bump.capacity();
        for i in 1..cap + 1 {
            bump.push_ptr(i);
        }
        let iter = bump.iter();
        assert!(!iter.first_chunk.is_dead());
        assert!(!iter.last_chunk.is_dead());
        assert!(!iter.first_chunk.is(iter.last_chunk));

        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..=cap));
        assert_eq!(bump.iter().count(), cap + 1);

        assert_eq!(bump.pop(), Some(cap));
        let iter = bump.iter();
        assert!(!iter.first_chunk.is_dead());
        assert!(!iter.last_chunk.is_dead());
        assert!(!iter.first_chunk.is(iter.last_chunk));

        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..cap));
        assert_eq!(bump.iter().count(), cap);

        bump.pop();
        bump.push_ptr(cap - 1);
        let iter = bump.iter();
        assert!(!iter.first_chunk.is_dead());
        assert!(!iter.last_chunk.is_dead());
        assert!(iter.first_chunk.is(iter.last_chunk));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..cap));
        assert_eq!(bump.iter().count(), cap);
    }
}

#[test]
fn iter_n_ne_0() {
    unsafe {
        let mut bump = RawBump::<usize, 3>::new();
        let iter = bump.iter();
        let inlined = bump.inlined_ptr().as_mut().get();
        assert!(iter.first_chunk.is(inlined));
        assert!(iter.last_chunk.is(inlined));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), &[]);
        assert_eq!(bump.iter().count(), 0);

        bump.push_ptr(0);
        let iter = bump.iter();
        let inlined = bump.inlined_ptr().as_mut().get();
        assert!(iter.first_chunk.is(inlined));
        assert!(iter.last_chunk.is(inlined));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), &[0]);
        assert_eq!(bump.iter().count(), 1);

        let cap = bump.capacity();
        for i in 1..cap + 1 {
            bump.push_ptr(i);
        }
        let iter = bump.iter();
        let inlined = bump.inlined_ptr().as_mut().get();
        assert!(iter.first_chunk.is(inlined));
        assert!(!iter.last_chunk.is(inlined));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..=cap));
        assert_eq!(bump.iter().count(), cap + 1);

        bump.pop();
        let iter = bump.iter();
        let inlined = bump.inlined_ptr().as_mut().get();
        assert!(iter.first_chunk.is(inlined));
        assert!(!iter.last_chunk.is(inlined));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..cap));
        assert_eq!(bump.iter().count(), cap);

        bump.pop();
        bump.push_ptr(cap - 1);
        let iter = bump.iter();
        let inlined = bump.inlined_ptr().as_mut().get();
        assert!(iter.first_chunk.is(inlined));
        assert!(iter.last_chunk.is(inlined));
        assert_eq!(clct(bump.iter().map(|ptr| ptr.read())), clct(0..cap));
        assert_eq!(bump.iter().count(), cap);
    }
}

#[test]
fn iter_advance_by() {
    let bump = RawBump::<usize, 10>::new();
    for i in 0..6 {
        bump.push_ptr(i);
    }
    let mut iter = bump.iter();
    assert_eq!(iter.advance_by(5), Ok(()));
    assert_eq!(iter.next().map(|ptr| unsafe { ptr.as_ref() }), Some(&5));
    assert_eq!(iter.advance_by(0), Ok(()));
    assert_eq!(iter.advance_by(1), Err(NonZero::new(1).unwrap()));
    assert_eq!(iter.advance_by(10), Err(NonZero::new(10).unwrap()));
    assert_eq!(
        iter.advance_by(usize::MAX),
        Err(NonZero::new(usize::MAX).unwrap())
    );
    assert_eq!(iter.advance_back_by(0), Ok(()));
    assert_eq!(iter.advance_back_by(1), Err(NonZero::new(1).unwrap()));
    assert_eq!(iter.advance_back_by(10), Err(NonZero::new(10).unwrap()));
    assert_eq!(
        iter.advance_back_by(usize::MAX),
        Err(NonZero::new(usize::MAX).unwrap())
    );
}

#[test]
fn iter_advance_by_zst() {
    let bump = RawBump::<(), 0>::new();
    for _ in 0..6 {
        bump.push_ptr(());
    }
    let mut iter = bump.iter();
    assert_eq!(iter.advance_by(5), Ok(()));
    assert_eq!(iter.next().map(|ptr| unsafe { ptr.as_ref() }), Some(&()));
    assert_eq!(iter.advance_by(0), Ok(()));
    assert_eq!(iter.advance_by(1), Err(NonZero::new(1).unwrap()));
    assert_eq!(iter.advance_by(10), Err(NonZero::new(10).unwrap()));
    assert_eq!(
        iter.advance_by(usize::MAX),
        Err(NonZero::new(usize::MAX).unwrap())
    );
    assert_eq!(iter.advance_back_by(0), Ok(()));
    assert_eq!(iter.advance_back_by(1), Err(NonZero::new(1).unwrap()));
    assert_eq!(iter.advance_back_by(10), Err(NonZero::new(10).unwrap()));
    assert_eq!(
        iter.advance_back_by(usize::MAX),
        Err(NonZero::new(usize::MAX).unwrap())
    );
}