1use crate::{AcpiError, AcpiResult};
2use core::{
3 alloc::{Allocator, Layout},
4 mem,
5 ptr::NonNull,
6};
7
8#[derive(Debug)]
11pub struct ManagedSlice<'a, T, A>
12where
13 A: Allocator,
14{
15 slice: &'a mut [T],
16 allocator: A,
17}
18
19impl<T, A> ManagedSlice<'_, T, A>
20where
21 A: Allocator,
22{
23 pub fn new_in(len: usize, allocator: A) -> AcpiResult<Self> {
25 let layout = Layout::array::<T>(len).map_err(|_| AcpiError::AllocError)?;
26 match allocator.allocate(layout) {
27 Ok(mut ptr) => {
28 let slice = unsafe { core::slice::from_raw_parts_mut(ptr.as_mut().as_mut_ptr().cast(), len) };
29 Ok(ManagedSlice { slice, allocator })
30 }
31 Err(_) => Err(AcpiError::AllocError),
32 }
33 }
34}
35
36#[cfg(feature = "alloc")]
37impl<T> ManagedSlice<'_, T, alloc::alloc::Global> {
38 pub fn new(len: usize) -> AcpiResult<Self> {
39 Self::new_in(len, alloc::alloc::Global)
40 }
41}
42
43impl<T, A> Drop for ManagedSlice<'_, T, A>
44where
45 A: Allocator,
46{
47 fn drop(&mut self) {
48 unsafe {
49 let slice_ptr = NonNull::new_unchecked(self.slice.as_ptr().cast_mut().cast::<u8>());
50 let slice_layout =
51 Layout::from_size_align_unchecked(mem::size_of_val(self.slice), mem::align_of_val(self.slice));
52 self.allocator.deallocate(slice_ptr, slice_layout);
53 }
54 }
55}
56
57impl<T, A> core::ops::Deref for ManagedSlice<'_, T, A>
58where
59 A: Allocator,
60{
61 type Target = [T];
62
63 fn deref(&self) -> &Self::Target {
64 self.slice
65 }
66}
67
68impl<T, A> core::ops::DerefMut for ManagedSlice<'_, T, A>
69where
70 A: Allocator,
71{
72 fn deref_mut(&mut self) -> &mut Self::Target {
73 self.slice
74 }
75}
76
77impl<T: Clone, A: Allocator + Clone> Clone for ManagedSlice<'_, T, A> {
78 fn clone(&self) -> Self {
79 let mut new_managed_slice = ManagedSlice::new_in(self.len(), self.allocator.clone()).unwrap();
80 new_managed_slice.clone_from_slice(self);
81 new_managed_slice
82 }
83}