use super::*;
use pretty_assertions::assert_eq;
#[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.push_ptr(());
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
assert_eq!(bump.pop(), Some(()));
bump.pop();
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
}
assert_eq!(bump.pop(), 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!(bump.pop(), None);
unsafe {
assert!(bump.inlined.get_mut().current_chunk().is_dead());
assert!(bump.inlined.get_mut().next_chunk().is_dead());
}
bump.push_ptr(cap_0);
let cap_01 = bump.capacity();
let cap_1 = cap_01 - cap_0;
assert_eq!(bump.capacity(), cap_01);
assert_eq!(bump.pop(), 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 {
bump.push_ptr(i);
}
bump.push_ptr(cap_01);
assert!(bump.capacity() > cap_01);
assert_eq!(bump.pop(), 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!(bump.pop(), 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());
}
bump.push_ptr(cap_01 - 1);
let cap_012 = bump.capacity();
let cap_02 = cap_012 - cap_1;
for i in cap_01..cap_012 {
bump.push_ptr(i);
}
for i in (cap_01..cap_012).rev() {
assert_eq!(bump.pop(), 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!(bump.pop(), 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!(bump.pop(), 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!(bump.pop(), 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!(bump.pop(), None);
let cap_0 = bump.capacity();
for i in 0..cap_0 {
bump.push_ptr(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());
}
bump.push_ptr(cap_0);
let cap_01 = bump.capacity();
let cap_1 = cap_01 - cap_0;
assert_eq!(bump.capacity(), cap_01);
assert_eq!(bump.pop(), 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 {
bump.push_ptr(i);
}
bump.push_ptr(cap_01);
assert!(bump.capacity() > cap_01);
assert_eq!(bump.pop(), 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!(bump.pop(), 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());
}
bump.push_ptr(cap_01 - 1);
let cap_012 = bump.capacity();
let cap_02 = cap_012 - cap_1;
for i in cap_01..cap_012 {
bump.push_ptr(i);
}
for i in (cap_01..cap_012).rev() {
assert_eq!(bump.pop(), 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!(bump.pop(), 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!(bump.pop(), 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!(bump.pop(), Some(cap_0 - 1));
assert_eq!(bump.capacity(), cap_02);
for i in (0..cap_0 - 1).rev() {
assert_eq!(bump.pop(), Some(i));
}
assert_eq!(bump.pop(), None);
assert_eq!(bump.capacity(), cap_02);
}
#[test]
fn bump_index() {
let bump = RawBump::<_, 0>::new();
bump.push_ptr(1);
bump.push_ptr(2);
bump.push_ptr(3);
bump.push_ptr(4);
bump.push_ptr(5);
unsafe {
assert_eq!(bump.index_unchecked(0).read(), 1);
assert_eq!(bump.index_unchecked(1).read(), 2);
assert_eq!(bump.index_unchecked(2).read(), 3);
assert_eq!(bump.index_unchecked(3).read(), 4);
assert_eq!(bump.index_unchecked(4).read(), 5);
}
let bump = RawBump::<_, 2>::new();
bump.push_ptr(1);
bump.push_ptr(2);
bump.push_ptr(3);
bump.push_ptr(4);
bump.push_ptr(5);
unsafe {
assert_eq!(bump.index_unchecked(0).read(), 1);
assert_eq!(bump.index_unchecked(1).read(), 2);
assert_eq!(bump.index_unchecked(2).read(), 3);
assert_eq!(bump.index_unchecked(3).read(), 4);
assert_eq!(bump.index_unchecked(4).read(), 5);
}
let bump = RawBump::<_, 0>::new();
bump.push_ptr(());
bump.push_ptr(());
bump.push_ptr(());
bump.push_ptr(());
bump.push_ptr(());
unsafe {
assert_eq!(bump.index_unchecked(0).read(), ());
assert_eq!(bump.index_unchecked(1).read(), ());
assert_eq!(bump.index_unchecked(2).read(), ());
assert_eq!(bump.index_unchecked(3).read(), ());
assert_eq!(bump.index_unchecked(4).read(), ());
}
}