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
use core::{ alloc::{Layout, LayoutErr}, cmp, }; #[inline] pub(crate) fn extend_layout(this: &Layout, next: Layout) -> Result<(Layout, usize), LayoutErr> { let new_align = cmp::max(this.align(), next.align()); let pad = layout_padding_needed_for(&this, next.align()); let offset = this.size().checked_add(pad).ok_or_else(layout_err)?; let new_size = offset.checked_add(next.size()).ok_or_else(layout_err)?; let layout = Layout::from_size_align(new_size, new_align)?; Ok((layout, offset)) } #[inline] pub(crate) fn pad_layout_to_align(this: &Layout) -> Layout { let pad = layout_padding_needed_for(this, this.align()); let new_size = this.size() + pad; unsafe { Layout::from_size_align_unchecked(new_size, this.align()) } } #[inline] pub(crate) fn layout_array<T>(n: usize) -> Result<Layout, LayoutErr> { repeat_layout(&Layout::new::<T>(), n).map(|(k, _)| k) } #[inline] pub(crate) fn repr_c_3(fields: [Layout; 3]) -> Result<(Layout, [usize; 3]), LayoutErr> { let mut offsets: [usize; 3] = [0; 3]; let mut layout = fields[0]; for i in 1..3 { let (new_layout, this_offset) = extend_layout(&layout, fields[i])?; layout = new_layout; offsets[i] = this_offset; } Ok((pad_layout_to_align(&layout), offsets)) } #[inline] fn layout_padding_needed_for(this: &Layout, align: usize) -> usize { let len = this.size(); let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1); len_rounded_up.wrapping_sub(len) } #[inline] fn repeat_layout(this: &Layout, n: usize) -> Result<(Layout, usize), LayoutErr> { let padded_size = pad_layout_to_align(this).size(); let alloc_size = padded_size.checked_mul(n).ok_or_else(layout_err)?; unsafe { Ok(( Layout::from_size_align_unchecked(alloc_size, this.align()), padded_size, )) } } #[inline] fn layout_err() -> LayoutErr { Layout::from_size_align(0, 0).unwrap_err() }