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}