#![cfg_attr(test, deny(warnings))]
#![deny(missing_docs)]
use std::mem;
#[inline]
pub unsafe fn allocate(size: usize) -> *mut u8 {
ptr_from_vec(Vec::with_capacity(size))
}
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, new_size: usize) -> *mut u8 {
if old_size > new_size {
let mut buf = Vec::from_raw_parts(ptr, new_size, old_size);
buf.shrink_to_fit();
ptr_from_vec(buf)
} else if new_size > old_size {
let additional = new_size - old_size;
let mut buf = Vec::from_raw_parts(ptr, 0, old_size);
buf.reserve_exact(additional);
ptr_from_vec(buf)
} else {
ptr
}
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, old_size: usize) {
Vec::from_raw_parts(ptr, 0, old_size);
}
pub fn empty() -> *mut u8 {
1 as *mut u8
}
#[inline]
fn ptr_from_vec(mut buf: Vec<u8>) -> *mut u8 {
let ptr = buf.as_mut_ptr();
mem::forget(buf);
ptr
}
#[cfg(test)]
mod tests {
use std::ptr;
use {allocate, reallocate, deallocate, empty};
#[test]
fn test_empty() {
let ptr = empty();
assert!(ptr != ptr::null_mut());
}
#[test]
fn test_allocate() {
let buffer = unsafe { allocate(8) };
assert!(buffer != ptr::null_mut());
unsafe {
ptr::write(buffer.offset(0), 8);
ptr::write(buffer.offset(1), 4);
ptr::write(buffer.offset(3), 5);
ptr::write(buffer.offset(5), 3);
ptr::write(buffer.offset(7), 6);
assert_eq!(ptr::read(buffer.offset(0)), 8);
assert_eq!(ptr::read(buffer.offset(1)), 4);
assert_eq!(ptr::read(buffer.offset(3)), 5);
assert_eq!(ptr::read(buffer.offset(5)), 3);
assert_eq!(ptr::read(buffer.offset(7)), 6);
};
unsafe { deallocate(buffer, 8); }
let buffer = unsafe { allocate(1024 * 1024) };
assert!(buffer != ptr::null_mut());
unsafe {
ptr::write(buffer.offset(1024 * 1024 - 1), 12);
assert_eq!(ptr::read(buffer.offset(1024 * 1024 - 1)), 12);
};
unsafe { deallocate(buffer, 1024 * 1024); }
}
#[test]
fn test_reallocate() {
let mut buffer = unsafe { allocate(8) };
assert!(buffer != ptr::null_mut());
buffer = unsafe { reallocate(buffer, 8, 16) };
assert!(buffer != ptr::null_mut());
unsafe {
ptr::write(buffer.offset(0), 8);
ptr::write(buffer.offset(1), 4);
ptr::write(buffer.offset(5), 3);
ptr::write(buffer.offset(7), 6);
};
unsafe { allocate(128) };
buffer = unsafe { reallocate(buffer, 16, 32) };
assert!(buffer != ptr::null_mut());
unsafe {
assert_eq!(ptr::read(buffer.offset(0)), 8);
assert_eq!(ptr::read(buffer.offset(1)), 4);
assert_eq!(ptr::read(buffer.offset(5)), 3);
assert_eq!(ptr::read(buffer.offset(7)), 6);
};
}
}