#[path = "shared/shared.rs"] mod util; use util::{ffi::*, vec::Vec, BlobVec}; fn main() { static mut DROPS: usize = 1; fn get_drops() -> usize { unsafe { (&raw const DROPS).read() } } unsafe fn update_drops(f: impl FnOnce(&mut usize)) { unsafe { let drops = &raw mut DROPS; f(&mut *drops); } } let mut vec = BlobVec { data: core::ptr::null_mut(), len: 0, cap: 0, elem_size: 1, drop: None, }; fn as_slice(vec: &BlobVec) -> &[T] { assert_eq!(vec.elem_size, core::mem::size_of::()); unsafe { core::slice::from_raw_parts(vec.data as *const T, vec.len) } } extern "C" fn drop(ptr: *mut u8) { unsafe { update_drops(|drops| { *drops *= ptr.cast::().read() as usize; }); } } unsafe { vec_init(&mut vec, 4, Some(drop)); let mut value: u32 = 2; assert_eq!(vec.len, 0); vec_push(&mut vec, &value as *const u32 as *const u8); assert_eq!(vec.len, 1); assert_eq!(as_slice::(&vec), &[2]); let retrieved = *(vec_get(&mut vec, 0) as *mut u32); assert_eq!(retrieved, 2); assert_eq!(get_drops(), 1); vec_drop_last(&mut vec); assert_eq!(vec.len, 0); assert_eq!(get_drops(), 2); value = 3; vec_push(&mut vec, &value as *const u32 as *const u8); assert_eq!(as_slice::(&vec), &[3]); value = 5; vec_push(&mut vec, &value as *const u32 as *const u8); assert_eq!(as_slice::(&vec), &[3, 5]); assert_eq!(vec.len, 2); vec_drop_last(&mut vec); vec_drop_last(&mut vec); assert_eq!(get_drops(), 2 * 3 * 5); eprintln!("Push/pop test passed\n"); } let mut vec = Vec::::new_with(100); assert_eq!(vec.len(), 0); vec.push(10); vec.push(20); vec.push(30); assert_eq!(vec.len(), 3); assert_eq!(vec.get(0), Some(&10)); assert_eq!(vec.get(1), Some(&20)); assert_eq!(vec.get(2), Some(&30)); assert_eq!(vec.pop(), Some(30)); assert_eq!(vec.len(), 2); vec.remove(0); assert_eq!(vec.len(), 1); assert_eq!(vec.get(0), Some(&20)); vec.push(40); vec.push(50); assert_eq!( vec.position(&40, |a, b| { eprintln!("Comparing {} and {}", a, b); a == b }), Some(1) ); assert_eq!(vec.as_slice(), &[20, 40, 50]); vec.insert(30, 1); assert_eq!(vec.as_slice(), &[20, 30, 40, 50]); let cmp = |a: &u32, b: &u32| match a.cmp(b) { core::cmp::Ordering::Less => -1, core::cmp::Ordering::Equal => 0, core::cmp::Ordering::Greater => 1, }; assert_eq!(vec.binary_search_by(&35, cmp), Err(2)); assert_eq!(vec.binary_search_by(&25, cmp), Err(1)); assert_eq!(vec.binary_search_by(&30, cmp), Ok(1)); assert_eq!(vec.binary_search_by(&5, cmp), Err(0)); assert_eq!(vec.binary_search_by(&55, cmp), Err(4)); _ = vec.insert_sorted(35, cmp); assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]); let mut vec = Vec::::new_with(100); _ = vec.insert_sorted(50, cmp); assert_eq!(vec.as_slice(), &[50]); // vec extend let elements = Box::new([1, 2, 3, 4, 5]); vec.extend(elements); assert_eq!(vec.as_slice(), &[50, 1, 2, 3, 4, 5]); // vec insert_many let elements = Box::new([6, 7, 8]); vec.insert_many(2, elements); assert_eq!(vec.as_slice(), &[50, 1, 6, 7, 8, 2, 3, 4, 5]); let mut vec = Vec::::new_with(100); assert_eq!(vec.len(), 0); _ = vec.insert_sorted(5, cmp); assert_eq!(vec.len(), 1); assert_eq!(vec.as_slice(), &[5]); _ = vec.insert_sorted(2, cmp); assert_eq!(vec.len(), 2); assert_eq!(vec.as_slice(), &[2, 5]); _ = vec.insert_sorted(7, cmp); assert_eq!(vec.len(), 3); assert_eq!(vec.as_slice(), &[2, 5, 7]); }