1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use alloc::alloc;
use core::{
alloc::{AllocError, Layout},
mem,
ptr::{slice_from_raw_parts, slice_from_raw_parts_mut, NonNull},
};
pub struct AllocGuard {
ptr: NonNull<u8>,
layout: Layout,
}
impl AllocGuard {
pub fn new(layout: Layout) -> Result<Self, AllocError> {
unsafe {
NonNull::new(alloc::alloc(layout))
.map_or(Err(AllocError), |ptr| Ok(Self::from_ptr(ptr, layout)))
}
}
pub fn ptr(&self) -> NonNull<u8> {
self.ptr.clone()
}
pub fn as_slice(&self) -> &[u8] {
unsafe { &*slice_from_raw_parts(self.ptr.as_ptr() as *const _, self.layout.size()) }
}
pub fn as_mut_slice(&self) -> &mut [u8] {
unsafe { &mut *slice_from_raw_parts_mut(self.ptr.as_ptr(), self.layout.size()) }
}
pub fn consume(self) {
mem::forget(self)
}
pub unsafe fn from_ptr(ptr: NonNull<u8>, layout: Layout) -> Self {
Self { ptr, layout }
}
}
impl Drop for AllocGuard {
fn drop(&mut self) {
unsafe { alloc::dealloc(self.ptr.as_ptr(), self.layout) }
}
}
unsafe impl Sync for AllocGuard {}
unsafe impl Send for AllocGuard {}