1use alloc::alloc::{alloc, dealloc};
2use core::{alloc::Layout, ptr::write, slice};
3
4pub struct Heap<T> {
6 ptr: *mut T,
7 len: usize,
8}
9
10impl<T> Heap<T> {
11 pub fn new(len: usize, default: impl Fn() -> T) -> Self {
17 let mut this = Self {
18 ptr: unsafe { alloc(Layout::array::<T>(len).unwrap()) } as _,
20 len,
21 };
22
23 for x in this.as_slice_mut() {
24 unsafe { write(x, default()) };
26 }
27
28 this
29 }
30
31 pub const fn as_slice(&mut self) -> &[T] {
33 unsafe { slice::from_raw_parts(self.ptr as _, self.len) }
35 }
36
37 pub const fn as_slice_mut(&mut self) -> &mut [T] {
39 unsafe { slice::from_raw_parts_mut(self.ptr as _, self.len) }
41 }
42}
43
44impl<T> Drop for Heap<T> {
45 fn drop(&mut self) {
46 unsafe { dealloc(self.ptr as _, Layout::new::<T>()) }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn new() {
57 Heap::<usize>::new(42, || 42);
58 }
59
60 #[test]
61 fn new_zero_sized() {
62 Heap::<usize>::new(0, || 42);
63 }
64}