Skip to content

Commit d8c717e

Browse files
committed
ADD: truncate() and clear()
Code is taken from the stdlib Vec and adapted to HeaderVec
1 parent 09d6827 commit d8c717e

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

src/lib.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,94 @@ impl<H, T> HeaderVec<H, T> {
474474
self.header_mut().len = new_len.into();
475475
}
476476

477+
/// Shortens a `HeaderVec`, keeping the first `len` elements and dropping
478+
/// the rest.
479+
///
480+
/// If `len` is greater or equal to the vector's current length, this has
481+
/// no effect.
482+
///
483+
/// The [`drain`] method can emulate `truncate`, but causes the excess
484+
/// elements to be returned instead of dropped.
485+
///
486+
/// Note that this method has no effect on the allocated capacity
487+
/// of the vector.
488+
///
489+
/// # Examples
490+
///
491+
/// Truncating a five element `HeaderVec` to two elements:
492+
///
493+
/// ```
494+
/// use header_vec::HeaderVec;
495+
/// let mut hv: HeaderVec<(), _> = HeaderVec::from([1, 2, 3, 4, 5]);
496+
/// hv.truncate(2);
497+
/// assert_eq!(hv.as_slice(), [1, 2]);
498+
/// ```
499+
///
500+
/// No truncation occurs when `len` is greater than the vector's current
501+
/// length:
502+
///
503+
/// ```
504+
/// use header_vec::HeaderVec;
505+
/// let mut hv: HeaderVec<(), _> = HeaderVec::from([1, 2, 3]);
506+
/// hv.truncate(8);
507+
/// assert_eq!(hv.as_slice(), [1, 2, 3]);
508+
/// ```
509+
///
510+
/// Truncating when `len == 0` is equivalent to calling the [`clear`]
511+
/// method.
512+
///
513+
/// ```
514+
/// use header_vec::HeaderVec;
515+
/// let mut hv: HeaderVec<(), _> = HeaderVec::from([1, 2, 3]);
516+
/// hv.truncate(0);
517+
/// assert_eq!(hv.as_slice(), []);
518+
/// ```
519+
///
520+
/// [`clear`]: HeaderVec::clear
521+
pub fn truncate(&mut self, len: usize) {
522+
unsafe {
523+
let old_len = self.len_exact();
524+
if len > old_len {
525+
return;
526+
}
527+
let remaining_len = old_len - len;
528+
let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
529+
self.header_mut().len = len.into();
530+
ptr::drop_in_place(s);
531+
}
532+
}
533+
534+
/// Clears a `HeaderVec`, removing all values.
535+
///
536+
/// Note that this method has no effect on the allocated capacity
537+
/// of the vector.
538+
///
539+
/// # Examples
540+
///
541+
/// ```
542+
/// use header_vec::HeaderVec;
543+
/// let mut hv: HeaderVec<(), _> = HeaderVec::from([1, 2, 3]);
544+
///
545+
/// hv.clear();
546+
///
547+
/// assert!(hv.is_empty());
548+
/// ```
549+
#[inline]
550+
pub fn clear(&mut self) {
551+
let elems: *mut [T] = self.as_mut_slice();
552+
553+
// SAFETY:
554+
// - `elems` comes directly from `as_mut_slice` and is therefore valid.
555+
// - Setting the length before calling `drop_in_place` means that,
556+
// if an element's `Drop` impl panics, the vector's `Drop` impl will
557+
// do nothing (leaking the rest of the elements) instead of dropping
558+
// some twice.
559+
unsafe {
560+
self.set_len(0);
561+
ptr::drop_in_place(elems);
562+
}
563+
}
564+
477565
/// Gives the offset in units of T (as if the pointer started at an array of T) that the slice actually starts at.
478566
#[inline(always)]
479567
const fn offset() -> usize {

0 commit comments

Comments
 (0)