@@ -458,6 +458,41 @@ where
458
458
459
459
Ok ( ( ) )
460
460
}
461
+
462
+ /// Shortens the vector, setting the length to `len` and drops the removed values.
463
+ /// If `len` is greater than or equal to the current length, this does nothing.
464
+ ///
465
+ /// This has no effect on the capacity and will not allocate.
466
+ ///
467
+ /// # Examples
468
+ ///
469
+ /// ```
470
+ /// let mut v = kernel::kvec![1, 2, 3]?;
471
+ /// v.truncate(1);
472
+ /// assert_eq!(v.len(), 1);
473
+ /// assert_eq!(&v, &[1]);
474
+ ///
475
+ /// # Ok::<(), Error>(())
476
+ /// ```
477
+ pub fn truncate ( & mut self , len : usize ) {
478
+ if len >= self . len ( ) {
479
+ return ;
480
+ }
481
+
482
+ let drop_range = len..self . len ( ) ;
483
+
484
+ // SAFETY: `drop_range` is a subrange of `[0, len)` by the bounds check above.
485
+ let ptr: * mut [ T ] = unsafe { self . get_unchecked_mut ( drop_range) } ;
486
+
487
+ // SAFETY: By the above bounds check, it is guaranteed that `len < self.capacity()`.
488
+ unsafe { self . set_len ( len) } ;
489
+
490
+ // SAFETY:
491
+ // - the dropped values are valid `T`s by the type invariant
492
+ // - we are allowed to invalidate [`new_len`, `old_len`) because we just changed the
493
+ // len, therefore we have exclusive access to [`new_len`, `old_len`)
494
+ unsafe { ptr:: drop_in_place ( ptr) } ;
495
+ }
461
496
}
462
497
463
498
impl < T : Clone , A : Allocator > Vec < T , A > {
0 commit comments