osom_lib_alloc/traits.rs
1use core::alloc::Layout;
2use core::fmt::Debug;
3use core::hash::Hash;
4
5/// Represents an error that occurs when allocating memory.
6/// Most likely due to out of memory.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[must_use]
9pub struct AllocationError;
10
11/// Represents a newly allocated piece of memory. Typically a thin wrapper
12/// around raw `*mut u8` pointer, but type safe.
13///
14/// # Safety
15///
16/// Any type implementing this trait must ensure that the memory
17/// is ultimately deallocated by calling [`AllocatedMemory::deallocate`].
18#[must_use]
19pub unsafe trait AllocatedMemory: Sized + PartialEq + Eq + Clone + Hash + Debug {
20 /// Converts the [`AllocatedMemory`] into a raw pointer.
21 ///
22 /// # Safety
23 ///
24 /// This function is unsafe since it doesn't move ownership, and so
25 /// multiple copies of the same memory can exist. Moreover it does not
26 /// validate the pointer, in particular it does not check whether it is
27 /// properly aligned for the type `T`.
28 unsafe fn as_ptr<T: Sized>(&self) -> *mut T;
29
30 /// Resizes the [`AllocatedMemory`] to a new layout.
31 ///
32 /// # Errors
33 ///
34 /// Returns an [`AllocationError`] if the memory cannot be resized.
35 fn resize(self, old_layout: Layout, new_layout: Layout) -> Result<Self, AllocationError>;
36
37 /// Deallocates the [`AllocatedMemory`].
38 fn deallocate(self, layout: Layout);
39}
40
41/// Represents a memory allocator.
42///
43/// # Safety
44///
45/// This trait is inherently unsafe, because it deals with raw pointers
46/// and memory management.
47#[must_use]
48pub unsafe trait Allocator: Default + Clone + Debug + Send + Sync {
49 type TAllocatedMemory: AllocatedMemory;
50
51 /// Allocates a new [`AllocatedMemory`] with the given layout.
52 ///
53 /// # Errors
54 ///
55 /// Returns an [`AllocationError`] if the memory cannot be allocated.
56 fn allocate(&self, layout: Layout) -> Result<Self::TAllocatedMemory, AllocationError>;
57
58 /// Creates an [`AllocatedMemory`] from a raw pointer.
59 ///
60 /// # Safety
61 ///
62 /// The pointer must originally arise from calling [`Allocator::allocate`].
63 /// Otherwise the behaviour is undefined.
64 unsafe fn convert_raw_ptr<T: Sized>(&self, ptr: *mut T) -> Self::TAllocatedMemory;
65
66 /// Creates a new dangling [`AllocatedMemory`]. This pointer
67 /// is non-zero, not valid but well-aligned. Note that it should
68 /// not be deallocated, nor dereferenced. It does however represent
69 /// a valid pointer to the type `T`.
70 ///
71 /// It is useful for example for creating slices of length 0
72 /// and other lazily-initialized things.
73 ///
74 /// # Safety
75 ///
76 /// This function is unsafe, because the pointer is not valid.
77 /// It is up to the caller to ensure that it is not used directly,
78 /// in particular it should never be dereferenced and deallocated.
79 unsafe fn dangling<T: Sized>(&self) -> Self::TAllocatedMemory;
80}