@@ -327,6 +327,103 @@ where
327
327
self . resize ( new_len, T :: default ( ) )
328
328
}
329
329
330
+ /// Forces the length of the vector to `new_len`.
331
+ ///
332
+ /// This is a low-level operation that maintains none of the normal
333
+ /// invariants of the type. Normally changing the length of a vector
334
+ /// is done using one of the safe operations instead, such as
335
+ /// [`truncate`], [`resize`], [`extend`], or [`clear`].
336
+ ///
337
+ /// [`truncate`]: #method.truncate
338
+ /// [`resize`]: #method.resize
339
+ /// [`extend`]: https://doc.rust-lang.org/stable/core/iter/trait.Extend.html#tymethod.extend
340
+ /// [`clear`]: #method.clear
341
+ ///
342
+ /// # Safety
343
+ ///
344
+ /// - `new_len` must be less than or equal to [`capacity()`].
345
+ /// - The elements at `old_len..new_len` must be initialized.
346
+ ///
347
+ /// [`capacity()`]: #method.capacity
348
+ ///
349
+ /// # Examples
350
+ ///
351
+ /// This method can be useful for situations in which the vector
352
+ /// is serving as a buffer for other code, particularly over FFI:
353
+ ///
354
+ /// ```no_run
355
+ /// # #![allow(dead_code)]
356
+ /// use heapless::Vec;
357
+ /// use heapless::consts::*;
358
+ ///
359
+ /// # // This is just a minimal skeleton for the doc example;
360
+ /// # // don't use this as a starting point for a real library.
361
+ /// # pub struct StreamWrapper { strm: *mut core::ffi::c_void }
362
+ /// # const Z_OK: i32 = 0;
363
+ /// # extern "C" {
364
+ /// # fn deflateGetDictionary(
365
+ /// # strm: *mut core::ffi::c_void,
366
+ /// # dictionary: *mut u8,
367
+ /// # dictLength: *mut usize,
368
+ /// # ) -> i32;
369
+ /// # }
370
+ /// # impl StreamWrapper {
371
+ /// pub fn get_dictionary(&self) -> Option<Vec<u8, U32768>> {
372
+ /// // Per the FFI method's docs, "32768 bytes is always enough".
373
+ /// let mut dict = Vec::new();
374
+ /// let mut dict_length = 0;
375
+ /// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
376
+ /// // 1. `dict_length` elements were initialized.
377
+ /// // 2. `dict_length` <= the capacity (32_768)
378
+ /// // which makes `set_len` safe to call.
379
+ /// unsafe {
380
+ /// // Make the FFI call...
381
+ /// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
382
+ /// if r == Z_OK {
383
+ /// // ...and update the length to what was initialized.
384
+ /// dict.set_len(dict_length);
385
+ /// Some(dict)
386
+ /// } else {
387
+ /// None
388
+ /// }
389
+ /// }
390
+ /// }
391
+ /// # }
392
+ /// ```
393
+ ///
394
+ /// While the following example is sound, there is a memory leak since
395
+ /// the inner vectors were not freed prior to the `set_len` call:
396
+ ///
397
+ /// ```
398
+ /// use core::iter::FromIterator;
399
+ /// use heapless::Vec;
400
+ /// use heapless::consts::*;
401
+ ///
402
+ /// let mut vec = Vec::<Vec<u8, U3>, U3>::from_iter(
403
+ /// [
404
+ /// Vec::from_iter([1, 0, 0].iter().cloned()),
405
+ /// Vec::from_iter([0, 1, 0].iter().cloned()),
406
+ /// Vec::from_iter([0, 0, 1].iter().cloned()),
407
+ /// ]
408
+ /// .iter()
409
+ /// .cloned()
410
+ /// );
411
+ /// // SAFETY:
412
+ /// // 1. `old_len..0` is empty so no elements need to be initialized.
413
+ /// // 2. `0 <= capacity` always holds whatever `capacity` is.
414
+ /// unsafe {
415
+ /// vec.set_len(0);
416
+ /// }
417
+ /// ```
418
+ ///
419
+ /// Normally, here, one would use [`clear`] instead to correctly drop
420
+ /// the contents and thus not leak memory.
421
+ pub unsafe fn set_len ( & mut self , new_len : usize ) {
422
+ debug_assert ! ( new_len <= self . capacity( ) ) ;
423
+
424
+ self . 0 . len = new_len
425
+ }
426
+
330
427
/// Removes an element from the vector and returns it.
331
428
///
332
429
/// The removed element is replaced by the last element of the vector.
@@ -726,8 +823,8 @@ where
726
823
727
824
#[ cfg( test) ]
728
825
mod tests {
729
- use as_slice:: AsSlice ;
730
826
use crate :: { consts:: * , Vec } ;
827
+ use as_slice:: AsSlice ;
731
828
use core:: fmt:: Write ;
732
829
733
830
#[ test]
0 commit comments