managed_slice.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. use crate::{AcpiError, AcpiResult};
  2. use core::{
  3. alloc::{Allocator, Layout},
  4. mem,
  5. ptr::NonNull,
  6. };
  7. /// Thin wrapper around a regular slice, taking a reference to an allocator for automatic
  8. /// deallocation when the slice is dropped out of scope.
  9. #[derive(Debug)]
  10. pub struct ManagedSlice<'a, T, A>
  11. where
  12. A: Allocator,
  13. {
  14. slice: &'a mut [T],
  15. allocator: A,
  16. }
  17. impl<'a, T, A> ManagedSlice<'a, T, A>
  18. where
  19. A: Allocator,
  20. {
  21. /// Attempt to allocate a new `ManagedSlice` that holds `len` `T`s.
  22. pub fn new_in(len: usize, allocator: A) -> AcpiResult<Self> {
  23. let layout = Layout::array::<T>(len).map_err(|_| AcpiError::AllocError)?;
  24. match allocator.allocate(layout) {
  25. Ok(mut ptr) => {
  26. let slice = unsafe { core::slice::from_raw_parts_mut(ptr.as_mut().as_mut_ptr().cast(), len) };
  27. Ok(ManagedSlice { slice, allocator })
  28. }
  29. Err(_) => Err(AcpiError::AllocError),
  30. }
  31. }
  32. }
  33. #[cfg(feature = "alloc")]
  34. impl<'a, T> ManagedSlice<'a, T, alloc::alloc::Global> {
  35. pub fn new(len: usize) -> AcpiResult<Self> {
  36. Self::new_in(len, alloc::alloc::Global)
  37. }
  38. }
  39. impl<'a, T, A> Drop for ManagedSlice<'a, T, A>
  40. where
  41. A: Allocator,
  42. {
  43. fn drop(&mut self) {
  44. unsafe {
  45. let slice_ptr = NonNull::new_unchecked(self.slice.as_ptr().cast_mut().cast::<u8>());
  46. let slice_layout =
  47. Layout::from_size_align_unchecked(mem::size_of_val(self.slice), mem::align_of_val(self.slice));
  48. self.allocator.deallocate(slice_ptr, slice_layout);
  49. }
  50. }
  51. }
  52. impl<'a, T, A> core::ops::Deref for ManagedSlice<'a, T, A>
  53. where
  54. A: Allocator,
  55. {
  56. type Target = [T];
  57. fn deref(&self) -> &Self::Target {
  58. self.slice
  59. }
  60. }
  61. impl<'a, T, A> core::ops::DerefMut for ManagedSlice<'a, T, A>
  62. where
  63. A: Allocator,
  64. {
  65. fn deref_mut(&mut self) -> &mut Self::Target {
  66. self.slice
  67. }
  68. }