mstak_util/
heap.rs

1use core::{mem::align_of, ptr::write, slice};
2
3/// A memory block on a heap.
4pub struct Heap<T> {
5    ptr: *mut T,
6    len: usize,
7}
8
9impl<T> Heap<T> {
10    /// Creates a heap.
11    pub fn new(len: usize, default: impl Fn() -> T) -> Self {
12        let mut this = Self {
13            ptr: unsafe { libc::malloc(len * align_of::<T>()) } as _,
14            len,
15        };
16
17        for x in this.as_slice_mut() {
18            unsafe { write(x, default()) };
19        }
20
21        this
22    }
23
24    /// Returns a slice.
25    pub fn as_slice(&mut self) -> &[T] {
26        unsafe { slice::from_raw_parts(self.ptr as _, self.len) }
27    }
28
29    /// Returns a mutable slice.
30    pub fn as_slice_mut(&mut self) -> &mut [T] {
31        unsafe { slice::from_raw_parts_mut(self.ptr as _, self.len) }
32    }
33}
34
35impl<T> Drop for Heap<T> {
36    fn drop(&mut self) {
37        unsafe { libc::free(self.ptr as _) }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn new() {
47        Heap::<usize>::new(42, || 42);
48    }
49
50    #[test]
51    fn new_zero_sized() {
52        Heap::<usize>::new(0, || 42);
53    }
54}