musli_core/alloc/
allocator.rs

1use super::{Alloc, AllocError};
2
3/// An allocator that can be used in combination with a context.
4///
5/// # Safety
6///
7/// Setting `IS_SYSTEM` to `true` has safety implications, since it determines
8/// whether the allocation can be safely converted into a standard container or
9/// not.
10pub unsafe trait Allocator: Copy {
11    /// Whether the allocations returned by this allocatore is backed by the
12    /// system allocator or not.
13    ///
14    /// # Safety
15    ///
16    /// Setting this to `true` has safety implications, since it determines
17    /// whether the allocation can be safely converted into a standard container
18    /// or not.
19    const IS_SYSTEM: bool;
20
21    /// A raw allocation from the allocator.
22    type Alloc<T>: Alloc<T>;
23
24    /// Construct an empty uninitialized raw vector with an alignment matching
25    /// that of `T` that is associated with this allocator.
26    ///
27    /// ## Examples
28    ///
29    /// ```
30    /// use core::slice;
31    /// use musli::alloc::{Alloc, AllocError, Allocator};
32    ///
33    /// let values: [u32; 4] = [1, 2, 3, 4];
34    ///
35    /// musli::alloc::default(|alloc| {
36    ///     let mut buf = alloc.alloc_empty::<u32>();
37    ///     let mut len = 0;
38    ///
39    ///     for value in values {
40    ///         buf.resize(len, 1)?;
41    ///
42    ///         // SAFETY: We've just resized the above buffer.
43    ///         unsafe {
44    ///             buf.as_mut_ptr().add(len).write(value);
45    ///         }
46    ///
47    ///         len += 1;
48    ///     }
49    ///
50    ///     // SAFETY: Slice does not outlive the buffer it references.
51    ///     let bytes = unsafe { slice::from_raw_parts(buf.as_ptr(), len) };
52    ///     assert_eq!(bytes, values);
53    ///     Ok::<_, AllocError>(())
54    /// });
55    /// # Ok::<_, AllocError>(())
56    /// ```
57    fn alloc_empty<T>(self) -> Self::Alloc<T>;
58
59    /// Construct an empty uninitialized raw allocation with an alignment
60    /// matching that of `T` that is associated with this allocator.
61    ///
62    /// ## Examples
63    ///
64    /// ```
65    /// use musli::alloc::{AllocError, Allocator, Alloc};
66    ///
67    /// musli::alloc::default(|alloc| {
68    ///     let mut buf = alloc.alloc(10u32)?;
69    ///
70    ///     unsafe {
71    ///         buf.as_mut_ptr().write(20u32);
72    ///         assert_eq!(buf.as_ptr().read(), 20u32);
73    ///     }
74    ///
75    ///     Ok::<_, AllocError>(())
76    /// });
77    /// # Ok::<_, AllocError>(())
78    /// ```
79    fn alloc<T>(self, value: T) -> Result<Self::Alloc<T>, AllocError>;
80}