use super::*;
use pretty_assertions::assert_eq;
fn push<T, const N: usize>(bump: &mut RawBump<T, N>, value: T) -> &mut T {
unsafe {
let mut ptr = bump.allocate();
ptr.write(value);
ptr.as_mut()
}
}
fn pop<T, const N: usize>(bump: &mut RawBump<T, N>) -> Option<T> {
bump.deallocate().map(|ptr| unsafe { ptr.read() })
}
#[test]
fn bump_with_capacity() {
unsafe {
let bump = RawBump::<i32, 0>::with_capacity(0);
assert_eq!(bump.capacity(), 0);
let mut bump = RawBump::<i32, 0>::with_capacity(3);
assert!(bump.capacity() >= 3);
let inlined_chunk = bump.inlined.get_mut().get();
let next_chunk = inlined_chunk.next();
assert_eq!(0, inlined_chunk.capacity());
assert!(next_chunk.capacity() >= 3 * i32::SIZE);
assert_eq!(bump.capacity() * i32::SIZE, next_chunk.capacity());
assert!(!inlined_chunk.prev().is_dead());
assert!(!inlined_chunk.next().is_dead());
assert!(next_chunk.prev().is_dead());
assert!(next_chunk.next().is_dead());
let mut bump = RawBump::<i32, 5>::with_capacity(5);
assert_eq!(bump.capacity(), 5);
let chunk = bump.inlined.get_mut().get();
assert_eq!(chunk.capacity(), 5 * i32::SIZE);
}
}
#[test]
fn bump_push_pop_zst() {
let mut bump = RawBump::<(), 0>::new();
unsafe {
bump.allocate();
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
assert_eq!(pop(&mut bump), Some(()));
bump.deallocate();
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
}
assert_eq!(pop(&mut bump), None);
}
#[test]
fn bump_push_pop_0() {
let mut bump = RawBump::<usize, 0>::new();
let cap_0 = bump.capacity();
assert_eq!(bump.capacity(), 0);
assert_eq!(pop(&mut bump), None);
unsafe {
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
}
push(&mut bump, cap_0);
let cap_01 = bump.capacity();
let cap_1 = cap_01 - cap_0;
assert_eq!(bump.capacity(), cap_01);
assert_eq!(pop(&mut bump), Some(cap_0));
assert!(bump.capacity() > cap_0);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
for i in cap_0..cap_01 {
push(&mut bump, i);
}
push(&mut bump, cap_01);
assert!(bump.capacity() > cap_01);
assert_eq!(pop(&mut bump), Some(cap_01));
assert!(bump.capacity() > cap_01);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(!current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(!current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), Some(cap_01 - 1));
assert!(bump.capacity() > cap_01);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
push(&mut bump, cap_01 - 1);
let cap_012 = bump.capacity();
let cap_02 = cap_012 - cap_1;
for i in cap_01..cap_012 {
push(&mut bump, i);
}
for i in (cap_01..cap_012).rev() {
assert_eq!(pop(&mut bump), Some(i));
}
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(!current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(!current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), Some(cap_01 - 1));
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
for i in (cap_0..cap_01 - 1).rev() {
assert_eq!(pop(&mut bump), Some(i));
}
assert_eq!(bump.capacity(), cap_012);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), None);
assert_eq!(bump.capacity(), cap_02);
}
#[test]
fn bump_push_pop_n() {
let mut bump = RawBump::<usize, 5>::new();
assert_eq!(bump.capacity(), 5);
assert_eq!(pop(&mut bump), None);
let cap_0 = bump.capacity();
for i in 0..cap_0 {
push(&mut bump, i);
}
assert_eq!(bump.capacity(), cap_0);
unsafe {
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
}
push(&mut bump, cap_0);
let cap_01 = bump.capacity();
let cap_1 = cap_01 - cap_0;
assert_eq!(bump.capacity(), cap_01);
assert_eq!(pop(&mut bump), Some(cap_0));
assert!(bump.capacity() > cap_0);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
for i in cap_0..cap_01 {
push(&mut bump, i);
}
push(&mut bump, cap_01);
assert!(bump.capacity() > cap_01);
assert_eq!(pop(&mut bump), Some(cap_01));
assert!(bump.capacity() > cap_01);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(!current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(!current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), Some(cap_01 - 1));
assert!(bump.capacity() > cap_01);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
push(&mut bump, cap_01 - 1);
let cap_012 = bump.capacity();
let cap_02 = cap_012 - cap_1;
for i in cap_01..cap_012 {
push(&mut bump, i);
}
for i in (cap_01..cap_012).rev() {
assert_eq!(pop(&mut bump), Some(i));
}
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(!current_chunk.is(first_chunk));
assert!(current_chunk.next().is_dead());
assert!(!current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), Some(cap_01 - 1));
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
for i in (cap_0..cap_01 - 1).rev() {
assert_eq!(pop(&mut bump), Some(i));
}
assert_eq!(bump.capacity(), cap_012);
unsafe {
let current_chunk = bump.inlined.get_mut().current_chunk();
let first_chunk = bump.inlined.get_mut().next_chunk();
assert!(!current_chunk.is_dead());
assert!(!first_chunk.is_dead());
assert!(current_chunk.is(first_chunk));
assert!(!current_chunk.next().is_dead());
assert!(current_chunk.prev().is_dead());
assert!(!first_chunk.next().is_dead());
assert!(first_chunk.prev().is_dead());
}
assert_eq!(pop(&mut bump), Some(cap_0 - 1));
assert_eq!(bump.capacity(), cap_02);
for i in (0..cap_0 - 1).rev() {
assert_eq!(pop(&mut bump), Some(i));
}
assert_eq!(pop(&mut bump), None);
assert_eq!(bump.capacity(), cap_02);
}
#[test]
fn bump_index() {
let mut bump = RawBump::<_, 0>::new();
push(&mut bump, 1);
push(&mut bump, 2);
push(&mut bump, 3);
push(&mut bump, 4);
push(&mut bump, 5);
unsafe {
assert_eq!(bump.index(0).read(), 1);
assert_eq!(bump.index(1).read(), 2);
assert_eq!(bump.index(2).read(), 3);
assert_eq!(bump.index(3).read(), 4);
assert_eq!(bump.index(4).read(), 5);
}
let mut bump = RawBump::<_, 2>::new();
push(&mut bump, 1);
push(&mut bump, 2);
push(&mut bump, 3);
push(&mut bump, 4);
push(&mut bump, 5);
unsafe {
assert_eq!(bump.index(0).read(), 1);
assert_eq!(bump.index(1).read(), 2);
assert_eq!(bump.index(2).read(), 3);
assert_eq!(bump.index(3).read(), 4);
assert_eq!(bump.index(4).read(), 5);
}
let mut bump = RawBump::<_, 0>::new();
push(&mut bump, ());
push(&mut bump, ());
push(&mut bump, ());
push(&mut bump, ());
push(&mut bump, ());
unsafe {
assert_eq!(bump.index(0).read(), ());
assert_eq!(bump.index(1).read(), ());
assert_eq!(bump.index(2).read(), ());
assert_eq!(bump.index(3).read(), ());
assert_eq!(bump.index(4).read(), ());
}
}