Create new allocation with given size and alignment.
(size: usize, alignment: NonZeroUsize)
| 19 | impl Allocation { |
| 20 | /// Create new allocation with given size and alignment. |
| 21 | pub(crate) fn new(size: usize, alignment: NonZeroUsize) -> Self { |
| 22 | let layout = Layout::array::<u8>(size) |
| 23 | .expect("size fits `isize`") |
| 24 | .align_to(alignment.get()) |
| 25 | .expect("valid alignment"); |
| 26 | |
| 27 | let ptr = if size == 0 { |
| 28 | // That's basically what the standard library does for empty `Vec`s. We are allowed to create an empty |
| 29 | // slice based on this pointer. |
| 30 | NonNull::<u8>::without_provenance(alignment) |
| 31 | } else { |
| 32 | // SAFETY: we made sure that the size is non-zero |
| 33 | let ptr = unsafe { std::alloc::alloc(layout) }; |
| 34 | |
| 35 | match NonNull::new(ptr) { |
| 36 | Some(ptr) => ptr, |
| 37 | None => { |
| 38 | panic!("cannot allocate {size} bytes with alignment {alignment}") |
| 39 | } |
| 40 | } |
| 41 | }; |
| 42 | |
| 43 | Self { layout, ptr } |
| 44 | } |
| 45 | |
| 46 | /// Correctly typed pointer. |
| 47 | fn ptr(&self) -> NonNull<MaybeUninit<u8>> { |