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