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 69 70 71 72 73 74 75 76 77 78
#[cfg(not(feature = "std"))] use alloc::alloc::{self, handle_alloc_error, Layout}; use core::{cmp, mem}; #[cfg(feature = "std")] use std::alloc::{self, handle_alloc_error, Layout}; #[cfg(test)] use core::ops::{Deref, DerefMut}; #[cfg(test)] use core::slice; pub(crate) struct Alloc<T> { ptr: *mut T, len: usize, align: usize, } impl<T> Alloc<T> { #[inline] pub unsafe fn new(nelem: usize, align: usize) -> Self { let align = cmp::max(align, mem::align_of::<T>()); #[cfg(debug_assertions)] let layout = Layout::from_size_align(mem::size_of::<T>() * nelem, align).unwrap(); #[cfg(not(debug_assertions))] let layout = Layout::from_size_align_unchecked(mem::size_of::<T>() * nelem, align); dprint!("Allocating nelem={}, layout={:?}", nelem, layout); let ptr = alloc::alloc(layout); if ptr.is_null() { handle_alloc_error(layout); } Alloc { ptr: ptr as *mut T, len: nelem, align, } } #[cfg(test)] pub fn init_with(mut self, elt: T) -> Alloc<T> where T: Copy, { for elt1 in &mut self[..] { *elt1 = elt; } self } #[inline] pub fn ptr_mut(&mut self) -> *mut T { self.ptr } } impl<T> Drop for Alloc<T> { fn drop(&mut self) { unsafe { let layout = Layout::from_size_align_unchecked(mem::size_of::<T>() * self.len, self.align); alloc::dealloc(self.ptr as _, layout); } } } #[cfg(test)] impl<T> Deref for Alloc<T> { type Target = [T]; fn deref(&self) -> &[T] { unsafe { slice::from_raw_parts(self.ptr, self.len) } } } #[cfg(test)] impl<T> DerefMut for Alloc<T> { fn deref_mut(&mut self) -> &mut [T] { unsafe { slice::from_raw_parts_mut(self.ptr, self.len) } } }