musli/alloc/vec.rs
1use core::fmt;
2use core::mem::ManuallyDrop;
3#[cfg(test)]
4use core::ops::{Deref, DerefMut};
5use core::ptr;
6use core::slice;
7
8use super::{Allocator, RawVec};
9
10/// A vector backed by an [`Allocator`].
11pub struct Vec<'a, T, A>
12where
13 A: 'a + ?Sized + Allocator,
14 T: 'a,
15{
16 buf: A::RawVec<'a, T>,
17 len: usize,
18}
19
20impl<'a, T, A> Vec<'a, T, A>
21where
22 A: 'a + ?Sized + Allocator,
23 T: 'a,
24{
25 /// Construct a buffer vector from raw parts.
26 const unsafe fn from_raw_parts(buf: A::RawVec<'a, T>, len: usize) -> Self {
27 Self { buf, len }
28 }
29
30 /// Construct a new buffer vector.
31 ///
32 /// ## Examples
33 ///
34 /// ```
35 /// use musli::alloc::Vec;
36 ///
37 /// musli::alloc::default!(|alloc| {
38 /// let mut a = Vec::new_in(alloc);
39 ///
40 /// a.push(String::from("Hello"));
41 /// a.push(String::from("World"));
42 ///
43 /// assert_eq!(a.as_slice(), ["Hello", "World"]);
44 /// });
45 /// ```
46 pub fn new_in(alloc: &'a A) -> Self {
47 Self {
48 buf: alloc.new_raw_vec::<T>(),
49 len: 0,
50 }
51 }
52
53 /// Construct a new buffer vector.
54 #[inline]
55 pub const fn new(buf: A::RawVec<'a, T>) -> Self {
56 Self { buf, len: 0 }
57 }
58
59 /// Get the number of initialized elements in the buffer.
60 ///
61 /// ## Examples
62 ///
63 /// ```
64 /// use musli::alloc::Vec;
65 ///
66 /// musli::alloc::default!(|alloc| {
67 /// let mut a = Vec::new_in(alloc);
68 ///
69 /// assert_eq!(a.len(), 0);
70 /// a.write(b"Hello");
71 /// assert_eq!(a.len(), 5);
72 /// });
73 /// ```
74 pub fn len(&self) -> usize {
75 self.len
76 }
77
78 /// Check if the buffer is empty.
79 ///
80 /// ## Examples
81 ///
82 /// ```
83 /// use musli::alloc::Vec;
84 ///
85 /// musli::alloc::default!(|alloc| {
86 /// let mut a = Vec::new_in(alloc);
87 ///
88 /// assert!(a.is_empty());
89 /// a.write(b"Hello");
90 /// assert!(!a.is_empty());
91 /// });
92 /// ```
93 #[inline]
94 pub fn is_empty(&self) -> bool {
95 self.len == 0
96 }
97
98 /// Write a single item.
99 ///
100 /// Returns `true` if the item could be successfully written. A `false`
101 /// value indicates that we are out of buffer capacity.
102 ///
103 /// ## Examples
104 ///
105 /// ```
106 /// use musli::alloc::Vec;
107 ///
108 /// musli::alloc::default!(|alloc| {
109 /// let mut a = Vec::new_in(alloc);
110 ///
111 /// a.push(b'H');
112 /// a.push(b'e');
113 /// a.push(b'l');
114 /// a.push(b'l');
115 /// a.push(b'o');
116 ///
117 /// assert_eq!(a.as_slice(), b"Hello");
118 /// });
119 /// ```
120 #[inline]
121 pub fn push(&mut self, item: T) -> bool {
122 if !self.buf.resize(self.len, 1) {
123 return false;
124 }
125
126 // SAFETY: The call to reserve ensures that we have enough capacity.
127 unsafe {
128 self.buf.as_mut_ptr().add(self.len).write(item);
129 self.len += 1;
130 }
131
132 true
133 }
134
135 /// Pop a single item from the buffer.
136 ///
137 /// Returns `None` if the buffer is empty.
138 ///
139 /// ## Examples
140 ///
141 /// ```
142 /// use musli::alloc::Vec;
143 ///
144 /// musli::alloc::default!(|alloc| {
145 /// let mut a = Vec::new_in(alloc);
146 ///
147 /// a.push(String::from("foo"));
148 /// a.push(String::from("bar"));
149 ///
150 /// assert_eq!(a.as_slice(), ["foo", "bar"]);
151 ///
152 /// assert_eq!(a.pop().as_deref(), Some("bar"));
153 /// assert_eq!(a.pop().as_deref(), Some("foo"));
154 /// assert_eq!(a.pop(), None);
155 /// });
156 /// ```
157 pub fn pop(&mut self) -> Option<T> {
158 if self.len == 0 {
159 return None;
160 }
161
162 self.len -= 1;
163
164 // SAFETY: We know that the buffer is initialized up to `len`.
165 unsafe { Some(ptr::read(self.buf.as_ptr().add(self.len))) }
166 }
167
168 /// Clear the buffer vector.
169 ///
170 /// ## Examples
171 ///
172 /// ```
173 /// use musli::alloc::Vec;
174 ///
175 /// musli::alloc::default!(|alloc| {
176 /// let mut a = Vec::new_in(alloc);
177 ///
178 /// a.push(b'H');
179 /// a.push(b'e');
180 /// a.push(b'l');
181 /// a.push(b'l');
182 /// a.push(b'o');
183 ///
184 /// assert_eq!(a.as_slice(), b"Hello");
185 /// a.clear();
186 /// assert_eq!(a.as_slice(), b"");
187 /// });
188 /// ```
189 pub fn clear(&mut self) {
190 // SAFETY: We know that the buffer is initialized up to `len`.
191 unsafe { ptr::drop_in_place(slice::from_raw_parts_mut(self.buf.as_mut_ptr(), self.len)) }
192 self.len = 0;
193 }
194
195 /// Get the initialized part of the buffer as a slice.
196 ///
197 /// ## Examples
198 ///
199 /// ```
200 /// use musli::alloc::Vec;
201 ///
202 /// musli::alloc::default!(|alloc| {
203 /// let mut a = Vec::new_in(alloc);
204 /// assert_eq!(a.as_slice(), b"");
205 /// a.write(b"Hello");
206 /// assert_eq!(a.as_slice(), b"Hello");
207 /// });
208 /// ```
209 pub fn as_slice(&self) -> &[T] {
210 // SAFETY: We know that the buffer is initialized up to `self.len`.
211 unsafe { slice::from_raw_parts(self.buf.as_ptr(), self.len) }
212 }
213
214 #[inline]
215 fn into_raw_parts(self) -> (A::RawVec<'a, T>, usize) {
216 let this = ManuallyDrop::new(self);
217
218 // SAFETY: The interior buffer is valid and will not be dropped thanks to `ManuallyDrop`.
219 unsafe {
220 let buf = ptr::addr_of!(this.buf).read();
221 (buf, this.len)
222 }
223 }
224}
225
226impl<'a, T, A> Vec<'a, T, A>
227where
228 A: 'a + ?Sized + Allocator,
229 T: 'a + Copy,
230{
231 /// Write the given number of bytes.
232 ///
233 /// Returns `true` if the bytes could be successfully written. A `false`
234 /// value indicates that we are out of buffer capacity.
235 ///
236 /// ## Examples
237 ///
238 /// ```
239 /// use musli::alloc::Vec;
240 ///
241 /// musli::alloc::default!(|alloc| {
242 /// let mut a = Vec::new_in(alloc);
243 /// assert_eq!(a.len(), 0);
244 /// a.write(b"Hello");
245 /// assert_eq!(a.len(), 5);
246 /// });
247 /// ```
248 pub fn write(&mut self, items: &[T]) -> bool {
249 if !self.buf.resize(self.len, items.len()) {
250 return false;
251 }
252
253 // SAFETY: The call to reserve ensures that we have enough capacity.
254 unsafe {
255 self.buf
256 .as_mut_ptr()
257 .add(self.len)
258 .copy_from_nonoverlapping(items.as_ptr(), items.len());
259 self.len += items.len();
260 }
261
262 true
263 }
264
265 /// Write a buffer of the same type onto the current buffer.
266 ///
267 /// This allows allocators to provide more efficient means of extending the
268 /// current buffer with one provided from the same allocator.
269 ///
270 /// ## Examples
271 ///
272 /// ```
273 /// use musli::alloc::Vec;
274 ///
275 /// musli::alloc::default!(|alloc| {
276 /// let mut a = Vec::new_in(alloc);
277 /// let mut b = Vec::new_in(alloc);
278 ///
279 /// a.write(b"Hello");
280 /// b.write(b" World");
281 ///
282 /// a.extend(b);
283 /// assert_eq!(a.as_slice(), b"Hello World");
284 /// });
285 /// ```
286 #[inline]
287 pub fn extend(&mut self, other: Vec<'_, T, A>) -> bool {
288 let (other, other_len) = other.into_raw_parts();
289
290 // Try to merge one buffer with another.
291 if let Err(buf) = self.buf.try_merge(self.len, other, other_len) {
292 let other = unsafe { Vec::<T, A>::from_raw_parts(buf, other_len) };
293 return self.write(other.as_slice());
294 }
295
296 self.len += other_len;
297 true
298 }
299}
300
301/// Try to write a format string into the buffer.
302///
303/// ## Examples
304///
305/// ```
306/// use core::fmt::Write;
307///
308/// use musli::alloc::Vec;
309///
310/// musli::alloc::default!(|alloc| {
311/// let mut a = Vec::new_in(alloc);
312/// let world = "World";
313///
314/// write!(a, "Hello {world}")?;
315///
316/// assert_eq!(a.as_slice(), b"Hello World");
317/// });
318/// # Ok::<(), core::fmt::Error>(())
319/// ```
320impl<'a, A> fmt::Write for Vec<'a, u8, A>
321where
322 A: 'a + ?Sized + Allocator,
323{
324 #[inline]
325 fn write_str(&mut self, s: &str) -> fmt::Result {
326 if !self.write(s.as_bytes()) {
327 return Err(fmt::Error);
328 }
329
330 Ok(())
331 }
332}
333
334#[cfg(test)]
335impl<'a, T, A> Deref for Vec<'a, T, A>
336where
337 A: 'a + ?Sized + Allocator,
338 T: 'a,
339{
340 type Target = A::RawVec<'a, T>;
341
342 #[inline]
343 fn deref(&self) -> &Self::Target {
344 &self.buf
345 }
346}
347
348#[cfg(test)]
349impl<'a, T, A> DerefMut for Vec<'a, T, A>
350where
351 A: 'a + ?Sized + Allocator,
352 T: 'a,
353{
354 #[inline]
355 fn deref_mut(&mut self) -> &mut Self::Target {
356 &mut self.buf
357 }
358}
359
360impl<'a, T, A> Drop for Vec<'a, T, A>
361where
362 A: 'a + ?Sized + Allocator,
363 T: 'a,
364{
365 fn drop(&mut self) {
366 self.clear();
367 }
368}