@@ -160,13 +160,15 @@ use core::{
160160mod extension;
161161mod impls;
162162mod slice;
163- // mod set_len;
164163
165164pub mod iter;
166165pub mod raw;
167166
168167use raw:: Storage ;
169168
169+ #[ doc( hidden) ]
170+ pub use core;
171+
170172/// A heap backed vector with a growable capacity
171173#[ cfg( any( doc, feature = "alloc" ) ) ]
172174#[ cfg( feature = "nightly" ) ]
@@ -181,7 +183,7 @@ pub type HeapVec<T> = GenericVec<T, raw::Heap<T>>;
181183#[ cfg( any( doc, feature = "nightly" ) ) ]
182184pub type ArrayVec < T , const N : usize > = TypeVec < T , [ T ; N ] > ;
183185/// An slice backed vector backed by potentially uninitialized memory
184- pub type SliceVec < ' a , T > = GenericVec < T , raw:: UninitSlice < ' a , T > > ;
186+ pub type SliceVec < ' a , T > = GenericVec < T , & ' a mut raw:: UninitSlice < T > > ;
185187
186188/// An array backed vector backed by initialized memory
187189#[ cfg( any( doc, feature = "nightly" ) ) ]
@@ -286,6 +288,37 @@ macro_rules! uninit_array {
286288 } ;
287289}
288290
291+ /// Save the changes to [`GenericVec::spare_capacity_mut`]
292+ ///
293+ /// $orig - a mutable reference to a [`GenericVec`]
294+ /// $spare - the [`SliceVec`] that was obtained from [`$orig.spare_capacity_mut()`]
295+ ///
296+ /// # Safety
297+ ///
298+ /// `$spare` should be the [`SliceVec`] returned by `$orig.spare_capacity_mut()`
299+ #[ macro_export]
300+ macro_rules! save_spare {
301+ ( $spare: expr, $orig: expr) => { {
302+ let spare: $crate:: SliceVec <_> = $spare;
303+ let spare = $crate:: core:: mem:: ManuallyDrop :: new( spare) ;
304+ let len = spare. len( ) ;
305+ let ptr = spare. as_ptr( ) ;
306+ let orig: & mut $crate:: GenericVec <_, _> = $orig;
307+ $crate:: validate_spare( ptr, orig) ;
308+ let len = len + orig. len( ) ;
309+ $orig. set_len_unchecked( len) ;
310+ } } ;
311+ }
312+
313+ #[ doc( hidden) ]
314+ pub fn validate_spare < T > ( spare_ptr : * const T , orig : & [ T ] ) {
315+ debug_assert ! (
316+ unsafe { orig. as_ptr( ) . add( orig. len( ) ) == spare_ptr } ,
317+ "Tried to use `save_spare!` with a `SliceVec` that was not obtained from `GenricVec::spare_capacity_mut`. \
318+ This is undefined behavior on release mode!"
319+ )
320+ }
321+
289322/// A vector type that can be backed up by a variety of different backends
290323/// including slices, arrays, and the heap.
291324#[ repr( C ) ]
@@ -452,13 +485,13 @@ impl<T, A: std::alloc::AllocRef> HeapVec<T, A> {
452485#[ cfg( not( feature = "nightly" ) ) ]
453486impl < ' a , T > SliceVec < ' a , T > {
454487 /// Create a new empty `SliceVec`
455- pub fn new ( slice : & ' a mut [ MaybeUninit < T > ] ) -> Self { Self :: with_storage ( raw:: UninitSlice :: new ( slice) ) }
488+ pub fn new ( slice : & ' a mut [ MaybeUninit < T > ] ) -> Self { Self :: with_storage ( raw:: UninitSlice :: from_mut ( slice) ) }
456489}
457490
458491#[ cfg( feature = "nightly" ) ]
459492impl < ' a , T > SliceVec < ' a , T > {
460493 /// Create a new empty `SliceVec`
461- pub const fn new ( slice : & ' a mut [ MaybeUninit < T > ] ) -> Self { Self :: with_storage ( raw:: UninitSlice :: new ( slice) ) }
494+ pub const fn new ( slice : & ' a mut [ MaybeUninit < T > ] ) -> Self { Self :: with_storage ( raw:: UninitSlice :: from_mut ( slice) ) }
462495}
463496
464497impl < ' a , T : Copy > InitSliceVec < ' a , T > {
@@ -587,10 +620,28 @@ impl<T, S: ?Sized + Storage<T>> GenericVec<T, S> {
587620 pub unsafe fn storage_mut ( & mut self ) -> & mut S { & mut self . storage }
588621
589622 /// Returns the remaining spare capacity of the vector as
590- /// a `SliceVec<'_, T>`.
623+ /// a [ `SliceVec<'_, T>`](SliceVec) .
591624 ///
592- /// Keep in mind that the `SliceVec<'_, T>` will drop all elements
593- /// that you push into it!
625+ /// Keep in mind that the [`SliceVec<'_, T>`](SliceVec) will drop all elements
626+ /// that you push into it when it goes out of scope! If you want
627+ /// these modifications to persist then you should use [`save_spare`]
628+ /// to persist these writes.
629+ ///
630+ /// ```
631+ /// let mut vec = generic_vec::TypeVec::<i32, [i32; 16]>::new();
632+ ///
633+ /// let mut spare = vec.spare_capacity_mut();
634+ /// spare.push(0);
635+ /// spare.push(2);
636+ /// drop(spare);
637+ /// assert_eq!(vec, []);
638+ ///
639+ /// let mut spare = vec.spare_capacity_mut();
640+ /// spare.push(0);
641+ /// spare.push(2);
642+ /// unsafe { generic_vec::save_spare!(spare, &mut vec) }
643+ /// assert_eq!(vec, [0, 2]);
644+ /// ```
594645 pub fn spare_capacity_mut ( & mut self ) -> SliceVec < ' _ , T > {
595646 // Safety
596647 //
@@ -725,9 +776,7 @@ impl<T, S: ?Sized + Storage<T>> GenericVec<T, S> {
725776 }
726777
727778 unsafe {
728- let writer = core:: mem:: ManuallyDrop :: new ( writer) ;
729- let len = writer. len ( ) + self . len ( ) ;
730- self . set_len_unchecked ( len) ;
779+ save_spare ! ( writer, self ) ;
731780 }
732781 }
733782
@@ -1601,7 +1650,7 @@ impl<T, S: ?Sized + Storage<T>> GenericVec<T, S> {
16011650 ///
16021651 /// When the iterator is dropped, all elements in the range are removed from
16031652 /// the vector, even if the iterator was not fully consumed. If the iterator
1604- /// is not dropped (with mem::forget for example), it is unspecified how many
1653+ /// is not dropped (with ` mem::forget` for example), it is unspecified how many
16051654 /// elements are removed.
16061655 ///
16071656 /// # Panic
0 commit comments