rkyv_test/util/
aligned_vec.rs

1#[cfg(not(feature = "std"))]
2use ::alloc::{alloc, boxed::Box, vec::Vec};
3use core::borrow::{Borrow, BorrowMut};
4use core::{
5    fmt,
6    ops::{Deref, DerefMut, Index, IndexMut},
7    ptr::NonNull,
8    slice,
9};
10#[cfg(feature = "std")]
11use std::{alloc, io};
12
13/// A vector of bytes that aligns its memory to 16 bytes.
14pub struct AlignedVec {
15    ptr: NonNull<u8>,
16    cap: usize,
17    len: usize,
18}
19
20impl Drop for AlignedVec {
21    #[inline]
22    fn drop(&mut self) {
23        if self.cap != 0 {
24            unsafe {
25                alloc::dealloc(self.ptr.as_ptr(), self.layout());
26            }
27        }
28    }
29}
30
31impl AlignedVec {
32    /// The alignment of the vector
33    pub const ALIGNMENT: usize = 16;
34
35    /// Constructs a new, empty `AlignedVec`.
36    ///
37    /// The vector will not allocate until elements are pushed into it.
38    ///
39    /// # Examples
40    /// ```
41    /// use rkyv::AlignedVec;
42    ///
43    /// let mut vec = AlignedVec::new();
44    /// ```
45    #[inline]
46    pub fn new() -> Self {
47        AlignedVec {
48            ptr: NonNull::dangling(),
49            cap: 0,
50            len: 0,
51        }
52    }
53
54    /// Constructs a new, empty `AlignedVec` with the specified capacity.
55    ///
56    /// The vector will be able to hold exactly `capacity` bytes without reallocating. If
57    /// `capacity` is 0, the vector will not allocate.
58    ///
59    /// # Examples
60    /// ```
61    /// use rkyv::AlignedVec;
62    ///
63    /// let mut vec = AlignedVec::with_capacity(10);
64    ///
65    /// // The vector contains no items, even though it has capacity for more
66    /// assert_eq!(vec.len(), 0);
67    /// assert_eq!(vec.capacity(), 10);
68    ///
69    /// // These are all done without reallocating...
70    /// for i in 0..10 {
71    ///     vec.push(i);
72    /// }
73    /// assert_eq!(vec.len(), 10);
74    /// assert_eq!(vec.capacity(), 10);
75    ///
76    /// // ...but this may make the vector reallocate
77    /// vec.push(11);
78    /// assert_eq!(vec.len(), 11);
79    /// assert!(vec.capacity() >= 11);
80    /// ```
81    #[inline]
82    pub fn with_capacity(capacity: usize) -> Self {
83        if capacity == 0 {
84            Self::new()
85        } else {
86            let ptr = unsafe {
87                alloc::alloc(alloc::Layout::from_size_align_unchecked(
88                    capacity,
89                    Self::ALIGNMENT,
90                ))
91            };
92            Self {
93                ptr: NonNull::new(ptr).unwrap(),
94                cap: capacity,
95                len: 0,
96            }
97        }
98    }
99
100    #[inline]
101    fn layout(&self) -> alloc::Layout {
102        unsafe { alloc::Layout::from_size_align_unchecked(self.cap, Self::ALIGNMENT) }
103    }
104
105    /// Clears the vector, removing all values.
106    ///
107    /// Note that this method has no effect on the allocated capacity of the vector.
108    ///
109    /// # Examples
110    /// ```
111    /// use rkyv::AlignedVec;
112    ///
113    /// let mut v = AlignedVec::new();
114    /// v.extend_from_slice(&[1, 2, 3, 4]);
115    ///
116    /// v.clear();
117    ///
118    /// assert!(v.is_empty());
119    /// ```
120    #[inline]
121    pub fn clear(&mut self) {
122        self.len = 0;
123    }
124
125    #[inline]
126    fn change_capacity(&mut self, new_cap: usize) {
127        if new_cap != self.cap {
128            let new_ptr = unsafe { alloc::realloc(self.ptr.as_ptr(), self.layout(), new_cap) };
129            self.ptr = NonNull::new(new_ptr).unwrap();
130            self.cap = new_cap;
131        }
132    }
133
134    /// Shrinks the capacity of the vector as much as possible.
135    ///
136    /// It will drop down as close as possible to the length but the allocator may still inform the
137    /// vector that there is space for a few more elements.
138    ///
139    /// # Examples
140    /// ```
141    /// use rkyv::AlignedVec;
142    ///
143    /// let mut vec = AlignedVec::with_capacity(10);
144    /// vec.extend_from_slice(&[1, 2, 3]);
145    /// assert_eq!(vec.capacity(), 10);
146    /// vec.shrink_to_fit();
147    /// assert!(vec.capacity() >= 3);
148    /// ```
149    #[inline]
150    pub fn shrink_to_fit(&mut self) {
151        if self.len == 0 {
152            self.clear()
153        } else {
154            self.change_capacity(self.len);
155        }
156    }
157
158    /// Returns an unsafe mutable pointer to the vector's buffer.
159    ///
160    /// The caller must ensure that the vector outlives the pointer this function returns, or else
161    /// it will end up pointing to garbage. Modifying the vector may cause its buffer to be
162    /// reallocated, which would also make any pointers to it invalid.
163    ///
164    /// # Examples
165    /// ```
166    /// use rkyv::AlignedVec;
167    ///
168    /// // Allocate vecotr big enough for 4 bytes.
169    /// let size = 4;
170    /// let mut x = AlignedVec::with_capacity(size);
171    /// let x_ptr = x.as_mut_ptr();
172    ///
173    /// // Initialize elements via raw pointer writes, then set length.
174    /// unsafe {
175    ///     for i in 0..size {
176    ///         *x_ptr.add(i) = i as u8;
177    ///     }
178    ///     x.set_len(size);
179    /// }
180    /// assert_eq!(&*x, &[0, 1, 2, 3]);
181    /// ```
182    #[inline]
183    pub fn as_mut_ptr(&mut self) -> *mut u8 {
184        self.ptr.as_ptr()
185    }
186
187    /// Extracts a mutable slice of the entire vector.
188    ///
189    /// Equivalent to `&mut s[..]`.
190    ///
191    /// # Examples
192    /// ```
193    /// use rkyv::AlignedVec;
194    ///
195    /// let mut vec = AlignedVec::new();
196    /// vec.extend_from_slice(&[1, 2, 3, 4, 5]);
197    /// assert_eq!(vec.as_mut_slice().len(), 5);
198    /// for i in 0..5 {
199    ///     assert_eq!(vec.as_mut_slice()[i], i as u8 + 1);
200    ///     vec.as_mut_slice()[i] = i as u8;
201    ///     assert_eq!(vec.as_mut_slice()[i], i as u8);
202    /// }
203    /// ```
204    #[inline]
205    pub fn as_mut_slice(&mut self) -> &mut [u8] {
206        unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
207    }
208
209    /// Returns a raw pointer to the vector's buffer.
210    ///
211    /// The caller must ensure that the vector outlives the pointer this function returns, or else
212    /// it will end up pointing to garbage. Modifying the vector may cause its buffer to be
213    /// reallocated, which would also make any pointers to it invalid.
214    ///
215    /// The caller must also ensure that the memory the pointer (non-transitively) points to is
216    /// never written to (except inside an `UnsafeCell`) using this pointer or any pointer derived
217    /// from it. If you need to mutate the contents of the slice, use
218    /// [`as_mut_ptr`](AlignedVec::as_mut_ptr).
219    ///
220    /// # Examples
221    /// ```
222    /// use rkyv::AlignedVec;
223    ///
224    /// let mut x = AlignedVec::new();
225    /// x.extend_from_slice(&[1, 2, 4]);
226    /// let x_ptr = x.as_ptr();
227    ///
228    /// unsafe {
229    ///     for i in 0..x.len() {
230    ///         assert_eq!(*x_ptr.add(i), 1 << i);
231    ///     }
232    /// }
233    /// ```
234    #[inline]
235    pub fn as_ptr(&self) -> *const u8 {
236        self.ptr.as_ptr()
237    }
238
239    /// Extracts a slice containing the entire vector.
240    ///
241    /// Equivalent to `&s[..]`.
242    ///
243    /// # Examples
244    /// ```
245    /// use rkyv::AlignedVec;
246    ///
247    /// let mut vec = AlignedVec::new();
248    /// vec.extend_from_slice(&[1, 2, 3, 4, 5]);
249    /// assert_eq!(vec.as_slice().len(), 5);
250    /// for i in 0..5 {
251    ///     assert_eq!(vec.as_slice()[i], i as u8 + 1);
252    /// }
253    /// ```
254    #[inline]
255    pub fn as_slice(&self) -> &[u8] {
256        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
257    }
258
259    /// Returns the number of elements the vector can hold without reallocating.
260    ///
261    /// # Examples
262    /// ```
263    /// use rkyv::AlignedVec;
264    ///
265    /// let vec = AlignedVec::with_capacity(10);
266    /// assert_eq!(vec.capacity(), 10);
267    /// ```
268    #[inline]
269    pub fn capacity(&self) -> usize {
270        self.cap
271    }
272
273    /// Reserves capacity for at least `additional` more bytes to be inserted into the given
274    /// `AlignedVec`. The collection may reserve more space to avoid frequent reallocations. After
275    /// calling `reserve`, capacity will be greater than or equal to `self.len() + additional`. Does
276    /// nothing if capacity is already sufficient.
277    ///
278    /// # Panics
279    ///
280    /// Panics if the new capacity exceeds `usize::MAX` bytes.
281    ///
282    /// # Examples
283    /// ```
284    /// use rkyv::AlignedVec;
285    ///
286    /// let mut vec = AlignedVec::new();
287    /// vec.push(1);
288    /// vec.reserve(10);
289    /// assert!(vec.capacity() >= 11);
290    /// ```
291    #[inline]
292    pub fn reserve(&mut self, additional: usize) {
293        let new_cap = self.len + additional;
294        if new_cap > self.cap {
295            let new_cap = new_cap
296                .checked_next_power_of_two()
297                .expect("cannot reserve a larger AlignedVec");
298            if self.cap == 0 {
299                let new_ptr = unsafe {
300                    alloc::alloc(alloc::Layout::from_size_align_unchecked(
301                        new_cap,
302                        Self::ALIGNMENT,
303                    ))
304                };
305                self.ptr = NonNull::new(new_ptr).unwrap();
306                self.cap = new_cap;
307            } else {
308                let new_ptr = unsafe { alloc::realloc(self.ptr.as_ptr(), self.layout(), new_cap) };
309                self.ptr = NonNull::new(new_ptr).unwrap();
310                self.cap = new_cap;
311            }
312        }
313    }
314
315    /// Returns `true` if the vector contains no elements.
316    ///
317    /// # Examples
318    /// ```
319    /// use rkyv::AlignedVec;
320    ///
321    /// let mut v = Vec::new();
322    /// assert!(v.is_empty());
323    ///
324    /// v.push(1);
325    /// assert!(!v.is_empty());
326    /// ```
327    #[inline]
328    pub fn is_empty(&self) -> bool {
329        self.len == 0
330    }
331
332    /// Returns the number of elements in the vector, also referred to as its 'length'.
333    ///
334    /// # Examples
335    /// ```
336    /// use rkyv::AlignedVec;
337    ///
338    /// let mut a = AlignedVec::new();
339    /// a.extend_from_slice(&[1, 2, 3]);
340    /// assert_eq!(a.len(), 3);
341    /// ```
342    #[inline]
343    pub fn len(&self) -> usize {
344        self.len
345    }
346
347    /// Copies and appends all bytes in a slice to the `AlignedVec`.
348    ///
349    /// The elements of the slice are appended in-order.
350    ///
351    /// # Examples
352    /// ```
353    /// use rkyv::AlignedVec;
354    ///
355    /// let mut vec = AlignedVec::new();
356    /// vec.push(1);
357    /// vec.extend_from_slice(&[2, 3, 4]);
358    /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
359    /// ```
360    #[inline]
361    pub fn extend_from_slice(&mut self, other: &[u8]) {
362        if !other.is_empty() {
363            self.reserve(other.len());
364            unsafe {
365                core::ptr::copy_nonoverlapping(
366                    other.as_ptr(),
367                    self.as_mut_ptr().add(self.len()),
368                    other.len(),
369                );
370            }
371            self.len += other.len();
372        }
373    }
374
375    /// Removes the last element from a vector and returns it, or `None` if it is empty.
376    ///
377    /// # Examples
378    /// ```
379    /// use rkyv::AlignedVec;
380    ///
381    /// let mut vec = AlignedVec::new();
382    /// vec.extend_from_slice(&[1, 2, 3]);
383    /// assert_eq!(vec.pop(), Some(3));
384    /// assert_eq!(vec.as_slice(), &[1, 2]);
385    /// ```
386    #[inline]
387    pub fn pop(&mut self) -> Option<u8> {
388        if self.len == 0 {
389            None
390        } else {
391            let result = self[self.len - 1];
392            self.len -= 1;
393            Some(result)
394        }
395    }
396
397    /// Appends an element to the back of a collection.
398    ///
399    /// # Panics
400    ///
401    /// Panics if the new capacity exceeds `usize::MAX` bytes.
402    ///
403    /// # Examples
404    /// ```
405    /// use rkyv::AlignedVec;
406    ///
407    /// let mut vec = AlignedVec::new();
408    /// vec.extend_from_slice(&[1, 2]);
409    /// vec.push(3);
410    /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
411    /// ```
412    #[inline]
413    pub fn push(&mut self, value: u8) {
414        unsafe {
415            self.reserve(1);
416            self.as_mut_ptr().add(self.len).write(value);
417            self.len += 1;
418        }
419    }
420
421    /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the
422    /// given `AlignedVec`. After calling `reserve_exact`, capacity will be greater than or equal
423    /// to `self.len() + additional`. Does nothing if the capacity is already sufficient.
424    ///
425    /// Note that the allocator may give the collection more space than it requests. Therefore,
426    /// capacity can not be relied upon to be precisely minimal. Prefer reserve if future insertions
427    /// are expected.
428    ///
429    /// # Panics
430    ///
431    /// Panics if the new capacity overflows `usize`.
432    ///
433    /// # Examples
434    /// ```
435    /// use rkyv::AlignedVec;
436    ///
437    /// let mut vec = AlignedVec::new();
438    /// vec.push(1);
439    /// vec.reserve_exact(10);
440    /// assert!(vec.capacity() >= 11);
441    /// ```
442    #[inline]
443    pub fn reserve_exact(&mut self, additional: usize) {
444        let new_cap = self
445            .len
446            .checked_add(additional)
447            .and_then(|n| n.checked_next_power_of_two())
448            .expect("reserve amount overflowed");
449        self.change_capacity(new_cap);
450    }
451
452    /// Forces the length of the vector to `new_len`.
453    ///
454    /// This is a low-level operation that maintains none of the normal invariants of the type.
455    ///
456    /// # Safety
457    ///
458    /// - `new_len` must be less than or equal to [`capacity()`](AlignedVec::capacity)
459    /// - The elements at `old_len..new_len` must be initialized
460    ///
461    /// # Examples
462    /// ```
463    /// use rkyv::AlignedVec;
464    ///
465    /// let mut vec = AlignedVec::with_capacity(3);
466    /// vec.extend_from_slice(&[1, 2, 3]);
467    ///
468    /// // SAFETY:
469    /// // 1. `old_len..0` is empty to no elements need to be initialized.
470    /// // 2. `0 <= capacity` always holds whatever capacity is.
471    /// unsafe {
472    ///     vec.set_len(0);
473    /// }
474    /// ```
475    #[inline]
476    pub unsafe fn set_len(&mut self, new_len: usize) {
477        debug_assert!(new_len <= self.capacity());
478
479        self.len = new_len;
480    }
481
482    /// Converts the vector into `Box<[u8]>`.
483    ///
484    /// This method reallocates and copies the underlying bytes. Any excess capacity is dropped.
485    ///
486    /// # Examples
487    /// ```
488    /// use rkyv::AlignedVec;
489    ///
490    /// let mut v = AlignedVec::new();
491    /// v.extend_from_slice(&[1, 2, 3]);
492    ///
493    /// let slice = v.into_boxed_slice();
494    /// ```
495    ///
496    /// Any excess capacity is removed:
497    ///
498    /// ```
499    /// use rkyv::AlignedVec;
500    ///
501    /// let mut vec = AlignedVec::with_capacity(10);
502    /// vec.extend_from_slice(&[1, 2, 3]);
503    ///
504    /// assert_eq!(vec.capacity(), 10);
505    /// let slice = vec.into_boxed_slice();
506    /// assert_eq!(slice.len(), 3);
507    /// ```
508    #[inline]
509    pub fn into_boxed_slice(self) -> Box<[u8]> {
510        self.into_vec().into_boxed_slice()
511    }
512
513    /// Converts the vector into `Vec<u8>`.
514    ///
515    /// This method reallocates and copies the underlying bytes. Any excess capacity is dropped.
516    ///
517    /// # Examples
518    /// ```
519    /// use rkyv::AlignedVec;
520    ///
521    /// let mut v = AlignedVec::new();
522    /// v.extend_from_slice(&[1, 2, 3]);
523    ///
524    /// let vec = v.into_vec();
525    /// assert_eq!(vec.len(), 3);
526    /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
527    /// ```
528    #[inline]
529    pub fn into_vec(self) -> Vec<u8> {
530        Vec::from(self.as_ref())
531    }
532}
533
534impl From<AlignedVec> for Vec<u8> {
535    #[inline]
536    fn from(aligned: AlignedVec) -> Self {
537        aligned.to_vec()
538    }
539}
540
541impl AsMut<[u8]> for AlignedVec {
542    #[inline]
543    fn as_mut(&mut self) -> &mut [u8] {
544        self.as_mut_slice()
545    }
546}
547
548impl AsRef<[u8]> for AlignedVec {
549    #[inline]
550    fn as_ref(&self) -> &[u8] {
551        self.as_slice()
552    }
553}
554
555impl Borrow<[u8]> for AlignedVec {
556    #[inline]
557    fn borrow(&self) -> &[u8] {
558        self.as_slice()
559    }
560}
561
562impl BorrowMut<[u8]> for AlignedVec {
563    #[inline]
564    fn borrow_mut(&mut self) -> &mut [u8] {
565        self.as_mut_slice()
566    }
567}
568
569impl Clone for AlignedVec {
570    #[inline]
571    fn clone(&self) -> Self {
572        unsafe {
573            let mut result = AlignedVec::with_capacity(self.len);
574            result.len = self.len;
575            core::ptr::copy_nonoverlapping(self.as_ptr(), result.as_mut_ptr(), self.len);
576            result
577        }
578    }
579}
580
581impl fmt::Debug for AlignedVec {
582    #[inline]
583    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
584        self.as_slice().fmt(f)
585    }
586}
587
588impl Default for AlignedVec {
589    #[inline]
590    fn default() -> Self {
591        Self::new()
592    }
593}
594
595impl Deref for AlignedVec {
596    type Target = [u8];
597
598    #[inline]
599    fn deref(&self) -> &Self::Target {
600        self.as_slice()
601    }
602}
603
604impl DerefMut for AlignedVec {
605    #[inline]
606    fn deref_mut(&mut self) -> &mut Self::Target {
607        self.as_mut_slice()
608    }
609}
610
611impl<I: slice::SliceIndex<[u8]>> Index<I> for AlignedVec {
612    type Output = <I as slice::SliceIndex<[u8]>>::Output;
613
614    #[inline]
615    fn index(&self, index: I) -> &Self::Output {
616        &self.as_slice()[index]
617    }
618}
619
620impl<I: slice::SliceIndex<[u8]>> IndexMut<I> for AlignedVec {
621    #[inline]
622    fn index_mut(&mut self, index: I) -> &mut Self::Output {
623        &mut self.as_mut_slice()[index]
624    }
625}
626
627#[cfg(feature = "std")]
628impl io::Write for AlignedVec {
629    #[inline]
630    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
631        self.extend_from_slice(buf);
632        Ok(buf.len())
633    }
634
635    #[inline]
636    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
637        let len = bufs.iter().map(|b| b.len()).sum();
638        self.reserve(len);
639        for buf in bufs {
640            self.extend_from_slice(buf);
641        }
642        Ok(len)
643    }
644
645    #[inline]
646    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
647        self.extend_from_slice(buf);
648        Ok(())
649    }
650
651    fn flush(&mut self) -> io::Result<()> {
652        Ok(())
653    }
654}
655
656// SAFETY: AlignedVec is safe to send to another thread
657unsafe impl Send for AlignedVec {}
658
659// SAFETY: AlignedVec is safe to share between threads
660unsafe impl Sync for AlignedVec {}
661
662impl Unpin for AlignedVec {}