liu/
util.rs

1pub use aliu::*;
2use alloc::alloc::Layout;
3use core::cell::Cell;
4use core::ptr::NonNull;
5
6#[repr(C)]
7pub struct HeapArrayData<Tag, Item>
8where
9    Item: Copy,
10{
11    tag: Tag,
12    items: [Item],
13}
14
15pub struct HeapArray<Tag, Item, A>
16where
17    Item: Copy,
18    A: Allocator,
19{
20    data: NonNull<HeapArrayData<Tag, Item>>,
21    alloc: A,
22}
23
24impl<Tag, Item> HeapArray<Tag, Item, Global>
25where
26    Item: Copy,
27{
28    #[inline]
29    pub fn new(tag: Tag, items: &[Item]) -> Self {
30        return Self::with_allocator(tag, items, Global);
31    }
32}
33
34impl<Tag, Item, A> HeapArray<Tag, Item, A>
35where
36    Item: Copy,
37    A: Allocator,
38{
39    fn layout(len: usize) -> Layout {
40        #[repr(C)]
41        pub struct Data<Tag, Item>
42        where
43            Item: Copy,
44        {
45            t: Tag,
46            i: Item,
47        }
48
49        let align = core::mem::align_of::<Data<Tag, Item>>();
50        let size = core::mem::size_of::<Data<Tag, Item>>();
51        let item_size = core::mem::size_of::<Item>();
52        let size = size - item_size + item_size * len;
53
54        return unsafe { Layout::from_size_align_unchecked(size, align) };
55    }
56
57    pub fn with_allocator(tag: Tag, items: &[Item], a: A) -> Self {
58        unsafe {
59            let ptr = match a.allocate(Self::layout(items.len())) {
60                Ok(mut p) => p.as_mut(),
61                Err(e) => panic!("rip"),
62            };
63
64            let ptr = ptr.as_mut_ptr() as *mut Item;
65            let data = core::slice::from_raw_parts_mut(ptr, items.len());
66            let data = data as *mut [Item] as *mut HeapArrayData<Tag, Item>;
67
68            let data = &mut *data;
69
70            core::ptr::write(&mut data.tag, tag);
71            data.items.copy_from_slice(items);
72
73            let data = NonNull::new_unchecked(data);
74
75            return Self { data, alloc: a };
76        };
77    }
78}
79
80impl<Tag, Item, A> Drop for HeapArray<Tag, Item, A>
81where
82    Item: Copy,
83    A: Allocator,
84{
85    fn drop(&mut self) {
86        unsafe {
87            let data = self.data.as_mut();
88            let layout = Self::layout(data.items.len());
89
90            core::ptr::drop_in_place(data);
91
92            let data = self.data.cast::<u8>();
93            self.alloc.deallocate(data, layout);
94        }
95    }
96}
97
98impl<Tag, Item, A> core::ops::Deref for HeapArray<Tag, Item, A>
99where
100    Item: Copy,
101    A: Allocator,
102{
103    type Target = HeapArrayData<Tag, Item>;
104
105    fn deref(&self) -> &Self::Target {
106        unsafe {
107            return self.data.as_ref();
108        }
109    }
110}
111
112impl<Tag, Item, A> core::ops::DerefMut for HeapArray<Tag, Item, A>
113where
114    Item: Copy,
115    A: Allocator,
116{
117    fn deref_mut(&mut self) -> &mut Self::Target {
118        unsafe {
119            return self.data.as_mut();
120        }
121    }
122}
123
124#[test]
125fn heap_array() {
126    let mut a = Pod::new();
127
128    for i in 0..100 {
129        a.push(100 - i);
130    }
131
132    let array = HeapArray::new(Box::new(12), &a);
133
134    assert_eq!(&*a, &array.items);
135}