alloc_traits/util.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
//! Various utilities such as default implementations.
/// Implementations of default items of traits.
///
/// It is expected that these might be used as a fallback 'super' call of sorts on trait
/// implementors to opportunistically do some form of optimization.
pub mod defaults {
/// Default implementations for the `LocalAlloc` trait.
///
/// See [`LocalAlloc`] for more information. The methods called by the functions in this module
/// are documented and will not change between non-breaking releases, if at all. Rather new
/// variants may be added that call additional methods that might be more efficient. This
/// avoids accidentally creating a dependency loop in implementors.
///
/// [`LocalAlloc`]: ../../../trait.LocalAlloc.html
pub mod local {
use core::ptr::{copy_nonoverlapping, write_bytes};
use crate::NonZeroLayout;
use crate::local::{LocalAlloc, Allocation};
/// Allocate a block of memory initialized with zeros.
///
/// See [`LocalAlloc::alloc_zeroed`] for more information. This is a default implementation
/// that might be less efficient than a dedicated one. It only uses the `alloc` method.
///
/// [`LocalAlloc::alloc_zeroed`]: ../../../trait.LocalAlloc.html
pub fn alloc_zeroed<'alloc, Alloc>(
this: &'alloc Alloc,
layout: NonZeroLayout
) -> Option<Allocation<'alloc>>
where
Alloc: LocalAlloc<'alloc> + ?Sized,
{
let allocation = this.alloc(layout)?;
unsafe {
write_bytes(allocation.ptr.as_ptr(), 0u8, allocation.layout.size().into());
}
Some(allocation)
}
/// Change the layout of a block previously allocated.
///
/// See [`LocalAlloc::realloc`] for more information. This is a default implementation that
/// might be less efficient than a dedicated one. It only uses the `alloc` and `dealloc`
/// methods.
///
/// # Safety
/// See the trait.
///
/// [`LocalAlloc::realloc`]: ../../../trait.LocalAlloc.html
pub unsafe fn realloc<'alloc, Alloc>(
this: &'alloc Alloc,
alloc: Allocation<'alloc>,
layout: NonZeroLayout
) -> Option<Allocation<'alloc>>
where
Alloc: LocalAlloc<'alloc> + ?Sized,
{
let new_alloc = this.alloc(layout)?;
copy_nonoverlapping(
alloc.ptr.as_ptr(),
new_alloc.ptr.as_ptr(),
core::cmp::min(layout.size(), alloc.layout.size()).get());
this.dealloc(alloc);
Some(new_alloc)
}
}
}