use core::num::NonZeroUsize;
#[derive(Clone)]
pub struct Layout {
size: usize,
align: usize,
phase: Option<NonZeroUsize>,
nocross: Option<NonZeroUsize>,
min: Option<NonZeroUsize>,
max: Option<NonZeroUsize>,
}
impl Layout {
pub const fn from_size_align(size: usize, align: usize) -> Option<Self> {
if !align.is_power_of_two() {
return None;
}
if size == 0 {
return None;
}
Some(Self {
size,
align,
phase: None,
nocross: None,
min: None,
max: None,
})
}
pub const fn new<T>() -> Self {
let core_layout = core::alloc::Layout::new::<T>();
Self {
size: core_layout.size(),
align: core_layout.align(),
phase: None,
nocross: None,
min: None,
max: None,
}
}
pub(crate) fn set_size(&mut self, size: usize) {
self.size = size;
}
pub(crate) fn align_up_to(&mut self, align: usize) {
self.align = self.align.max(align);
}
pub const fn with_phase(mut self, phase: usize) -> Self {
self.phase = NonZeroUsize::new(phase);
self
}
pub const fn with_nocross(mut self, align: usize) -> Option<Self> {
if !align.is_power_of_two() {
return None;
}
if self.size > align {
return None;
}
self.nocross = NonZeroUsize::new(align);
Some(self)
}
pub const fn with_min(mut self, min: usize) -> Self {
self.min = NonZeroUsize::new(min);
self
}
pub const fn with_max(mut self, max: usize) -> Self {
self.max = NonZeroUsize::new(max);
self
}
pub fn size(&self) -> usize {
self.size
}
pub fn align(&self) -> usize {
self.align
}
pub fn phase(&self) -> Option<usize> {
self.phase.map(NonZeroUsize::get)
}
pub fn nocross(&self) -> Option<usize> {
self.nocross.map(NonZeroUsize::get)
}
pub fn min(&self) -> Option<usize> {
self.min.map(NonZeroUsize::get)
}
pub fn max(&self) -> Option<usize> {
self.max.map(NonZeroUsize::get)
}
}
impl From<core::alloc::Layout> for Layout {
fn from(core_layout: core::alloc::Layout) -> Self {
Self {
size: core_layout.size(),
align: core_layout.align(),
phase: None,
nocross: None,
min: None,
max: None,
}
}
}