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}