Skip to main content

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