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}