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 {}