117 lines
3.3 KiB
Rust
117 lines
3.3 KiB
Rust
#[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<T>(vec: &BlobVec) -> &[T] {
|
|
assert_eq!(vec.elem_size, core::mem::size_of::<T>());
|
|
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::<u32>().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::<u32>(&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::<u32>(&vec), &[3]);
|
|
value = 5;
|
|
vec_push(&mut vec, &value as *const u32 as *const u8);
|
|
assert_eq!(as_slice::<u32>(&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::<u32>::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::<u32>::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]);
|
|
}
|