use std::alloc::{GlobalAlloc, Layout};
#[global_allocator]
static A: zk_alloc::ZkAllocator = zk_alloc::ZkAllocator;
static ZK: zk_alloc::ZkAllocator = zk_alloc::ZkAllocator;
#[test]
fn realloc_partial_overlap_preserves_source_bytes() {
zk_alloc::begin_phase();
let layout1 = Layout::from_size_align(8192, 8).unwrap();
let p1 = unsafe { ZK.alloc(layout1) };
assert!(!p1.is_null(), "phase-N alloc returned null");
unsafe { std::ptr::write_bytes(p1, 0xC1, 8192) };
zk_alloc::end_phase();
zk_alloc::begin_phase();
let layout_y = Layout::from_size_align(4096, 8).unwrap();
let py = unsafe { ZK.alloc(layout_y) };
assert!(!py.is_null(), "py alloc returned null");
unsafe { std::ptr::write_bytes(py, 0xD0, 4096) };
let p2 = unsafe { ZK.realloc(p1, layout1, 16384) };
assert!(!p2.is_null(), "realloc returned null");
println!(
"p1=0x{:x} py=0x{:x} p2=0x{:x}",
p1 as usize, py as usize, p2 as usize
);
let bytes = unsafe { std::slice::from_raw_parts(p2, 8192) };
let lower_d0 = bytes[..4096].iter().all(|&b| b == 0xD0);
let upper_c1 = bytes[4096..].iter().all(|&b| b == 0xC1);
let upper_first_bad = bytes[4096..].iter().position(|&b| b != 0xC1);
eprintln!("lower_d0={lower_d0} upper_c1={upper_c1} upper_first_bad={upper_first_bad:?}");
assert!(
lower_d0,
"lower 4K of p2 should hold py's 0xD0 bytes (src had 0xD0 for [0,4K))"
);
assert!(
upper_c1,
"upper 4K of p2 was corrupted: expected 0xC1 (src's upper half) but \
forward-direction memcpy in copy_nonoverlapping clobbered the \
overlapping source range. Switch to ptr::copy (memmove)."
);
zk_alloc::end_phase();
}