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}