vpp_plugin/vppinfra/vec.rs
1//! Dynamically resizable arrays
2//!
3//! This module provides abstractions around VPP's vector type, which is a
4//! dynamically resizable array similar to Rust's `Vec<T>`.
5//!
6//! # Memory layout
7//!
8//! ```text
9//! +-------------------+----------------+----------------+----------------+
10//! | vec_header_t hdr | T elem[0] | T elem[1] | T elem[2] | ...
11//! +-------------------+----------------+----------------+----------------+
12//! ^
13//! +---------------- User pointer
14//! ```
15//! # Relationship between `Vec<T>` and `VecRef<T>`
16//!
17//! The `Vec<T>` type is an owning vector type that manages the memory
18//! allocation and deallocation for the vector. It provides methods for
19//! modifying the vector, such as `push`, `pop`, and `insert_mut`.
20//! The `VecRef<T>` type is a non-owning reference type that provides
21//! read-only access to the elements of the vector. It is used when
22//! you want to pass around a reference to a vector without taking ownership of it.
23//!
24//! Note that there may be some times when you don't own the vector, but you need
25//! to perform operations which may resize it, such as to push an element. Be careful about
26//! updating the original pointer because if the vector is resized the pointer may change and
27//! the original pointer may no longer be valid. In these cases, you can temporarily take
28//! ownership of the vector by doing:
29//!
30//! ```rust
31//! use vpp_plugin::vppinfra::vec::Vec;
32//! # use vpp_plugin::vec;
33//!
34//! # vpp_plugin::vppinfra::clib_mem_init();
35//! # let mut ptr = vec![1, 2, 3].into_raw();
36//! let mut v = unsafe { Vec::from_raw(ptr) };
37//! v.push(1);
38//! ptr = v.into_raw();
39//! # unsafe { Vec::from_raw(ptr); } // prevent leak
40//! ```
41
42use std::{
43 borrow::{Borrow, BorrowMut},
44 cmp::Ordering,
45 fmt,
46 mem::{ManuallyDrop, MaybeUninit},
47 ops::{Deref, DerefMut},
48 ptr, slice,
49};
50
51use crate::bindings::{
52 _vec_alloc_internal, _vec_resize_internal, vec_attr_t, vec_free_not_inline, vec_header_t,
53 VEC_MIN_ALIGN,
54};
55
56/// Reference to a dynamically resizable array
57///
58/// A `&VecRef<T>` is equivalent to a `T *` pointer in VPP (`*mut T` in Rust parlance).
59///
60/// Due to the memory layout of VPP vectors, this type provides methods to access the vector and
61/// modify it as long as it never needs resizing. If resizing is needed, you must use the
62/// [`Vec<T>`] type.
63pub struct VecRef<T>(foreign_types::Opaque, std::marker::PhantomData<T>);
64
65impl<T> VecRef<T> {
66 /// Creates a `&VecRef<T>` directly from a pointer
67 ///
68 /// # Safety
69 /// - The pointer must be valid and point to a VPP vector of type `T`.
70 /// - `T` needs to have the alignment that is less than or equal to the alignment of elements
71 /// used when allocating the vector.
72 /// - The pointer must stay valid and the contents must not be mutated for the duration of the
73 /// lifetime of the returned reference.
74 ///
75 /// See also [`Self::from_raw_mut`].
76 #[inline(always)]
77 pub unsafe fn from_raw<'a>(ptr: *const T) -> &'a Self {
78 &*(ptr as *mut _)
79 }
80
81 /// Creates a `&mut VecRef<T>` directly from a pointer
82 ///
83 /// # Safety
84 /// - The pointer must be valid and point to a VPP vector of type `T`.
85 /// - `T` needs to have the alignment that is less than or equal to the alignment of elements
86 /// used when allocating the vector.
87 /// - The pointer must stay valid and the contents must not be mutated for the duration of the
88 /// lifetime of the returned reference.
89 ///
90 /// See also [`Self::from_raw`].
91 #[inline(always)]
92 pub unsafe fn from_raw_mut<'a>(ptr: *mut T) -> &'a mut Self {
93 &mut *(ptr as *mut _)
94 }
95
96 /// Creates an `Option<&VecRef<T>>` directly from a pointer
97 ///
98 /// # Safety
99 ///
100 /// Either the pointer must be null or all of the following must be true:
101 /// - The pointer must be valid and point to a VPP vector of type `T`.
102 /// - `T` needs to have the alignment that is less than or equal to the alignment of elements
103 /// used when allocating the vector.
104 /// - The pointer must stay valid and the contents must not be mutated for the duration of the
105 /// lifetime of the returned reference.
106 ///
107 /// See also [`Self::from_raw_mut`].
108 #[inline(always)]
109 pub unsafe fn from_raw_opt<'a>(ptr: *const T) -> Option<&'a Self> {
110 if ptr.is_null() {
111 None
112 } else {
113 Some(&*(ptr as *mut _))
114 }
115 }
116
117 /// Creates an `Option<&mut VecRef<T>>` directly from a pointer
118 ///
119 /// # Safety
120 ///
121 /// Either the pointer must be null or all of the following must be true:
122 /// - The pointer must be valid and point to a VPP vector of type `T`.
123 /// - `T` needs to have the alignment that is less than or equal to the alignment of elements
124 /// used when allocating the vector.
125 /// - The pointer must stay valid and the contents must not be mutated for the duration of the
126 /// lifetime of the returned reference.
127 ///
128 /// See also [`Self::from_raw_mut`].
129 #[inline(always)]
130 pub unsafe fn from_raw_mut_opt<'a>(ptr: *mut T) -> Option<&'a mut Self> {
131 if ptr.is_null() {
132 None
133 } else {
134 Some(&mut *(ptr as *mut _))
135 }
136 }
137
138 /// Returns a raw pointer to the first element of the vector
139 ///
140 /// The caller must ensure that the vector outlives the returned pointer. Modifying the vector
141 /// may invalidate the pointer.
142 ///
143 /// The caller must ensure that the pointer is not used to mutate the vector (except inside an
144 /// `UnsafeCell`).
145 ///
146 /// If you need a mutable pointer, use [`Self::as_mut_ptr`] instead.
147 #[inline(always)]
148 pub const fn as_ptr(&self) -> *const T {
149 self as *const _ as *const _
150 }
151
152 /// Returns a raw pointer to the first element of the vector
153 ///
154 /// The caller must ensure that the vector outlives the returned pointer. Modifying the vector
155 /// may invalidate the pointer.
156 ///
157 /// The caller must ensure that the pointer is not used to mutate the vector (except inside an
158 /// `UnsafeCell`).
159 ///
160 /// If you need a mutable pointer, use [`Self::as_mut_ptr`] instead.
161 #[inline(always)]
162 pub const fn as_mut_ptr(&self) -> *mut T {
163 self as *const _ as *mut _
164 }
165
166 fn as_vec_header_ptr(&self) -> *mut vec_header_t {
167 // SAFETY: creation preconditions mean this is a valid object and so the vec_header_t is
168 // located just before the user pointer
169 unsafe {
170 let ptr: *mut vec_header_t = self.as_mut_ptr().cast();
171 ptr.sub(1)
172 }
173 }
174
175 /// Returns the length of the vector
176 #[inline]
177 pub fn len(&self) -> usize {
178 // SAFETY: creation preconditions mean this is a valid object and it's safe to read the
179 // len field
180 unsafe { (*self.as_vec_header_ptr()).len as usize }
181 }
182
183 /// Returns true if the vector is empty
184 #[inline]
185 pub fn is_empty(&self) -> bool {
186 self.len() == 0
187 }
188
189 /// Returns the capacity of the vector
190 ///
191 /// This is the total number of elements that can be stored in the vector without resizing.
192 pub fn capacity(&self) -> usize {
193 // SAFETY: creation preconditions mean this is a valid object and it's safe to access the
194 // header
195 unsafe {
196 let hdr = self.as_vec_header_ptr();
197 ((*hdr).len + (*hdr).grow_elts as u32) as usize
198 }
199 }
200
201 /// Removes and returns the element at the specified index
202 ///
203 /// # Panics
204 ///
205 /// Panics if `index` is out of bounds.
206 pub fn remove(&mut self, index: usize) -> T {
207 let hdr = self.as_vec_header_ptr();
208 // SAFETY: creation preconditions mean this is a valid object, we ensure index is in
209 // bounds and on exit the length is decremented so the dropped element cannot be accessed
210 // again
211 unsafe {
212 let len = (*hdr).len as usize;
213
214 assert!(
215 index < len,
216 "removal index (is {index}) should be < len (is {len})"
217 );
218
219 // the place we are taking from.
220 let ptr = self.as_mut_ptr().add(index);
221 // copy it out, unsafely having a copy of the value on
222 // the stack and in the vector at the same time.
223 let ret = ptr::read(ptr);
224
225 // Shift everything down to fill in that spot.
226 ptr::copy(ptr.add(1), ptr, len - index - 1);
227
228 (*hdr).len = len as u32 - 1;
229 (*hdr).grow_elts += 1;
230 ret
231 }
232 }
233
234 /// Removes and returns the last element of the vector, if any
235 pub fn pop(&mut self) -> Option<T> {
236 let hdr = self.as_vec_header_ptr();
237 // SAFETY: creation preconditions mean this is a valid object, and on exit the length is
238 // decremented so the dropped element cannot be accessed again
239 unsafe {
240 let len = (*hdr).len as usize;
241 if len == 0 {
242 None
243 } else {
244 (*hdr).len = len as u32 - 1;
245 (*hdr).grow_elts += 1;
246 Some(ptr::read(self.as_ptr().add(len - 1)))
247 }
248 }
249 }
250
251 /// Clears the vector, removing all elements
252 ///
253 /// Note this has no effect on the capacity of the vector.
254 pub fn clear(&mut self) {
255 let elems: *mut [T] = self.as_mut_slice();
256 // SAFETY: creation preconditions mean this is a valid object, and on exit the length is
257 // set to zero so the dropped elements cannot be accessed again
258 unsafe {
259 let hdr = self.as_vec_header_ptr();
260 // Preserve total capacity (len + grow_elts) when clearing. Save
261 // the old capacity and set grow_elts to that value so capacity
262 // does not shrink.
263 let len = (*hdr).len;
264 let old_grow = (*hdr).grow_elts as u32;
265 let cap = len.saturating_add(old_grow);
266 (*hdr).len = 0;
267 (*hdr).grow_elts = cap.try_into().unwrap_or(u8::MAX);
268 ptr::drop_in_place(elems);
269 }
270 }
271
272 /// Returns the contents of the vector as a slice
273 ///
274 /// Equivalent to `&vec[..]`.
275 ///
276 /// See also [`Self::as_mut_slice`].
277 pub fn as_slice(&self) -> &[T] {
278 // SAFETY: creation preconditions mean this is a valid object and contiguous and
279 // initialised up to len
280 unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
281 }
282
283 /// Returns the contents of the vector as a mutable slice
284 ///
285 /// Equivalent to `&mut vec[..]`.
286 ///
287 /// See also [`Self::as_slice`].
288 pub fn as_mut_slice(&mut self) -> &mut [T] {
289 // SAFETY: creation preconditions mean this is a valid object and contiguous and
290 // initialised up to len
291 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
292 }
293
294 /// Returns the allocated spare capacity of the vector as a slice of `MaybeUninit<T>`
295 ///
296 /// This can be used to initialize multiple elements at once before updating the length
297 /// using [`Self::set_len`].
298 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
299 // SAFETY: creation preconditions mean this is a valid object and contiguous and
300 // memory is allocated up to capacity, and the use of MaybeUninit<T> ensures that the
301 // uninitialised elements cannot be read by safe code.
302 unsafe {
303 slice::from_raw_parts_mut(
304 self.as_ptr().add(self.len()) as *mut MaybeUninit<T>,
305 self.capacity() - self.len(),
306 )
307 }
308 }
309
310 /// Sets the length of the vector
311 ///
312 /// # Safety
313 /// - `new_len` must be less than or equal to the capacity of the vector.
314 /// - The elements up to `new_len` must be initialized.
315 pub unsafe fn set_len(&mut self, new_len: usize) {
316 debug_assert!(new_len <= self.capacity());
317 let hdr = self.as_vec_header_ptr();
318 let new_grow_elts = self.capacity() - new_len;
319 (*hdr).len = new_len as u32;
320 (*hdr).grow_elts = new_grow_elts.try_into().unwrap_or(u8::MAX);
321 }
322}
323
324impl<T> Deref for VecRef<T> {
325 type Target = [T];
326
327 fn deref(&self) -> &[T] {
328 self.as_slice()
329 }
330}
331
332impl<T> DerefMut for VecRef<T> {
333 fn deref_mut(&mut self) -> &mut [T] {
334 self.as_mut_slice()
335 }
336}
337
338impl<T: fmt::Debug> fmt::Debug for VecRef<T> {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 fmt::Debug::fmt(self.as_slice(), f)
341 }
342}
343
344impl<T> AsRef<VecRef<T>> for VecRef<T> {
345 fn as_ref(&self) -> &VecRef<T> {
346 self
347 }
348}
349
350impl<T> AsMut<VecRef<T>> for VecRef<T> {
351 fn as_mut(&mut self) -> &mut VecRef<T> {
352 self
353 }
354}
355
356impl<T> AsRef<[T]> for VecRef<T> {
357 fn as_ref(&self) -> &[T] {
358 self
359 }
360}
361
362impl<T> AsMut<[T]> for VecRef<T> {
363 fn as_mut(&mut self) -> &mut [T] {
364 self
365 }
366}
367
368impl<T> PartialOrd<VecRef<T>> for VecRef<T>
369where
370 T: PartialOrd,
371{
372 #[inline]
373 fn partial_cmp(&self, other: &VecRef<T>) -> Option<Ordering> {
374 PartialOrd::partial_cmp(&**self, &**other)
375 }
376}
377
378impl<T: Eq> Eq for VecRef<T> {}
379
380impl<T: Ord> Ord for VecRef<T> {
381 #[inline]
382 fn cmp(&self, other: &Self) -> Ordering {
383 Ord::cmp(&**self, &**other)
384 }
385}
386
387// SAFETY: it's fine to deallocate the memory from another thread, and fine to access Vec<T> from
388// another thread as long as T is Send
389unsafe impl<T> Send for VecRef<T> where T: Send {}
390
391/// Owned dynamically resizable array
392///
393/// A `Vec<T>` is equivalent to a `T *` pointer in VPP (`*mut T` in Rust parlance).
394pub struct Vec<T>(*mut T);
395
396impl<T> Vec<T> {
397 /// Return the length of the vector (0 for null/empty vectors)
398 pub fn len(&self) -> usize {
399 if self.as_ptr().is_null() {
400 0
401 } else {
402 // SAFETY: pointer is non-null and points to a VPP vector
403 unsafe { VecRef::from_raw(self.as_ptr()).len() }
404 }
405 }
406
407 /// Returns true if the vector is empty
408 pub fn is_empty(&self) -> bool {
409 self.len() == 0
410 }
411
412 /// Return the capacity for this vector (0 for null/empty vectors)
413 pub fn capacity(&self) -> usize {
414 if self.as_ptr().is_null() {
415 0
416 } else {
417 // SAFETY: pointer is non-null and points to a VPP vector
418 unsafe { VecRef::from_raw(self.as_ptr()).capacity() }
419 }
420 }
421
422 unsafe fn as_vec_header_ptr(&self) -> *mut vec_header_t {
423 // SAFETY: caller ensures pointer is non-null, and this is a valid vector and so has a
424 // vector header immediately before it
425 unsafe { (self.as_mut_ptr() as *mut vec_header_t).sub(1) }
426 }
427
428 /// Returns the contents of the vector as a slice (safe for empty vectors)
429 pub fn as_slice(&self) -> &[T] {
430 let len = self.len();
431 if len == 0 {
432 &[]
433 } else {
434 // SAFETY: non-null pointer and len elements are initialized
435 unsafe { slice::from_raw_parts(self.as_ptr(), len) }
436 }
437 }
438
439 /// Returns the contents of the vector as a mutable slice (safe for empty vectors)
440 pub fn as_mut_slice(&mut self) -> &mut [T] {
441 let len = self.len();
442 if len == 0 {
443 &mut []
444 } else {
445 // SAFETY: non-null pointer and len elements are initialized
446 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), len) }
447 }
448 }
449
450 /// Returns the allocated spare capacity as MaybeUninit slice (0-length for empty vectors)
451 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
452 let len = self.len();
453 let cap = self.capacity();
454 if cap == len {
455 &mut []
456 } else {
457 // SAFETY: memory for capacity elements is allocated
458 unsafe {
459 slice::from_raw_parts_mut(
460 self.as_mut_ptr().add(len) as *mut MaybeUninit<T>,
461 cap - len,
462 )
463 }
464 }
465 }
466
467 /// Sets the length of the vector
468 ///
469 /// # Safety
470 ///
471 /// Caller must ensure new_len <= capacity and elements 0..new_len are initialized.
472 pub unsafe fn set_len(&mut self, new_len: usize) {
473 if self.as_ptr().is_null() {
474 debug_assert_eq!(new_len, 0);
475 return;
476 }
477 debug_assert!(new_len <= self.capacity());
478 let hdr = self.as_vec_header_ptr();
479 let new_grow_elts = self.capacity() - new_len;
480 (*hdr).len = new_len as u32;
481 (*hdr).grow_elts = new_grow_elts.try_into().unwrap_or(u8::MAX);
482 }
483
484 /// Creates a `Vec<T>` directly from a pointer
485 ///
486 /// # Safety
487 ///
488 /// Either the pointer must be null or all of the following must be true:
489 /// - The pointer must be valid and point to a VPP vector of type `T`.
490 /// - `T` needs to have the alignment that is less than or equal to the alignment of elements
491 /// used when allocating the vector.
492 /// - The pointer must stay valid and the contents must not be mutated for the duration of the
493 /// lifetime of the returned object.
494 pub unsafe fn from_raw(ptr: *mut T) -> Vec<T> {
495 Vec(ptr)
496 }
497
498 /// Creates a new vector with the at least the specified capacity
499 ///
500 /// The created vector will have a length of 0.
501 ///
502 /// Note that the capacity of the created vector may be larger than the requested capacity.
503 pub fn with_capacity(capacity: usize) -> Self {
504 let align = std::mem::align_of::<T>() as u16;
505 let attr = vec_attr_t {
506 align: align.max(VEC_MIN_ALIGN as u16),
507 hdr_sz: 0, // TODO
508 heap: std::ptr::null_mut(),
509 elt_sz: std::mem::size_of::<T>() as u32,
510 };
511 // SAFETY: we ensure that the attributes are valid for T, and _vec_alloc_internal returns a valid
512 // pointer or aborts, and the pointer has memory laid out as we expect, i.e. the
513 // vec_header_t before it.
514 unsafe {
515 let mut v = Self(_vec_alloc_internal(capacity as u64, &attr).cast());
516 // vpp sets len to the alloc'd len, but the semantics of this method is such that len should only be those that are in use
517 v.set_len(0);
518 v
519 }
520 }
521
522 /// Creates a new, empty vector
523 pub const fn new() -> Self {
524 Self(std::ptr::null_mut())
525 }
526
527 /// Reserves capacity for at least `additional` more elements to be inserted
528 ///
529 /// # Panics
530 ///
531 /// Panics if the new capacity overflows `u32`.
532 pub fn reserve(&mut self, additional: usize) {
533 let align = std::mem::align_of::<T>() as u16;
534 let len = self.len();
535 let new_len = len.checked_add(additional).unwrap_or_else(|| {
536 panic!("Overflow on adding {additional} elements to vec of len {len}")
537 });
538 // u32 is the len field in the header, despite _vec_size_internal taking a u64
539 let new_len = u32::try_from(new_len).unwrap_or_else(|_| {
540 panic!("Overflow on adding {additional} elements to vec of len {len}")
541 });
542 let attr = vec_attr_t {
543 align: align.max(VEC_MIN_ALIGN as u16),
544 hdr_sz: 0, // TODO
545 heap: std::ptr::null_mut(),
546 elt_sz: std::mem::size_of::<T>() as u32,
547 };
548 // SAFETY: we ensure that the attributes are valid for T, pass a valid pointer (with a
549 // vec_header_t before it) to _vec_resize_internal and _vec_resize_internal returns a valid
550 // pointer or aborts, and the pointer has memory laid out as we expect, i.e. the
551 // vec_header_t before it, and we preserve len to avoid uninitialised element access.
552 unsafe {
553 // If this vector is currently empty (null pointer), ask the allocator to allocate
554 // space via _vec_alloc_internal by calling _vec_resize_internal with a null pointer.
555 let ptr = _vec_resize_internal(self.as_mut_ptr().cast(), new_len.into(), &attr);
556 self.0 = ptr.cast();
557 // Preserve len, since _vec_resize_internal adds to it, whereas it's unallocated space for us
558 self.set_len(len);
559 }
560 }
561
562 /// Pushes an element to the end of the vector
563 ///
564 /// # Panics
565 ///
566 /// Panics if the new capacity overflows `u32`.
567 pub fn push(&mut self, value: T) {
568 let len = self.len();
569 if len == self.capacity() {
570 self.reserve(1);
571 }
572 // SAFETY: creation preconditions mean this is a valid object, and we have reserved
573 // space for at least one more element and len is set correctly, with grow_elts
574 // updated so the capacity is correct.
575 unsafe {
576 let end = self.as_mut_ptr().add(len);
577 ptr::write(end, value);
578 let hdr = self.as_vec_header_ptr();
579 (*hdr).len = len as u32 + 1;
580 (*hdr).grow_elts -= 1;
581 }
582 }
583
584 /// Inserts an element at the specified index, shifting all elements after it to the right
585 ///
586 /// # Panics
587 ///
588 /// Panics if `index > len` or if the new capacity overflows `u32`.
589 pub fn insert_mut(&mut self, index: usize, element: T) -> &mut T {
590 let len = self.len();
591 let capacity = self.capacity();
592
593 assert!(
594 index <= len,
595 "insertion index (is {index}) should be <= len (is {len})"
596 );
597
598 if len == capacity {
599 self.reserve(1);
600 }
601 // SAFETY: creation preconditions mean this is a valid object, index is valid and we have
602 // reserved space for at least one more element and len is set correctly, with grow_elts
603 // updated so the capacity is correct, and the returned reference is valid until the next
604 // mutation of the vector.
605 unsafe {
606 let p = self.as_mut_ptr().add(index);
607 if index < len {
608 // Shift everything over to make space. (Duplicating the
609 // `index`th element into two consecutive places.)
610 ptr::copy(p, p.add(1), len - index);
611 }
612 ptr::write(p, element);
613 let hdr = self.as_vec_header_ptr();
614 (*hdr).len = len as u32 + 1;
615 (*hdr).grow_elts -= 1;
616 &mut *p
617 }
618 }
619
620 /// Consumes the vector, returning a raw pointer to the first element
621 ///
622 /// After calling this method, the caller is responsible for managing the memory of the
623 /// vector. In particular, the caller should call the destructor (if any) for each element
624 /// and free the memory allocated for the vector.
625 #[must_use = "losing the pointer will leak the vector"]
626 pub fn into_raw(self) -> *mut T {
627 let v = ManuallyDrop::new(self);
628 v.as_mut_ptr()
629 }
630
631 /// Returns a raw pointer to the first element of the vector
632 ///
633 /// The caller must ensure that the vector outlives the returned pointer. Modifying the vector
634 /// may invalidate the pointer.
635 ///
636 /// The caller must ensure that the pointer is not used to mutate the vector (except inside an
637 /// `UnsafeCell`).
638 ///
639 /// If you need a mutable pointer, use [`Self::as_mut_ptr`] instead.
640 #[inline(always)]
641 pub const fn as_ptr(&self) -> *const T {
642 self.0
643 }
644
645 /// Returns a raw pointer to the first element of the vector
646 ///
647 /// The caller must ensure that the vector outlives the returned pointer. Modifying the vector
648 /// may invalidate the pointer.
649 ///
650 /// The caller must ensure that the pointer is not used to mutate the vector (except inside an
651 /// `UnsafeCell`).
652 ///
653 /// If you need a mutable pointer, use [`Self::as_mut_ptr`] instead.
654 #[inline(always)]
655 pub const fn as_mut_ptr(&self) -> *mut T {
656 self.0
657 }
658}
659
660impl<T> Default for Vec<T> {
661 fn default() -> Vec<T> {
662 Vec::new()
663 }
664}
665
666impl<T: Clone> Vec<T> {
667 /// Extend the vector by `n` clones of value.
668 pub fn extend_with(&mut self, n: usize, value: T) {
669 self.reserve(n);
670 let new_len = self.len() + n;
671
672 // SAFETY: creation preconditions mean this is a valid object, we have reserved
673 // space for n more elements, the new elements are initialised by writing the value and
674 // set_len is called with the correct new length.
675 unsafe {
676 let mut ptr = self.as_mut_ptr().add(self.len());
677
678 // Write all elements except the last one
679 for _ in 1..n {
680 ptr::write(ptr, value.clone());
681 ptr = ptr.add(1);
682 }
683
684 if n > 0 {
685 // We can write the last element directly without cloning needlessly
686 ptr::write(ptr, value);
687 }
688
689 self.set_len(new_len);
690 }
691 }
692}
693
694impl<T> Extend<T> for Vec<T> {
695 #[track_caller]
696 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
697 let mut iter = iter.into_iter();
698 while let Some(element) = iter.next() {
699 let len = self.len();
700 if len == self.capacity() {
701 let (lower, _) = iter.size_hint();
702 self.reserve(lower.saturating_add(1));
703 }
704 // SAFETY: creation preconditions mean this is a valid object, and we have reserved
705 // space for at least one more element the new element is initialised by writing the
706 // value and set_len is called with the correct new length.
707 unsafe {
708 ptr::write(self.as_mut_ptr().add(len), element);
709 self.set_len(len + 1);
710 }
711 }
712 }
713}
714
715impl<'a, T: Copy + 'a> Extend<&'a T> for Vec<T> {
716 #[track_caller]
717 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
718 let mut iter = iter.into_iter();
719 while let Some(element) = iter.next() {
720 let len = self.len();
721 if len == self.capacity() {
722 let (lower, _) = iter.size_hint();
723 self.reserve(lower.saturating_add(1));
724 }
725 // SAFETY: creation preconditions mean this is a valid object, and we have reserved
726 // space for at least one more element the new element is initialised by writing the
727 // value and set_len is called with the correct new length.
728 unsafe {
729 ptr::write(self.as_mut_ptr().add(len), *element);
730 self.set_len(len + 1);
731 }
732 }
733 }
734}
735
736impl<T> Drop for Vec<T> {
737 fn drop(&mut self) {
738 // If the vector is empty it's represented as a null pointer; nothing to do.
739 if self.as_mut_ptr().is_null() {
740 return;
741 }
742
743 // SAFETY: pointer is non-null and we own the allocation
744 unsafe {
745 let elems: *mut [T] = self.as_mut_slice();
746 ptr::drop_in_place(elems);
747 vec_free_not_inline(self.as_mut_ptr().cast())
748 }
749 }
750}
751
752impl<T> Deref for Vec<T> {
753 type Target = [T];
754
755 fn deref(&self) -> &[T] {
756 self.as_slice()
757 }
758}
759
760impl<T> DerefMut for Vec<T> {
761 fn deref_mut(&mut self) -> &mut [T] {
762 self.as_mut_slice()
763 }
764}
765
766impl<T> Vec<T> {
767 /// Removes and returns the element at `index`.
768 /// For empty (null) vectors this will panic as index is out of bounds.
769 pub fn remove(&mut self, index: usize) -> T {
770 if self.as_mut_ptr().is_null() {
771 panic!("removal index (is {index}) should be <= len (is 0)");
772 }
773 // SAFETY: pointer non-null
774 unsafe { VecRef::from_raw_mut(self.as_mut_ptr()).remove(index) }
775 }
776
777 /// Pops the last element if any
778 pub fn pop(&mut self) -> Option<T> {
779 if self.as_mut_ptr().is_null() {
780 None
781 } else {
782 // SAFETY: pointer non-null
783 unsafe { VecRef::from_raw_mut(self.as_mut_ptr()).pop() }
784 }
785 }
786
787 /// Clears the vector
788 pub fn clear(&mut self) {
789 if self.as_mut_ptr().is_null() {
790 return;
791 }
792 // SAFETY: pointer non-null
793 unsafe { VecRef::from_raw_mut(self.as_mut_ptr()).clear() }
794 }
795
796 /// Returns an optional `&VecRef<T>` for this vector.
797 ///
798 /// Returns `None` when the vector is empty (null pointer), otherwise returns a
799 /// `&VecRef<T>` constructed from the internal pointer.
800 pub fn as_vec_ref(&self) -> Option<&VecRef<T>> {
801 if self.as_ptr().is_null() {
802 None
803 } else {
804 // SAFETY: pointer is non-null and points to a valid VecRef layout
805 Some(unsafe { VecRef::from_raw(self.as_ptr()) })
806 }
807 }
808
809 /// Returns an optional `&mut VecRef<T>` for this vector.
810 ///
811 /// Returns `None` when the vector is empty (null pointer), otherwise returns a
812 /// `&mut VecRef<T>` constructed from the internal pointer.
813 pub fn as_vec_ref_mut(&mut self) -> Option<&mut VecRef<T>> {
814 if self.as_mut_ptr().is_null() {
815 None
816 } else {
817 // SAFETY: pointer is non-null and points to a valid VecRef layout
818 Some(unsafe { VecRef::from_raw_mut(self.as_mut_ptr()) })
819 }
820 }
821}
822
823// Note: we intentionally do not implement Deref/DerefMut to VecRef<T> because owned vectors may
824// be empty (null pointer) and VecRef<T>::from_raw requires a valid non-null pointer.
825
826impl<T: Clone> Clone for Vec<T> {
827 fn clone(&self) -> Self {
828 self.as_slice().to_vpp_vec()
829 }
830}
831
832impl<T: fmt::Debug> fmt::Debug for Vec<T> {
833 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
834 fmt::Debug::fmt(self.as_slice(), f)
835 }
836}
837
838impl<T> AsRef<Vec<T>> for Vec<T> {
839 fn as_ref(&self) -> &Vec<T> {
840 self
841 }
842}
843
844impl<T> AsMut<Vec<T>> for Vec<T> {
845 fn as_mut(&mut self) -> &mut Vec<T> {
846 self
847 }
848}
849
850impl<T> AsRef<[T]> for Vec<T> {
851 fn as_ref(&self) -> &[T] {
852 self
853 }
854}
855
856impl<T> AsMut<[T]> for Vec<T> {
857 fn as_mut(&mut self) -> &mut [T] {
858 self
859 }
860}
861
862impl<T> Borrow<[T]> for Vec<T> {
863 fn borrow(&self) -> &[T] {
864 &self[..]
865 }
866}
867
868impl<T> BorrowMut<[T]> for Vec<T> {
869 fn borrow_mut(&mut self) -> &mut [T] {
870 &mut self[..]
871 }
872}
873
874impl<T> PartialOrd<Vec<T>> for Vec<T>
875where
876 T: PartialOrd,
877{
878 #[inline]
879 fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
880 PartialOrd::partial_cmp(&**self, &**other)
881 }
882}
883
884impl<T: Eq> Eq for Vec<T> {}
885
886impl<T: Ord> Ord for Vec<T> {
887 #[inline]
888 fn cmp(&self, other: &Self) -> Ordering {
889 Ord::cmp(&**self, &**other)
890 }
891}
892
893/// Extension trait for slices to convert to VPP vectors
894pub trait SliceExt<T> {
895 /// Converts the slice to a VPP vector by cloning each element
896 fn to_vpp_vec(&self) -> Vec<T>
897 where
898 T: Clone;
899}
900
901impl<T> SliceExt<T> for [T] {
902 fn to_vpp_vec(&self) -> Vec<T>
903 where
904 T: Clone,
905 {
906 let len = self.len();
907 let mut vec = Vec::with_capacity(len);
908 let slots = vec.spare_capacity_mut();
909 // .take(slots.len()) is necessary for LLVM to remove bounds checks
910 // and has better codegen than zip.
911 for (i, b) in self.iter().enumerate().take(slots.len()) {
912 slots[i].write(b.clone());
913 }
914 // SAFETY:
915 // the vec was allocated and initialized above to at least this length.
916 unsafe {
917 vec.set_len(self.len());
918 }
919 vec
920 }
921}
922
923macro_rules! __impl_slice_eq {
924 ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => {
925 impl<T, U, $($vars)*> PartialEq<$rhs> for $lhs
926 where
927 T: PartialEq<U>,
928 $($ty: $bound)?
929 {
930 #[inline]
931 fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
932 }
933 }
934}
935
936__impl_slice_eq! { [] VecRef<T>, VecRef<U> }
937__impl_slice_eq! { [] VecRef<T>, std::vec::Vec<U> }
938__impl_slice_eq! { [] VecRef<T>, &[U] }
939__impl_slice_eq! { [] VecRef<T>, &mut [U] }
940__impl_slice_eq! { [] VecRef<T>, [U] }
941__impl_slice_eq! { [] VecRef<T>, Vec<U> }
942__impl_slice_eq! { [] Vec<T>, Vec<U> }
943__impl_slice_eq! { [] Vec<T>, VecRef<U> }
944__impl_slice_eq! { [] Vec<T>, std::vec::Vec<U> }
945__impl_slice_eq! { [] Vec<T>, &[U] }
946__impl_slice_eq! { [] Vec<T>, &mut [U] }
947__impl_slice_eq! { [] Vec<T>, [U] }
948__impl_slice_eq! { [const N: usize] VecRef<T>, [U; N] }
949__impl_slice_eq! { [const N: usize] VecRef<T>, &[U; N] }
950
951// SAFETY: it's fine to deallocate the memory from another thread, and fine to access Vec<T> from
952// another thread as long as T is Send
953unsafe impl<T> Send for Vec<T> where T: Send {}
954
955/// Creates a [`Vec<T>`] from a list of elements
956///
957/// Allows creating a VPP vector in a similar way to the standard library's `vec!` macro.
958#[macro_export]
959macro_rules! vec {
960 () => (
961 $crate::vppinfra::vec::Vec::new()
962 );
963 ($elem:expr; $n:expr) => ({
964 let mut v = $crate::vppinfra::vec::Vec::with_capacity($n);
965 v.extend_with($n, $elem);
966 v
967 });
968 ($($x:expr),+ $(,)?) => (
969 $crate::vppinfra::vec::SliceExt::to_vpp_vec(
970 [$($x),+].as_slice()
971 )
972 );
973}
974
975#[cfg(test)]
976mod tests {
977 use crate::vppinfra::vec::SliceExt;
978 use crate::vppinfra::VecRef;
979 use crate::{vec, vppinfra::clib_mem_init};
980
981 use super::Vec;
982
983 #[test]
984 fn push_pop() {
985 clib_mem_init();
986
987 let mut v = Vec::new();
988 v.push(1);
989 v.push(2);
990 v.push(3);
991 assert_eq!(v.len(), 3);
992 assert!(v.capacity() >= 3);
993
994 assert_eq!(v.pop(), Some(3));
995 assert_eq!(v.pop(), Some(2));
996 assert_eq!(v.pop(), Some(1));
997 assert_eq!(v.pop(), None);
998 }
999
1000 #[test]
1001 fn test_macro() {
1002 clib_mem_init();
1003
1004 let v: Vec<u8> = vec![];
1005 assert_eq!(v.len(), 0);
1006
1007 let v = vec![1, 2, 3];
1008 assert_eq!(v[0], 1);
1009 assert_eq!(v[1], 2);
1010 assert_eq!(v[2], 3);
1011
1012 let v = vec![1; 3];
1013 assert_eq!(v[0], 1);
1014 assert_eq!(v[1], 1);
1015 assert_eq!(v[2], 1);
1016 }
1017
1018 #[test]
1019 fn extend_from() {
1020 clib_mem_init();
1021
1022 let mut v: Vec<u32> = Vec::new();
1023 v.extend(&[1, 2, 3]);
1024 assert_eq!(v.len(), 3);
1025 assert_eq!(v[0], 1);
1026 assert_eq!(v[1], 2);
1027 assert_eq!(v[2], 3);
1028 }
1029
1030 #[test]
1031 fn remove() {
1032 clib_mem_init();
1033
1034 let mut v = vec![1, 2, 3, 4];
1035 // Remove from the middle and shift
1036 let removed = v.remove(1);
1037 assert_eq!(removed, 2);
1038 assert_eq!(v.len(), 3);
1039 assert_eq!(v[0], 1);
1040 assert_eq!(v[1], 3);
1041 assert_eq!(v[2], 4);
1042
1043 // Remove from the end
1044 let removed = v.remove(2);
1045 assert_eq!(removed, 4);
1046 assert_eq!(v.len(), 2);
1047 assert_eq!(v[0], 1);
1048 assert_eq!(v[1], 3);
1049 }
1050
1051 #[test]
1052 fn insert_mut() {
1053 clib_mem_init();
1054
1055 let mut v = vec![1, 3];
1056 // Insert in the middle
1057 let slot = v.insert_mut(1, 2);
1058 // slot should point to the newly-inserted element
1059 assert_eq!(*slot, 2);
1060 assert_eq!(v.len(), 3);
1061 assert_eq!(v[0], 1);
1062 assert_eq!(v[1], 2);
1063 assert_eq!(v[2], 3);
1064
1065 // Insert at the end
1066 let slot = v.insert_mut(3, 4);
1067 // slot should point to the newly-inserted element
1068 assert_eq!(*slot, 4);
1069 assert_eq!(v.len(), 4);
1070 assert_eq!(v[0], 1);
1071 assert_eq!(v[1], 2);
1072 assert_eq!(v[2], 3);
1073 assert_eq!(v[3], 4);
1074 }
1075
1076 #[test]
1077 fn clear_preserves_capacity() {
1078 clib_mem_init();
1079
1080 let mut v = vec![10, 20, 30];
1081 let cap = v.capacity();
1082 v.clear();
1083 assert_eq!(v.len(), 0);
1084 assert!(
1085 v.capacity() >= cap,
1086 "New capacity {} should be >= old capacity {}",
1087 v.capacity(),
1088 cap
1089 );
1090 }
1091
1092 #[test]
1093 fn into_raw_and_from_raw_roundtrip() {
1094 clib_mem_init();
1095
1096 let mut v = Vec::new();
1097 v.push(7);
1098 v.push(8);
1099 let raw = v.into_raw();
1100
1101 // SAFETY: raw was produced by Vec::into_raw above and is valid to
1102 // reconstruct into a Vec here within the same process.
1103 unsafe {
1104 let v2 = Vec::from_raw(raw);
1105 assert_eq!(v2.len(), 2);
1106 assert_eq!(v2[0], 7);
1107 assert_eq!(v2[1], 8);
1108 // v2 drops here and frees the memory
1109 }
1110 }
1111
1112 #[test]
1113 fn extend_with_clones() {
1114 clib_mem_init();
1115
1116 let mut v: Vec<String> = Vec::new();
1117 v.extend_with(3, "x".to_string());
1118 assert_eq!(v.len(), 3);
1119 assert_eq!(v[0], "x");
1120 assert_eq!(v[1], "x");
1121 assert_eq!(v[2], "x");
1122 }
1123
1124 #[test]
1125 fn slice_to_vpp_vec() {
1126 clib_mem_init();
1127
1128 let s = [42u16, 43u16];
1129 let v = s.as_slice().to_vpp_vec();
1130 assert_eq!(v.len(), 2);
1131 assert_eq!(v[0], 42);
1132 assert_eq!(v[1], 43);
1133 }
1134
1135 #[test]
1136 fn clone_vec() {
1137 clib_mem_init();
1138
1139 let v = vec![5u8, 6u8];
1140 let v2 = v.clone();
1141 assert_eq!(v2.len(), 2);
1142 assert_eq!(v2[0], 5);
1143 assert_eq!(v2[1], 6);
1144 }
1145
1146 #[test]
1147 fn spare_capacity_and_set_len() {
1148 clib_mem_init();
1149
1150 let mut v: Vec<u32> = Vec::with_capacity(4);
1151 let slots = v.spare_capacity_mut();
1152 // write two values into spare capacity
1153 slots[0].write(100);
1154 slots[1].write(200);
1155 // SAFETY: we've initialised two elements and set_len is used to expose them
1156 unsafe { v.set_len(2) }
1157 assert_eq!(v.len(), 2);
1158 assert_eq!(v[0], 100);
1159 assert_eq!(v[1], 200);
1160 }
1161
1162 #[test]
1163 fn empty_vec_is_null() {
1164 clib_mem_init();
1165
1166 let mut v: Vec<u8> = Vec::new();
1167 assert_eq!(v.len(), 0);
1168 assert_eq!(v.capacity(), 0);
1169 assert_eq!(v.as_slice(), &[]);
1170 assert!(
1171 v.as_ptr().is_null(),
1172 "expected pointer for empty Vec to be null"
1173 );
1174
1175 assert_eq!(v.spare_capacity_mut().len(), 0);
1176 assert_eq!(v.pop(), None);
1177 v.clear();
1178
1179 let raw = v.into_raw();
1180 assert!(
1181 raw.is_null(),
1182 "expected raw pointer for empty Vec to be null"
1183 );
1184
1185 // SAFETY: the pointer is null and it's documented this is allowed
1186 let v = unsafe { Vec::from_raw(raw) };
1187 assert_eq!(v.as_vec_ref(), None);
1188
1189 // SAFETY: passing a null pointer to the function is documented as allowed
1190 let v = unsafe { VecRef::from_raw_opt(std::ptr::null::<u8>()) };
1191 assert_eq!(v, None);
1192
1193 // SAFETY: passing a null pointer to the function is documented as allowed
1194 let v = unsafe { VecRef::from_raw_mut_opt(std::ptr::null_mut::<u8>()) };
1195 assert_eq!(v, None);
1196 }
1197}