#[cfg(all(
feature = "allocator-api",
not(feature = "allocator-api-shim"),
not(feature = "nightly-allocator-api")
))]
compile_error!(
"the `allocator-api` feature is internal; enable one of `allocator-api2-v02`, \
`allocator-api2-v03`, or `nightly-allocator-api` instead"
);
#[cfg(all(feature = "nightly-allocator-api", feature = "allocator-api-shim"))]
compile_error!(
"`nightly-allocator-api` cannot be combined with the `allocator-api2-v02` / \
`allocator-api2-v03` shims; select a single allocator backend"
);
mod common;
pub(crate) use common::*;
#[cfg(not(feature = "allocator-api"))]
mod default;
#[cfg(not(feature = "allocator-api"))]
pub(crate) use default::*;
#[cfg(feature = "allocator-api")]
#[allow(clippy::module_inception)]
mod allocator;
#[cfg(feature = "allocator-api")]
pub(crate) use allocator::*;
pub(crate) use internal::*;
#[cfg(feature = "allocator-api")]
pub use internal::Global;
#[cfg(test)]
mod tests {
use core::alloc::Layout;
use super::*;
fn get_allocator() -> Global {
Global
}
#[test]
fn test_global_allocator_zero_sized() {
let allocator = get_allocator();
let layout = Layout::new::<()>();
let ptr = AllocatorProvider::allocate(&allocator, layout).unwrap();
assert_eq!(ptr.len(), 0);
unsafe {
AllocatorProvider::deallocate(&allocator, ptr.cast(), layout);
}
}
#[test]
fn test_global_allocator_basic() {
let allocator = get_allocator();
let layout = Layout::new::<u64>();
let ptr = AllocatorProvider::allocate(&allocator, layout).unwrap();
assert_eq!(ptr.len(), 8);
unsafe {
let raw_ptr = ptr.as_ptr().cast::<u64>();
raw_ptr.write(42);
assert_eq!(raw_ptr.read(), 42);
AllocatorProvider::deallocate(&allocator, ptr.cast(), layout);
}
}
#[test]
fn test_global_allocator_grow() {
let allocator = get_allocator();
let old_layout = Layout::from_size_align(8, 8).unwrap();
let new_layout = Layout::from_size_align(16, 8).unwrap();
let old_ptr = AllocatorProvider::allocate(&allocator, old_layout).unwrap();
unsafe {
old_ptr.as_ptr().cast::<u64>().write(42);
let new_ptr = AllocatorProvider::grow(
&allocator,
old_ptr.cast(),
old_layout,
new_layout,
)
.unwrap();
assert_eq!(new_ptr.len(), 16);
assert_eq!(new_ptr.as_ptr().cast::<u64>().read(), 42);
AllocatorProvider::deallocate(&allocator, new_ptr.cast(), new_layout);
}
}
#[test]
fn test_global_allocator_shrink() {
let allocator = get_allocator();
let old_layout = Layout::from_size_align(16, 8).unwrap();
let new_layout = Layout::from_size_align(8, 8).unwrap();
let old_ptr = AllocatorProvider::allocate(&allocator, old_layout).unwrap();
unsafe {
old_ptr.as_ptr().cast::<u64>().write(42);
let new_ptr = AllocatorProvider::shrink(
&allocator,
old_ptr.cast(),
old_layout,
new_layout,
)
.unwrap();
assert_eq!(new_ptr.len(), 8);
assert_eq!(new_ptr.as_ptr().cast::<u64>().read(), 42);
AllocatorProvider::deallocate(&allocator, new_ptr.cast(), new_layout);
}
}
}