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}