Skip to main content

rkyv/util/alloc/
aligned_vec.rs

1use core::{
2    alloc::Layout,
3    borrow::{Borrow, BorrowMut},
4    fmt,
5    mem::ManuallyDrop,
6    ops::{Deref, DerefMut, Index, IndexMut},
7    ptr::NonNull,
8    slice,
9};
10
11use rancor::Fallible;
12
13use crate::{
14    alloc::{
15        alloc::{alloc, dealloc, handle_alloc_error, realloc},
16        boxed::Box,
17        vec::Vec,
18    },
19    ser::{Allocator, Writer},
20    vec::{ArchivedVec, VecResolver},
21    with::{ArchiveWith, AsVec, DeserializeWith, SerializeWith},
22    Place,
23};
24
25/// A vector of bytes that aligns its memory to the specified alignment.
26///
27/// ```
28/// # use rkyv::util::AlignedVec;
29/// let bytes = AlignedVec::<4096>::with_capacity(1);
30/// assert_eq!(bytes.as_ptr() as usize % 4096, 0);
31/// ```
32pub struct AlignedVec<const ALIGNMENT: usize = 16> {
33    ptr: NonNull<u8>,
34    cap: usize,
35    len: usize,
36}
37
38impl<const A: usize> Drop for AlignedVec<A> {
39    fn drop(&mut self) {
40        if self.cap != 0 {
41            unsafe {
42                dealloc(self.ptr.as_ptr(), self.layout());
43            }
44        }
45    }
46}
47
48impl<const ALIGNMENT: usize> AlignedVec<ALIGNMENT> {
49    /// The alignment of the vector
50    pub const ALIGNMENT: usize = ALIGNMENT;
51
52    /// Maximum capacity of the vector.
53    ///
54    /// Dictated by the requirements of [`Layout`]. "`size`, when rounded up to
55    /// the nearest multiple of `align`, must not overflow `isize` (i.e. the
56    /// rounded value must be less than or equal to `isize::MAX`)".
57    pub const MAX_CAPACITY: usize = isize::MAX as usize - (Self::ALIGNMENT - 1);
58
59    /// Constructs a new, empty `AlignedVec`.
60    ///
61    /// The vector will not allocate until elements are pushed into it.
62    ///
63    /// # Examples
64    /// ```
65    /// # use rkyv::util::AlignedVec;
66    /// let mut vec = AlignedVec::<16>::new();
67    /// ```
68    pub fn new() -> Self {
69        Self::with_capacity(0)
70    }
71
72    /// Constructs a new, empty `AlignedVec` with the specified capacity.
73    ///
74    /// The vector will be able to hold exactly `capacity` bytes without
75    /// reallocating. If `capacity` is 0, the vector will not allocate.
76    ///
77    /// # Examples
78    /// ```
79    /// # use rkyv::util::AlignedVec;
80    /// let mut vec = AlignedVec::<16>::with_capacity(10);
81    ///
82    /// // The vector contains no items, even though it has capacity for more
83    /// assert_eq!(vec.len(), 0);
84    /// assert_eq!(vec.capacity(), 10);
85    ///
86    /// // These are all done without reallocating...
87    /// for i in 0..10 {
88    ///     vec.push(i);
89    /// }
90    /// assert_eq!(vec.len(), 10);
91    /// assert_eq!(vec.capacity(), 10);
92    ///
93    /// // ...but this may make the vector reallocate
94    /// vec.push(11);
95    /// assert_eq!(vec.len(), 11);
96    /// assert!(vec.capacity() >= 11);
97    /// ```
98    pub fn with_capacity(capacity: usize) -> Self {
99        assert!(ALIGNMENT > 0, "ALIGNMENT must be 1 or more");
100        assert!(
101            ALIGNMENT.is_power_of_two(),
102            "ALIGNMENT must be a power of 2"
103        );
104        // As `ALIGNMENT` has to be a power of 2, this caps `ALIGNMENT` at a max
105        // of `(isize::MAX + 1) / 2` (1 GiB on 32-bit systems).
106        assert!(
107            ALIGNMENT < isize::MAX as usize,
108            "ALIGNMENT must be less than isize::MAX"
109        );
110
111        if capacity == 0 {
112            Self {
113                ptr: NonNull::dangling(),
114                cap: 0,
115                len: 0,
116            }
117        } else {
118            assert!(
119                capacity <= Self::MAX_CAPACITY,
120                "`capacity` cannot exceed `Self::MAX_CAPACITY`"
121            );
122
123            let ptr = unsafe {
124                let layout = Layout::from_size_align_unchecked(
125                    capacity,
126                    Self::ALIGNMENT,
127                );
128                let ptr = alloc(layout);
129                if ptr.is_null() {
130                    handle_alloc_error(layout);
131                }
132                NonNull::new_unchecked(ptr)
133            };
134
135            Self {
136                ptr,
137                cap: capacity,
138                len: 0,
139            }
140        }
141    }
142
143    fn layout(&self) -> Layout {
144        unsafe { Layout::from_size_align_unchecked(self.cap, Self::ALIGNMENT) }
145    }
146
147    /// Clears the vector, removing all values.
148    ///
149    /// Note that this method has no effect on the allocated capacity of the
150    /// vector.
151    ///
152    /// # Examples
153    /// ```
154    /// # use rkyv::util::AlignedVec;
155    /// let mut v = AlignedVec::<16>::new();
156    /// v.extend_from_slice(&[1, 2, 3, 4]);
157    ///
158    /// v.clear();
159    ///
160    /// assert!(v.is_empty());
161    /// ```
162    pub fn clear(&mut self) {
163        self.len = 0;
164    }
165
166    /// Change capacity of vector.
167    ///
168    /// Will set capacity to exactly `new_cap`.
169    /// Can be used to either grow or shrink capacity.
170    /// Backing memory will be reallocated.
171    ///
172    /// Usually the safe methods `reserve` or `reserve_exact` are a better
173    /// choice. This method only exists as a micro-optimization for very
174    /// performance-sensitive code where where the calculation of capacity
175    /// required has already been performed, and you want to avoid doing it
176    /// again, or if you want to implement a different growth strategy.
177    ///
178    /// # Safety
179    ///
180    /// - `new_cap` must be less than or equal to
181    ///   [`MAX_CAPACITY`](AlignedVec::MAX_CAPACITY)
182    /// - `new_cap` must be greater than or equal to [`len()`](AlignedVec::len)
183    pub unsafe fn change_capacity(&mut self, new_cap: usize) {
184        debug_assert!(new_cap <= Self::MAX_CAPACITY);
185        debug_assert!(new_cap >= self.len);
186
187        if new_cap > 0 {
188            let new_ptr = if self.cap > 0 {
189                // SAFETY:
190                // - `self.ptr` is currently allocated because `self.cap` is
191                //   greater than zero.
192                // - `self.layout()` always matches the layout used to allocate
193                //   the current block of memory.
194                // - We checked that `new_cap` is greater than zero.
195                let new_ptr = unsafe {
196                    realloc(self.ptr.as_ptr(), self.layout(), new_cap)
197                };
198                if new_ptr.is_null() {
199                    // SAFETY:
200                    // - `ALIGNMENT` is always guaranteed to be a nonzero power
201                    //   of two.
202                    // - We checked that `new_cap` doesn't overflow `isize` when
203                    //   rounded up to the nearest power of two.
204                    let layout = unsafe {
205                        Layout::from_size_align_unchecked(
206                            new_cap,
207                            Self::ALIGNMENT,
208                        )
209                    };
210                    handle_alloc_error(layout);
211                }
212                new_ptr
213            } else {
214                // SAFETY:
215                // - `ALIGNMENT` is always guaranteed to be a nonzero power of
216                //   two.
217                // - We checked that `new_cap` doesn't overflow `isize` when
218                //   rounded up to the nearest power of two.
219                let layout = unsafe {
220                    Layout::from_size_align_unchecked(new_cap, Self::ALIGNMENT)
221                };
222                // SAFETY: We checked that `new_cap` has non-zero size.
223                let new_ptr = unsafe { alloc(layout) };
224                if new_ptr.is_null() {
225                    handle_alloc_error(layout);
226                }
227                new_ptr
228            };
229            // SAFETY: We checked that `new_ptr` is non-null in each of the
230            // branches.
231            self.ptr = unsafe { NonNull::new_unchecked(new_ptr) };
232            self.cap = new_cap;
233        } else if self.cap > 0 {
234            // SAFETY: Because the capacity is nonzero, `self.ptr` points to a
235            // currently-allocated memory block. All memory blocks are allocated
236            // with a layout of `self.layout()`.
237            unsafe {
238                dealloc(self.ptr.as_ptr(), self.layout());
239            }
240            self.ptr = NonNull::dangling();
241            self.cap = 0;
242        }
243    }
244
245    /// Shrinks the capacity of the vector as much as possible.
246    ///
247    /// It will drop down as close as possible to the length but the allocator
248    /// may still inform the vector that there is space for a few more
249    /// elements.
250    ///
251    /// # Examples
252    /// ```
253    /// # use rkyv::util::AlignedVec;
254    /// let mut vec = AlignedVec::<16>::with_capacity(10);
255    /// vec.extend_from_slice(&[1, 2, 3]);
256    /// assert_eq!(vec.capacity(), 10);
257    /// vec.shrink_to_fit();
258    /// assert!(vec.capacity() >= 3);
259    ///
260    /// vec.clear();
261    /// vec.shrink_to_fit();
262    /// assert!(vec.capacity() == 0);
263    /// ```
264    pub fn shrink_to_fit(&mut self) {
265        if self.cap != self.len {
266            // New capacity cannot exceed max as it's shrinking
267            unsafe { self.change_capacity(self.len) };
268        }
269    }
270
271    /// Returns an unsafe mutable pointer to the vector's buffer.
272    ///
273    /// The caller must ensure that the vector outlives the pointer this
274    /// function returns, or else it will end up pointing to garbage.
275    /// Modifying the vector may cause its buffer to be reallocated, which
276    /// would also make any pointers to it invalid.
277    ///
278    /// # Examples
279    /// ```
280    /// # use rkyv::util::AlignedVec;
281    /// // Allocate 1-aligned vector big enough for 4 bytes.
282    /// let size = 4;
283    /// let mut x = AlignedVec::<1>::with_capacity(size);
284    /// let x_ptr = x.as_mut_ptr();
285    ///
286    /// // Initialize elements via raw pointer writes, then set length.
287    /// unsafe {
288    ///     for i in 0..size {
289    ///         *x_ptr.add(i) = i as u8;
290    ///     }
291    ///     x.set_len(size);
292    /// }
293    /// assert_eq!(&*x, &[0, 1, 2, 3]);
294    /// ```
295    pub fn as_mut_ptr(&mut self) -> *mut u8 {
296        self.ptr.as_ptr()
297    }
298
299    /// Extracts a mutable slice of the entire vector.
300    ///
301    /// Equivalent to `&mut s[..]`.
302    ///
303    /// # Examples
304    /// ```
305    /// # use rkyv::util::AlignedVec;
306    /// let mut vec = AlignedVec::<16>::new();
307    /// vec.extend_from_slice(&[1, 2, 3, 4, 5]);
308    /// assert_eq!(vec.as_mut_slice().len(), 5);
309    /// for i in 0..5 {
310    ///     assert_eq!(vec.as_mut_slice()[i], i as u8 + 1);
311    ///     vec.as_mut_slice()[i] = i as u8;
312    ///     assert_eq!(vec.as_mut_slice()[i], i as u8);
313    /// }
314    /// ```
315    pub fn as_mut_slice(&mut self) -> &mut [u8] {
316        unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
317    }
318
319    /// Returns a raw pointer to the vector's buffer.
320    ///
321    /// The caller must ensure that the vector outlives the pointer this
322    /// function returns, or else it will end up pointing to garbage.
323    /// Modifying the vector may cause its buffer to be reallocated, which
324    /// would also make any pointers to it invalid.
325    ///
326    /// The caller must also ensure that the memory the pointer
327    /// (non-transitively) points to is never written to (except inside an
328    /// `UnsafeCell`) using this pointer or any pointer derived from it. If
329    /// you need to mutate the contents of the slice, use
330    /// [`as_mut_ptr`](AlignedVec::as_mut_ptr).
331    ///
332    /// # Examples
333    /// ```
334    /// # use rkyv::util::AlignedVec;
335    /// let mut x = AlignedVec::<16>::new();
336    /// x.extend_from_slice(&[1, 2, 4]);
337    /// let x_ptr = x.as_ptr();
338    ///
339    /// unsafe {
340    ///     for i in 0..x.len() {
341    ///         assert_eq!(*x_ptr.add(i), 1 << i);
342    ///     }
343    /// }
344    /// ```
345    pub fn as_ptr(&self) -> *const u8 {
346        self.ptr.as_ptr()
347    }
348
349    /// Extracts a slice containing the entire vector.
350    ///
351    /// Equivalent to `&s[..]`.
352    ///
353    /// # Examples
354    /// ```
355    /// # use rkyv::util::AlignedVec;
356    /// let mut vec = AlignedVec::<16>::new();
357    /// vec.extend_from_slice(&[1, 2, 3, 4, 5]);
358    /// assert_eq!(vec.as_slice().len(), 5);
359    /// for i in 0..5 {
360    ///     assert_eq!(vec.as_slice()[i], i as u8 + 1);
361    /// }
362    /// ```
363    pub fn as_slice(&self) -> &[u8] {
364        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
365    }
366
367    /// Returns the number of elements the vector can hold without reallocating.
368    ///
369    /// # Examples
370    /// ```
371    /// # use rkyv::util::AlignedVec;
372    /// let vec = AlignedVec::<16>::with_capacity(10);
373    /// assert_eq!(vec.capacity(), 10);
374    /// ```
375    pub fn capacity(&self) -> usize {
376        self.cap
377    }
378
379    /// Reserves capacity for at least `additional` more bytes to be inserted
380    /// into the given `AlignedVec`. The collection may reserve more space
381    /// to avoid frequent reallocations. After calling `reserve`, capacity
382    /// will be greater than or equal to `self.len() + additional`. Does
383    /// nothing if capacity is already sufficient.
384    ///
385    /// # Panics
386    ///
387    /// Panics if the new capacity exceeds `Self::MAX_CAPACITY` bytes.
388    ///
389    /// # Examples
390    /// ```
391    /// # use rkyv::util::AlignedVec;
392    ///
393    /// let mut vec = AlignedVec::<16>::new();
394    /// vec.push(1);
395    /// vec.reserve(10);
396    /// assert!(vec.capacity() >= 11);
397    /// ```
398    pub fn reserve(&mut self, additional: usize) {
399        // Cannot wrap because capacity always exceeds len,
400        // but avoids having to handle potential overflow here
401        let remaining = self.cap.wrapping_sub(self.len);
402        if additional > remaining {
403            self.do_reserve(additional);
404        }
405    }
406
407    /// Extend capacity after `reserve` has found it's necessary.
408    ///
409    /// Actually performing the extension is in this separate function marked
410    /// `#[cold]` to hint to compiler that this branch is not often taken.
411    /// This keeps the path for common case where capacity is already sufficient
412    /// as fast as possible, and makes `reserve` more likely to be inlined.
413    /// This is the same trick that Rust's `Vec::reserve` uses.
414    #[cold]
415    fn do_reserve(&mut self, additional: usize) {
416        let new_cap = self
417            .len
418            .checked_add(additional)
419            .expect("cannot reserve a larger AlignedVec");
420        unsafe { self.grow_capacity_to(new_cap) };
421    }
422
423    /// Grows total capacity of vector to `new_cap` or more.
424    ///
425    /// Capacity after this call will be `new_cap` rounded up to next power of
426    /// 2, unless that would exceed maximum capacity, in which case capacity
427    /// is capped at the maximum.
428    ///
429    /// This is same growth strategy used by `reserve`, `push` and
430    /// `extend_from_slice`.
431    ///
432    /// Usually the safe methods `reserve` or `reserve_exact` are a better
433    /// choice. This method only exists as a micro-optimization for very
434    /// performance-sensitive code where where the calculation of capacity
435    /// required has already been performed, and you want to avoid doing it
436    /// again.
437    ///
438    /// Maximum capacity is `isize::MAX + 1 - Self::ALIGNMENT` bytes.
439    ///
440    /// # Panics
441    ///
442    /// Panics if `new_cap` exceeds `Self::MAX_CAPACITY` bytes.
443    ///
444    /// # Safety
445    ///
446    /// - `new_cap` must be greater than current
447    ///   [`capacity()`](AlignedVec::capacity)
448    ///
449    /// # Examples
450    /// ```
451    /// # use rkyv::util::AlignedVec;
452    ///
453    /// let mut vec = AlignedVec::<16>::new();
454    /// vec.push(1);
455    /// unsafe { vec.grow_capacity_to(50) };
456    /// assert_eq!(vec.len(), 1);
457    /// assert_eq!(vec.capacity(), 64);
458    /// ```
459    pub unsafe fn grow_capacity_to(&mut self, new_cap: usize) {
460        debug_assert!(new_cap > self.cap);
461
462        let new_cap = if new_cap > (isize::MAX as usize + 1) >> 1 {
463            // Rounding up to next power of 2 would result in `isize::MAX + 1`
464            // or higher, which exceeds max capacity. So cap at max
465            // instead.
466            assert!(
467                new_cap <= Self::MAX_CAPACITY,
468                "cannot reserve a larger AlignedVec"
469            );
470            Self::MAX_CAPACITY
471        } else {
472            // Cannot overflow due to check above
473            new_cap.next_power_of_two()
474        };
475        // SAFETY: We just checked that `new_cap` is greater than or equal to
476        // `len` and less than or equal to `MAX_CAPACITY`.
477        unsafe {
478            self.change_capacity(new_cap);
479        }
480    }
481
482    /// Resizes the Vec in-place so that len is equal to new_len.
483    ///
484    /// If new_len is greater than len, the Vec is extended by the difference,
485    /// with each additional slot filled with value. If new_len is less than
486    /// len, the Vec is simply truncated.
487    ///
488    /// # Panics
489    ///
490    /// Panics if the new length exceeds `Self::MAX_CAPACITY` bytes.
491    ///
492    /// # Examples
493    /// ```
494    /// # use rkyv::util::AlignedVec;
495    ///
496    /// let mut vec = AlignedVec::<16>::new();
497    /// vec.push(3);
498    /// vec.resize(3, 2);
499    /// assert_eq!(vec.as_slice(), &[3, 2, 2]);
500    ///
501    /// let mut vec = AlignedVec::<16>::new();
502    /// vec.extend_from_slice(&[1, 2, 3, 4]);
503    /// vec.resize(2, 0);
504    /// assert_eq!(vec.as_slice(), &[1, 2]);
505    /// ```
506    pub fn resize(&mut self, new_len: usize, value: u8) {
507        if new_len > self.len {
508            let additional = new_len - self.len;
509            self.reserve(additional);
510            unsafe {
511                core::ptr::write_bytes(
512                    self.ptr.as_ptr().add(self.len),
513                    value,
514                    additional,
515                );
516            }
517        }
518        unsafe {
519            self.set_len(new_len);
520        }
521    }
522
523    /// Returns `true` if the vector contains no elements.
524    ///
525    /// # Examples
526    /// ```
527    /// # use rkyv::util::AlignedVec;
528    ///
529    /// let mut v = Vec::new();
530    /// assert!(v.is_empty());
531    ///
532    /// v.push(1);
533    /// assert!(!v.is_empty());
534    /// ```
535    pub fn is_empty(&self) -> bool {
536        self.len == 0
537    }
538
539    /// Returns the number of elements in the vector, also referred to as its
540    /// 'length'.
541    ///
542    /// # Examples
543    /// ```
544    /// # use rkyv::util::AlignedVec;
545    ///
546    /// let mut a = AlignedVec::<16>::new();
547    /// a.extend_from_slice(&[1, 2, 3]);
548    /// assert_eq!(a.len(), 3);
549    /// ```
550    pub fn len(&self) -> usize {
551        self.len
552    }
553
554    /// Copies and appends all bytes in a slice to the `AlignedVec`.
555    ///
556    /// The elements of the slice are appended in-order.
557    ///
558    /// # Examples
559    /// ```
560    /// # use rkyv::util::AlignedVec;
561    ///
562    /// let mut vec = AlignedVec::<16>::new();
563    /// vec.push(1);
564    /// vec.extend_from_slice(&[2, 3, 4]);
565    /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
566    /// ```
567    pub fn extend_from_slice(&mut self, other: &[u8]) {
568        self.reserve(other.len());
569        unsafe {
570            core::ptr::copy_nonoverlapping(
571                other.as_ptr(),
572                self.as_mut_ptr().add(self.len()),
573                other.len(),
574            );
575        }
576        self.len += other.len();
577    }
578
579    /// Removes the last element from a vector and returns it, or `None` if it
580    /// is empty.
581    ///
582    /// # Examples
583    /// ```
584    /// # use rkyv::util::AlignedVec;
585    ///
586    /// let mut vec = AlignedVec::<16>::new();
587    /// vec.extend_from_slice(&[1, 2, 3]);
588    /// assert_eq!(vec.pop(), Some(3));
589    /// assert_eq!(vec.as_slice(), &[1, 2]);
590    /// ```
591    pub fn pop(&mut self) -> Option<u8> {
592        if self.len == 0 {
593            None
594        } else {
595            let result = self[self.len - 1];
596            self.len -= 1;
597            Some(result)
598        }
599    }
600
601    /// Appends an element to the back of a collection.
602    ///
603    /// # Panics
604    ///
605    /// Panics if the new capacity exceeds `Self::MAX_CAPACITY` bytes.
606    ///
607    /// # Examples
608    /// ```
609    /// # use rkyv::util::AlignedVec;
610    ///
611    /// let mut vec = AlignedVec::<16>::new();
612    /// vec.extend_from_slice(&[1, 2]);
613    /// vec.push(3);
614    /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
615    /// ```
616    pub fn push(&mut self, value: u8) {
617        if self.len == self.cap {
618            self.reserve_for_push();
619        }
620
621        unsafe {
622            self.as_mut_ptr().add(self.len).write(value);
623            self.len += 1;
624        }
625    }
626
627    /// Extend capacity by at least 1 byte after `push` has found it's
628    /// necessary.
629    ///
630    /// Actually performing the extension is in this separate function marked
631    /// `#[cold]` to hint to compiler that this branch is not often taken.
632    /// This keeps the path for common case where capacity is already sufficient
633    /// as fast as possible, and makes `push` more likely to be inlined.
634    /// This is the same trick that Rust's `Vec::push` uses.
635    #[cold]
636    fn reserve_for_push(&mut self) {
637        // `len` is always less than `isize::MAX`, so no possibility of overflow
638        // here
639        let new_cap = self.len + 1;
640        unsafe { self.grow_capacity_to(new_cap) };
641    }
642
643    /// Reserves the minimum capacity for exactly `additional` more elements to
644    /// be inserted in the given `AlignedVec`. After calling
645    /// `reserve_exact`, capacity will be greater than or equal
646    /// to `self.len() + additional`. Does nothing if the capacity is already
647    /// sufficient.
648    ///
649    /// Note that the allocator may give the collection more space than it
650    /// requests. Therefore, capacity can not be relied upon to be precisely
651    /// minimal. Prefer reserve if future insertions are expected.
652    ///
653    /// # Panics
654    ///
655    /// Panics if the new capacity exceeds `Self::MAX_CAPACITY`.
656    ///
657    /// # Examples
658    /// ```
659    /// # use rkyv::util::AlignedVec;
660    ///
661    /// let mut vec = AlignedVec::<16>::new();
662    /// vec.push(1);
663    /// vec.reserve_exact(10);
664    /// assert!(vec.capacity() >= 11);
665    /// ```
666    pub fn reserve_exact(&mut self, additional: usize) {
667        // This function does not use the hot/cold paths trick that `reserve`
668        // and `push` do, on assumption that user probably knows this will
669        // require an increase in capacity. Otherwise, they'd likely use
670        // `reserve`.
671        let new_cap = self
672            .len
673            .checked_add(additional)
674            .expect("cannot reserve a larger AlignedVec");
675        if new_cap > self.cap {
676            assert!(
677                new_cap <= Self::MAX_CAPACITY,
678                "cannot reserve a larger AlignedVec"
679            );
680            unsafe { self.change_capacity(new_cap) };
681        }
682    }
683
684    /// Forces the length of the vector to `new_len`.
685    ///
686    /// This is a low-level operation that maintains none of the normal
687    /// invariants of the type.
688    ///
689    /// # Safety
690    ///
691    /// - `new_len` must be less than or equal to
692    ///   [`capacity()`](AlignedVec::capacity)
693    /// - The elements at `old_len..new_len` must be initialized
694    ///
695    /// # Examples
696    /// ```
697    /// # use rkyv::util::AlignedVec;
698    /// let mut vec = AlignedVec::<16>::with_capacity(3);
699    /// vec.extend_from_slice(&[1, 2, 3]);
700    ///
701    /// // SAFETY:
702    /// // 1. `old_len..0` is empty to no elements need to be initialized.
703    /// // 2. `0 <= capacity` always holds whatever capacity is.
704    /// unsafe {
705    ///     vec.set_len(0);
706    /// }
707    /// ```
708    pub unsafe fn set_len(&mut self, new_len: usize) {
709        debug_assert!(new_len <= self.capacity());
710
711        self.len = new_len;
712    }
713
714    /// Converts the vector into `Box<[u8]>`. The returned slice is 1-aligned.
715    ///
716    /// This method reallocates and copies the underlying bytes. Any excess
717    /// capacity is dropped.
718    ///
719    /// # Examples
720    /// ```
721    /// # use rkyv::util::AlignedVec;
722    /// let mut v = AlignedVec::<16>::new();
723    /// v.extend_from_slice(&[1, 2, 3]);
724    ///
725    /// let slice = v.into_boxed_slice();
726    /// ```
727    ///
728    /// Any excess capacity is removed:
729    ///
730    /// ```
731    /// # use rkyv::util::AlignedVec;
732    /// let mut vec = AlignedVec::<16>::with_capacity(10);
733    /// vec.extend_from_slice(&[1, 2, 3]);
734    ///
735    /// assert_eq!(vec.capacity(), 10);
736    /// let slice = vec.into_boxed_slice();
737    /// assert_eq!(slice.len(), 3);
738    /// ```
739    pub fn into_boxed_slice(self) -> Box<[u8]> {
740        self.into_vec().into_boxed_slice()
741    }
742
743    /// Converts the vector into `Vec<u8>`.
744    ///
745    /// This method reallocates and copies the underlying bytes. Any excess
746    /// capacity is dropped.
747    ///
748    /// # Examples
749    /// ```
750    /// # use rkyv::util::AlignedVec;
751    /// let mut v = AlignedVec::<16>::new();
752    /// v.extend_from_slice(&[1, 2, 3]);
753    ///
754    /// let vec = v.into_vec();
755    /// assert_eq!(vec.len(), 3);
756    /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
757    /// ```
758    pub fn into_vec(self) -> Vec<u8> {
759        Vec::from(self.as_ref())
760    }
761
762    /// Decompose an [`AlignedVec`] into its raw components: `(NonNull pointer,
763    /// length, capacity)`.
764    ///
765    /// The returned parts can be used to re-assemble the [`AlignedVec`] using
766    /// the [`from_parts`](AlignedVec::from_parts) function.
767    ///
768    /// After calling this function, the caller is responsible for the memory
769    /// previously managed by the [`AlignedVec`]. The only way to do this is
770    /// to convert the [`NonNull`] pointer, the length and the capacity back
771    /// into an [`AlignedVec`] using the [`from_parts`](AlignedVec::from_parts)
772    /// function, allowing the destructor to perform the cleanup.
773    ///
774    /// # Example
775    ///
776    /// ```
777    /// use rkyv::util::AlignedVec;
778    ///
779    /// let mut v: AlignedVec<16> = AlignedVec::new();
780    /// for i in 1..=5 {
781    ///     v.push(i);
782    /// }
783    ///
784    /// let (ptr, len, cap) = v.into_parts();
785    ///
786    /// let rebuilt: AlignedVec<16> =
787    ///     unsafe { AlignedVec::from_parts(ptr, len, cap) };
788    /// assert_eq!(rebuilt.as_slice(), &[1, 2, 3, 4, 5]);
789    /// ```
790    #[must_use = "losing the pointer will leak memory"]
791    pub fn into_parts(self) -> (NonNull<u8>, usize, usize) {
792        let this = ManuallyDrop::new(self);
793        (this.ptr, this.len, this.cap)
794    }
795
796    /// Create an [`AlignedVec`] directly from a [`NonNull`] pointer, a length
797    /// and a capacity.
798    ///
799    /// # Safety
800    ///
801    /// This is method is only safe to use with the parts returned from calling
802    /// [`into_parts`](AlignedVec::into_parts). The ownership of `ptr` is
803    /// transferred to the [`AlignedVec`], which may then de- or reallocate
804    /// the pointer or change the contents of the memory pointed to by the
805    /// pointer at will. Ensure that nothing else uses the pointer after
806    /// calling this function.
807    ///
808    /// # Example
809    ///
810    /// ```
811    /// use rkyv::util::AlignedVec;
812    ///
813    /// let mut v: AlignedVec<16> = AlignedVec::new();
814    /// for i in 1..=5 {
815    ///     v.push(i);
816    /// }
817    ///
818    /// let (ptr, len, cap) = v.into_parts();
819    ///
820    /// let rebuilt: AlignedVec<16> =
821    ///     unsafe { AlignedVec::from_parts(ptr, len, cap) };
822    /// assert_eq!(rebuilt.as_slice(), &[1, 2, 3, 4, 5]);
823    /// ```
824    pub unsafe fn from_parts(ptr: NonNull<u8>, len: usize, cap: usize) -> Self {
825        Self { ptr, len, cap }
826    }
827}
828
829#[cfg(feature = "std")]
830const _: () = {
831    use std::io;
832
833    impl<const A: usize> AlignedVec<A> {
834        /// Reads all bytes until EOF from `r` and appends them to this
835        /// `AlignedVec`.
836        ///
837        /// If successful, this function will return the total number of bytes
838        /// read.
839        ///
840        /// # Examples
841        /// ```
842        /// # use rkyv::util::AlignedVec;
843        ///
844        /// let source = (0..4096).map(|x| (x % 256) as u8).collect::<Vec<_>>();
845        /// let mut bytes = AlignedVec::<16>::new();
846        /// bytes.extend_from_reader(&mut source.as_slice()).unwrap();
847        ///
848        /// assert_eq!(bytes.len(), 4096);
849        /// assert_eq!(bytes[0], 0);
850        /// assert_eq!(bytes[100], 100);
851        /// assert_eq!(bytes[2945], 129);
852        /// ```
853        pub fn extend_from_reader<R: io::Read + ?Sized>(
854            &mut self,
855            r: &mut R,
856        ) -> io::Result<usize> {
857            let start_len = self.len();
858            let start_cap = self.capacity();
859
860            // Extra initialized bytes from previous loop iteration.
861            let mut initialized = 0;
862            loop {
863                if self.len() == self.capacity() {
864                    // No available capacity, reserve some space.
865                    self.reserve(32);
866                }
867
868                let read_buf_start = unsafe { self.as_mut_ptr().add(self.len) };
869                let read_buf_len = self.capacity() - self.len();
870
871                // Initialize the uninitialized portion of the available space.
872                unsafe {
873                    // The first `initialized` bytes don't need to be zeroed.
874                    // This leaves us `read_buf_len - initialized` bytes to zero
875                    // starting at `initialized`.
876                    core::ptr::write_bytes(
877                        read_buf_start.add(initialized),
878                        0,
879                        read_buf_len - initialized,
880                    );
881                }
882
883                // The entire read buffer is now initialized, so we can create a
884                // mutable slice of it.
885                let read_buf = unsafe {
886                    core::slice::from_raw_parts_mut(
887                        read_buf_start,
888                        read_buf_len,
889                    )
890                };
891
892                match r.read(read_buf) {
893                    Ok(read) => {
894                        // We filled `read` additional bytes.
895                        unsafe {
896                            self.set_len(self.len() + read);
897                        }
898                        initialized = read_buf_len - read;
899
900                        if read == 0 {
901                            return Ok(self.len() - start_len);
902                        }
903                    }
904                    Err(e) if e.kind() == io::ErrorKind::Interrupted => {
905                        continue
906                    }
907                    Err(e) => return Err(e),
908                }
909
910                if self.len() == self.capacity() && self.capacity() == start_cap
911                {
912                    // The buffer might be an exact fit. Let's read into a probe
913                    // buffer and see if it returns `Ok(0)`.
914                    // If so, we've avoided an unnecessary
915                    // doubling of the capacity. But if not, append the
916                    // probe buffer to the primary buffer and let its capacity
917                    // grow.
918                    let mut probe = [0u8; 32];
919
920                    loop {
921                        match r.read(&mut probe) {
922                            Ok(0) => return Ok(self.len() - start_len),
923                            Ok(n) => {
924                                self.extend_from_slice(&probe[..n]);
925                                break;
926                            }
927                            Err(ref e)
928                                if e.kind() == io::ErrorKind::Interrupted =>
929                            {
930                                continue
931                            }
932                            Err(e) => return Err(e),
933                        }
934                    }
935                }
936            }
937        }
938    }
939
940    impl<const A: usize> io::Write for AlignedVec<A> {
941        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
942            self.extend_from_slice(buf);
943            Ok(buf.len())
944        }
945
946        fn write_vectored(
947            &mut self,
948            bufs: &[io::IoSlice<'_>],
949        ) -> io::Result<usize> {
950            let len = bufs.iter().map(|b| b.len()).sum();
951            self.reserve(len);
952            for buf in bufs {
953                self.extend_from_slice(buf);
954            }
955            Ok(len)
956        }
957
958        fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
959            self.extend_from_slice(buf);
960            Ok(())
961        }
962
963        fn flush(&mut self) -> io::Result<()> {
964            Ok(())
965        }
966    }
967};
968
969impl<const A: usize> From<AlignedVec<A>> for Vec<u8> {
970    fn from(aligned: AlignedVec<A>) -> Self {
971        aligned.to_vec()
972    }
973}
974
975impl<const A: usize> AsMut<[u8]> for AlignedVec<A> {
976    fn as_mut(&mut self) -> &mut [u8] {
977        self.as_mut_slice()
978    }
979}
980
981impl<const A: usize> AsRef<[u8]> for AlignedVec<A> {
982    fn as_ref(&self) -> &[u8] {
983        self.as_slice()
984    }
985}
986
987impl<const A: usize> Borrow<[u8]> for AlignedVec<A> {
988    fn borrow(&self) -> &[u8] {
989        self.as_slice()
990    }
991}
992
993impl<const A: usize> BorrowMut<[u8]> for AlignedVec<A> {
994    fn borrow_mut(&mut self) -> &mut [u8] {
995        self.as_mut_slice()
996    }
997}
998
999impl<const A: usize> Clone for AlignedVec<A> {
1000    fn clone(&self) -> Self {
1001        unsafe {
1002            let mut result = Self::with_capacity(self.len);
1003            result.len = self.len;
1004            core::ptr::copy_nonoverlapping(
1005                self.as_ptr(),
1006                result.as_mut_ptr(),
1007                self.len,
1008            );
1009            result
1010        }
1011    }
1012}
1013
1014impl<const A: usize> fmt::Debug for AlignedVec<A> {
1015    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1016        self.as_slice().fmt(f)
1017    }
1018}
1019
1020impl<const A: usize> Default for AlignedVec<A> {
1021    fn default() -> Self {
1022        Self::new()
1023    }
1024}
1025
1026impl<const A: usize> Deref for AlignedVec<A> {
1027    type Target = [u8];
1028
1029    fn deref(&self) -> &Self::Target {
1030        self.as_slice()
1031    }
1032}
1033
1034impl<const A: usize> DerefMut for AlignedVec<A> {
1035    fn deref_mut(&mut self) -> &mut Self::Target {
1036        self.as_mut_slice()
1037    }
1038}
1039
1040impl<const A: usize, I: slice::SliceIndex<[u8]>> Index<I> for AlignedVec<A> {
1041    type Output = <I as slice::SliceIndex<[u8]>>::Output;
1042
1043    fn index(&self, index: I) -> &Self::Output {
1044        &self.as_slice()[index]
1045    }
1046}
1047
1048impl<const A: usize, I: slice::SliceIndex<[u8]>> IndexMut<I> for AlignedVec<A> {
1049    fn index_mut(&mut self, index: I) -> &mut Self::Output {
1050        &mut self.as_mut_slice()[index]
1051    }
1052}
1053
1054// SAFETY: AlignedVec is safe to send to another thread
1055unsafe impl<const A: usize> Send for AlignedVec<A> {}
1056
1057// SAFETY: AlignedVec is safe to share between threads
1058unsafe impl<const A: usize> Sync for AlignedVec<A> {}
1059
1060impl<const A: usize> Unpin for AlignedVec<A> {}
1061
1062impl<const A: usize> ArchiveWith<AlignedVec<A>> for AsVec {
1063    type Archived = ArchivedVec<u8>;
1064    type Resolver = VecResolver;
1065
1066    fn resolve_with(
1067        field: &AlignedVec<A>,
1068        resolver: Self::Resolver,
1069        out: Place<Self::Archived>,
1070    ) {
1071        ArchivedVec::resolve_from_len(field.len(), resolver, out)
1072    }
1073}
1074
1075impl<S, const A: usize> SerializeWith<AlignedVec<A>, S> for AsVec
1076where
1077    S: Allocator + Fallible + Writer + ?Sized,
1078{
1079    fn serialize_with(
1080        field: &AlignedVec<A>,
1081        serializer: &mut S,
1082    ) -> Result<Self::Resolver, S::Error> {
1083        ArchivedVec::serialize_from_slice(field.as_slice(), serializer)
1084    }
1085}
1086
1087impl<D, const A: usize> DeserializeWith<ArchivedVec<u8>, AlignedVec<A>, D>
1088    for AsVec
1089where
1090    D: Fallible + ?Sized,
1091{
1092    fn deserialize_with(
1093        field: &ArchivedVec<u8>,
1094        _: &mut D,
1095    ) -> Result<AlignedVec<A>, D::Error> {
1096        let mut result = AlignedVec::with_capacity(field.len());
1097        result.extend_from_slice(field.as_slice());
1098        Ok(result)
1099    }
1100}