pub struct Layout { /* private fields */ }Expand description
The layout of a block of memory in the form of its size and alignment in bytes.
Note that this is memapi’s custom type, not stdlib’s alloc::alloc::Layout. If a function
you want does not exist, request it in an issue.
Implementations§
Source§impl Layout
impl Layout
Sourcepub const fn new<T>() -> Layout
pub const fn new<T>() -> Layout
Creates a layout for the given type.
This just delegates to <T as [SizedProps>::LAYOUT].
Sourcepub const fn array<T>(n: usize) -> Result<Layout, Error>
pub const fn array<T>(n: usize) -> Result<Layout, Error>
Creates a layout representing an array of n T.
§Errors
Err(Error::InvalidLayout([T::SZ], [T::ALN], LayoutErr::ExceedsMax)) if
the length of the computed array, in bytes, would exceed USIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn extend(&self, other: Layout) -> Result<(Layout, usize), Error>
pub const fn extend(&self, other: Layout) -> Result<(Layout, usize), Error>
Combines two layouts sequentially, returning the combined layout and the
offset where other begins.
Given two layouts self and other, computes a layout describing a block of memory that
can hold a value of layout self followed by a value of layout other, where other
starts at an offset that satisfies its alignment. Returns the resulting combined layout and
the offset at which other begins.
Note that this is only const on Rust versions 1.47 and above.
§Errors
Err(Error::InvalidLayout(self.size(),
other.align(), LayoutErr::ExceedsMax)) if
self.size() rounded up to the nearest multiple of
other.align() would exceed USIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn dangling(&self) -> NonNull<u8>
pub const fn dangling(&self) -> NonNull<u8>
Returns a valid, dangling pointer for this layout’s alignment.
The returned pointer is non-null and correctly aligned for types that use this layout’s alignment but should not be dereferenced.
Sourcepub unsafe fn for_value_raw<T: ?Sized>(val: *const T) -> Layout
pub unsafe fn for_value_raw<T: ?Sized>(val: *const T) -> Layout
Sourcepub const fn from_size_align(size: usize, align: usize) -> Result<Layout, Error>
pub const fn from_size_align(size: usize, align: usize) -> Result<Layout, Error>
Creates a layout with the given size and alignment.
§Errors
Err(Error::InvalidLayout(size, align, LayoutErr::ZeroAlign))ifalign == 0.Err(Error::InvalidLayout(size, align, LayoutErr::NonPowerOfTwoAlign))ifalignis not a power of two.Err(Error::InvalidLayout(size, align, LayoutErr::ExceedsMax))ifsizerounded up to the nearest multiple ofalignwould exceedUSIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn aligned_alloc_compatible_from_size_align(
size: usize,
align: usize,
) -> Result<Layout, Error>
pub const fn aligned_alloc_compatible_from_size_align( size: usize, align: usize, ) -> Result<Layout, Error>
Creates a layout compatible with C’s aligned_alloc requirements from the given size and
align.
C’s aligned_alloc(alignment, size) requires:
alignmentis a power of two, non-zero, and a multiple ofsize_of::<*mut [c_void]>().sizeis a multiple ofalignment.
Therefore:
alignwill be rounded up to the nearest multiple ofsize_of::<*mut [c_void]>()if it isn’t already.sizewill be rounded up to the nearest multiple of the resulting alignment.
This is semantically equivalent to Layout::from_size_align(size,
align).and_then(|l|
l.to_aligned_alloc_compatible()).
§Errors
Err(Error::InvalidLayout(self.align(), self.align(), LayoutErr::ZeroAlign))ifalign == 0.Err(Error::InvalidLayout(self.size(), self.align(), LayoutErr::CRoundUp))ifsizerounded up to the new alignment would exceedUSIZE_MAX_NO_HIGH_BIT.
§Examples
let l = Layout::aligned_alloc_compatible_from_size_align(10, 1).unwrap();
assert!(l.align() >= usize::SZ);
assert_eq!(l.size() % l.align(), 0);
assert!(l.size() >= 10);
// on 64-bit systems, l == Layout(size = 16, align = 8).
// 32-bit, l == Layout(size = 12, align = 4)Sourcepub const unsafe fn from_size_align_unchecked(
size: usize,
align: usize,
) -> Layout
pub const unsafe fn from_size_align_unchecked( size: usize, align: usize, ) -> Layout
Creates a layout with the given size and alignment.
In debug mode, this will panic if passed an invalid size or alignment.
§Safety
The caller must ensure:
alignis a non-zero power of two.sizerounded up toaligndoes not exceedUSIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn padding_needed_for(&self, align: usize) -> Result<usize, Error>
pub const fn padding_needed_for(&self, align: usize) -> Result<usize, Error>
Returns the amount of padding necessary after self to ensure that the following address
will satisfy align.
§Errors
Err(Error::InvalidLayout(size, align, LayoutErr::ZeroAlign))ifalign == 0.Err(Error::InvalidLayout(size, align, LayoutErr::NonPowerOfTwoAlign))ifalignis not a power of two.Err(Error::InvalidLayout(size, align, LayoutErr::ExceedsMax))ifsizerounded up to the nearest multiple ofalignwould exceedUSIZE_MAX_NO_HIGH_BIT.
§Example
assert_eq!(unsafe { Layout::from_size_align_unchecked(6, 8) }.padding_needed_for(8), Ok(2));Sourcepub const fn pad_to_align(&self) -> Layout
pub const fn pad_to_align(&self) -> Layout
Creates a layout by rounding the size of this layout up to a multiple of the layout’s alignment.
This is equivalent to adding the result of Layout::padding_needed_for to
self.size().
Sourcepub const fn repeat(&self, count: usize) -> Result<(Layout, usize), Error>
pub const fn repeat(&self, count: usize) -> Result<(Layout, usize), Error>
Creates a layout for count instances of the value described by layout, with padding
between each to ensure that each instance is given its requested size and alignment.
On success, returns (l, offs) where l is the layout of the array and offs is the
distance between the start of each element in the array (stride).
Note that this is only const on Rust versions 1.47 and above.
§Errors
Err(Error::ArithmeticError) if multiplying count by
layout.size(), rounded up to the nearest multiple of
layout.align(), would overflow.
Sourcepub const fn repeat_packed(&self, count: usize) -> Result<Layout, Error>
pub const fn repeat_packed(&self, count: usize) -> Result<Layout, Error>
Creates a layout for count instances of the value described by layout, with no padding
between.
Note that, unlike Layout::repeat, repeat_packed doesn’t guarantee that repeated
instances of the value described by layout will be properly aligned, even if layout is
properly aligned.
In other words, if the layout returned byrepeat_packed is used to allocate an array, it
isn’t guaranteed that all elements in the array will be properly aligned.
Note that this is only const on Rust versions 1.47 and above.
§Errors
Err(Error::ArithmeticError)if multiplyinglayout.size()bycountwould overflow.Err(Error::InvalidLayout(self.size() * count, self.align(), LayoutErr::ExceedsMax))ifself.size() * countrounded up to the nearest multiple ofself.align()would exceedUSIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn align_to(&self, align: usize) -> Result<Layout, Error>
pub const fn align_to(&self, align: usize) -> Result<Layout, Error>
Creates a layout with the same size as self but an alignment meeting align. If
self.align() >= align, returns self.
This method doesn’t modify the size of the new layout.
§Errors
Err(Error::InvalidLayout(self.size(), align, LayoutErr::ZeroAlign))ifalign == 0.Err(Error::InvalidLayout(self.size(), align, LayoutErr::NonPowerOfTwoAlign))ifalignis not a power of two.Err(Error::InvalidLayout(self.size(), align, LayoutErr::ExceedsMax))ifself.size()rounded up to the nearest multiple ofalignwould exceedUSIZE_MAX_NO_HIGH_BIT.
Sourcepub const fn align_to_multiple_of(&self, align: usize) -> Result<Layout, Error>
pub const fn align_to_multiple_of(&self, align: usize) -> Result<Layout, Error>
Returns a layout with the same size as self but whose alignment has been rounded up to
the nearest multiple of align.
This differs from Layout::align_to: align_to sets the layout’s
alignment to the provided alignment if that alignment is larger than the current one.
This method instead rounds self.align() up to a multiple of the provided
align.
§Errors
Err(Error::InvalidLayout(self.align(), align, LayoutErr::ZeroAlign))ifalign == 0.Err(Error::InvalidLayout(self.align(), align, LayoutErr::NonPowerOfTwoAlign))ifalignis not a power of two.Err(Error::InvalidLayout(self.size(), align, LayoutErr::ExceedsMax))ifself.size()rounded up to the nearest multiple of the new alignment would exceedUSIZE_MAX_NO_HIGH_BIT.
§Examples
// current alignment 8, round up to a multiple of 16 => next multiple is 16
let l = unsafe { Layout::from_size_align_unchecked(30, 8) };
let rounded = l.align_to_multiple_of(16).unwrap();
assert_eq!(rounded.align(), 16);
assert_eq!(rounded.size(), 30);Sourcepub const fn to_aligned_alloc_compatible(&self) -> Result<Layout, Error>
pub const fn to_aligned_alloc_compatible(&self) -> Result<Layout, Error>
Converts this layout into one compatible with C’s aligned_alloc requirements.
C’s aligned_alloc(alignment, size) requires:
alignmentis a power of two, non-zero, and a multiple ofsize_of::<*mut [c_void]>().sizeis a multiple ofalignment.
Therefore:
- The alignment will be rounded up to the nearest multiple of
size_of::<*mut [c_void]>()if it isn’t already. - The size will be rounded up to the nearest multiple of the resulting alignment.
§Errors
Err(Error::InvalidLayout(self.size(),
self.align(), LayoutErr::CRoundUp)) if:
align == 0.alignis not a power of two.alignrounded up tosize_of::<*mut [c_void]>()would exceed the maximum allowed alignment.sizerounded up to the new alignment would exceedUSIZE_MAX_NO_HIGH_BIT.
§Examples
let l = Layout::from_size_align(10, 1).unwrap();
let compatible = l.to_aligned_alloc_compatible().unwrap();
assert!(compatible.align() >= usize::SZ);
assert_eq!(compatible.size() % compatible.align(), 0);
assert!(compatible.size() >= 10);
// on 64-bit systems, compatible == Layout(size = 16, align = 8).
// 32-bit, compatible == Layout(size = 12, align = 4)Sourcepub const fn to_stdlib(self) -> StdLayout
pub const fn to_stdlib(self) -> StdLayout
Converts this layout to an alloc::alloc::Layout.
Sourcepub const fn from_stdlib(layout: StdLayout) -> Layout
pub const fn from_stdlib(layout: StdLayout) -> Layout
Converts an alloc::alloc::Layout to a Layout.
Note that this is only const on Rust versions 1.50 and above.