musli_core/alloc/alloc.rs
1use super::AllocError;
2
3/// A value allocated through [`Allocator::alloc`].
4///
5/// [`Allocator::alloc`]: super::Allocator::alloc
6///
7/// ## Examples
8///
9/// ```
10/// use musli::alloc::{AllocError, Allocator, Alloc};
11///
12/// musli::alloc::default(|alloc| {
13/// let mut buf = alloc.alloc(10u32)?;
14///
15/// unsafe {
16/// buf.as_mut_ptr().write(20u32);
17/// assert_eq!(buf.as_ptr().read(), 20u32);
18/// }
19///
20/// Ok::<_, AllocError>(())
21/// });
22/// # Ok::<_, AllocError>(())
23/// ```
24///
25/// Example of a correctly managed slice allocation:
26///
27/// ```
28/// use core::slice;
29/// use musli::alloc::{Alloc, AllocError, Allocator};
30///
31/// let values: [u32; 4] = [1, 2, 3, 4];
32///
33/// musli::alloc::default(|alloc| {
34/// let mut buf = alloc.alloc_empty::<u32>();
35/// let mut len = 0;
36///
37/// for value in values {
38/// buf.resize(len, 1)?;
39///
40/// // SAFETY: We've just resized the above buffer.
41/// unsafe {
42/// buf.as_mut_ptr().add(len).write(value);
43/// }
44///
45/// len += 1;
46/// }
47///
48/// // SAFETY: Slice does not outlive the buffer it references.
49/// let bytes = unsafe { slice::from_raw_parts(buf.as_ptr(), len) };
50/// assert_eq!(bytes, values);
51/// Ok::<_, AllocError>(())
52/// });
53/// # Ok::<_, AllocError>(())
54/// ```
55pub trait Alloc<T>: Sized {
56 /// Get a pointer into the allocation.
57 ///
58 /// ## Examples
59 ///
60 /// ```
61 /// use musli::alloc::{AllocError, Allocator, Alloc};
62 ///
63 /// musli::alloc::default(|alloc| {
64 /// let mut buf = alloc.alloc(10u32)?;
65 ///
66 /// unsafe {
67 /// buf.as_mut_ptr().write(20u32);
68 /// assert_eq!(buf.as_ptr().read(), 20u32);
69 /// }
70 ///
71 /// Ok::<_, AllocError>(())
72 /// });
73 /// # Ok::<_, AllocError>(())
74 /// ```
75 fn as_ptr(&self) -> *const T;
76
77 /// Get a mutable pointer into the allocation.
78 ///
79 /// ## Examples
80 ///
81 /// ```
82 /// use musli::alloc::{AllocError, Allocator, Alloc};
83 ///
84 /// musli::alloc::default(|alloc| {
85 /// let mut buf = alloc.alloc(10u32)?;
86 ///
87 /// unsafe {
88 /// buf.as_mut_ptr().write(20u32);
89 /// assert_eq!(buf.as_ptr().read(), 20u32);
90 /// }
91 ///
92 /// Ok::<_, AllocError>(())
93 /// });
94 /// # Ok::<_, AllocError>(())
95 /// ```
96 fn as_mut_ptr(&mut self) -> *mut T;
97
98 /// Returns the capacity of the buffer.
99 fn capacity(&self) -> usize;
100
101 /// Resize the buffer to fit at least additional elements.
102 ///
103 /// Returns the new capacity of the buffer.
104 fn resize(&mut self, len: usize, additional: usize) -> Result<(), AllocError>;
105
106 /// Try to merge one buffer with another.
107 ///
108 /// The two length parameters refers to the initialized length of the two
109 /// buffers.
110 ///
111 /// If this returns `Err(B)` if merging was not possible.
112 ///
113 /// Returns the capacity of the newly merged buffer.
114 fn try_merge<B>(&mut self, this_len: usize, other: B, other_len: usize) -> Result<(), B>
115 where
116 B: Alloc<T>;
117}