mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-27 12:30:35 +00:00
Vec: add set_len
This commit is contained in:
parent
9e08514d39
commit
0364e05766
99
src/vec.rs
99
src/vec.rs
@ -327,6 +327,103 @@ where
|
||||
self.resize(new_len, T::default())
|
||||
}
|
||||
|
||||
/// Forces the length of the vector to `new_len`.
|
||||
///
|
||||
/// This is a low-level operation that maintains none of the normal
|
||||
/// invariants of the type. Normally changing the length of a vector
|
||||
/// is done using one of the safe operations instead, such as
|
||||
/// [`truncate`], [`resize`], [`extend`], or [`clear`].
|
||||
///
|
||||
/// [`truncate`]: #method.truncate
|
||||
/// [`resize`]: #method.resize
|
||||
/// [`extend`]: https://doc.rust-lang.org/stable/core/iter/trait.Extend.html#tymethod.extend
|
||||
/// [`clear`]: #method.clear
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - `new_len` must be less than or equal to [`capacity()`].
|
||||
/// - The elements at `old_len..new_len` must be initialized.
|
||||
///
|
||||
/// [`capacity()`]: #method.capacity
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// This method can be useful for situations in which the vector
|
||||
/// is serving as a buffer for other code, particularly over FFI:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # #![allow(dead_code)]
|
||||
/// use heapless::Vec;
|
||||
/// use heapless::consts::*;
|
||||
///
|
||||
/// # // This is just a minimal skeleton for the doc example;
|
||||
/// # // don't use this as a starting point for a real library.
|
||||
/// # pub struct StreamWrapper { strm: *mut core::ffi::c_void }
|
||||
/// # const Z_OK: i32 = 0;
|
||||
/// # extern "C" {
|
||||
/// # fn deflateGetDictionary(
|
||||
/// # strm: *mut core::ffi::c_void,
|
||||
/// # dictionary: *mut u8,
|
||||
/// # dictLength: *mut usize,
|
||||
/// # ) -> i32;
|
||||
/// # }
|
||||
/// # impl StreamWrapper {
|
||||
/// pub fn get_dictionary(&self) -> Option<Vec<u8, U32768>> {
|
||||
/// // Per the FFI method's docs, "32768 bytes is always enough".
|
||||
/// let mut dict = Vec::new();
|
||||
/// let mut dict_length = 0;
|
||||
/// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
|
||||
/// // 1. `dict_length` elements were initialized.
|
||||
/// // 2. `dict_length` <= the capacity (32_768)
|
||||
/// // which makes `set_len` safe to call.
|
||||
/// unsafe {
|
||||
/// // Make the FFI call...
|
||||
/// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
|
||||
/// if r == Z_OK {
|
||||
/// // ...and update the length to what was initialized.
|
||||
/// dict.set_len(dict_length);
|
||||
/// Some(dict)
|
||||
/// } else {
|
||||
/// None
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// While the following example is sound, there is a memory leak since
|
||||
/// the inner vectors were not freed prior to the `set_len` call:
|
||||
///
|
||||
/// ```
|
||||
/// use core::iter::FromIterator;
|
||||
/// use heapless::Vec;
|
||||
/// use heapless::consts::*;
|
||||
///
|
||||
/// let mut vec = Vec::<Vec<u8, U3>, U3>::from_iter(
|
||||
/// [
|
||||
/// Vec::from_iter([1, 0, 0].iter().cloned()),
|
||||
/// Vec::from_iter([0, 1, 0].iter().cloned()),
|
||||
/// Vec::from_iter([0, 0, 1].iter().cloned()),
|
||||
/// ]
|
||||
/// .iter()
|
||||
/// .cloned()
|
||||
/// );
|
||||
/// // SAFETY:
|
||||
/// // 1. `old_len..0` is empty so no elements need to be initialized.
|
||||
/// // 2. `0 <= capacity` always holds whatever `capacity` is.
|
||||
/// unsafe {
|
||||
/// vec.set_len(0);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Normally, here, one would use [`clear`] instead to correctly drop
|
||||
/// the contents and thus not leak memory.
|
||||
pub unsafe fn set_len(&mut self, new_len: usize) {
|
||||
debug_assert!(new_len <= self.capacity());
|
||||
|
||||
self.0.len = new_len
|
||||
}
|
||||
|
||||
/// Removes an element from the vector and returns it.
|
||||
///
|
||||
/// The removed element is replaced by the last element of the vector.
|
||||
@ -726,8 +823,8 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use as_slice::AsSlice;
|
||||
use crate::{consts::*, Vec};
|
||||
use as_slice::AsSlice;
|
||||
use core::fmt::Write;
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user