Skip to content

Commit e2765f8

Browse files
authored
Rollup merge of rust-lang#81687 - WaffleLapkin:split_at_spare, r=KodrAus
Make Vec::split_at_spare_mut public This PR introduces a new method to the public API, under `vec_split_at_spare` feature gate: ```rust impl<T, A: Allocator> impl Vec<T, A> { pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]); } ``` The method returns 2 slices, one slice references the content of the vector, and the other references the remaining spare capacity. The method was previously implemented while adding `Vec::extend_from_within` in rust-lang#79015, and used to implement `Vec::spare_capacity_mut` (as the later is just a subset of former one). See also previous [discussion in `Vec::spare_capacity_mut` tracking issue](rust-lang#75017 (comment)). ## Unresolved questions - [ ] Should we consider changing the name? `split_at_spare_mut` doesn't seem like an intuitive name - [ ] Should we deprecate `Vec::spare_capacity_mut`? Any usecase of `Vec::spare_capacity_mut` can be replaced with `Vec::split_at_spare_mut` (but not vise-versa) r? `@KodrAus`
2 parents 3f09418 + 8ff7b75 commit e2765f8

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

library/alloc/src/vec/mod.rs

+53-1
Original file line numberDiff line numberDiff line change
@@ -1828,8 +1828,60 @@ impl<T, A: Allocator> Vec<T, A> {
18281828
self.split_at_spare_mut().1
18291829
}
18301830

1831+
/// Returns vector content as a slice of `T`, along with the remaining spare
1832+
/// capacity of the vector as a slice of `MaybeUninit<T>`.
1833+
///
1834+
/// The returned spare capacity slice can be used to fill the vector with data
1835+
/// (e.g. by reading from a file) before marking the data as initialized using
1836+
/// the [`set_len`] method.
1837+
///
1838+
/// [`set_len`]: Vec::set_len
1839+
///
1840+
/// Note that this is a low-level API, which should be used with care for
1841+
/// optimization purposes. If you need to append data to a `Vec`
1842+
/// you can use [`push`], [`extend`], [`extend_from_slice`],
1843+
/// [`extend_from_within`], [`insert`], [`append`], [`resize`] or
1844+
/// [`resize_with`], depending on your exact needs.
1845+
///
1846+
/// [`push`]: Vec::push
1847+
/// [`extend`]: Vec::extend
1848+
/// [`extend_from_slice`]: Vec::extend_from_slice
1849+
/// [`extend_from_within`]: Vec::extend_from_within
1850+
/// [`insert`]: Vec::insert
1851+
/// [`append`]: Vec::append
1852+
/// [`resize`]: Vec::resize
1853+
/// [`resize_with`]: Vec::resize_with
1854+
///
1855+
/// # Examples
1856+
///
1857+
/// ```
1858+
/// #![feature(vec_split_at_spare, maybe_uninit_extra)]
1859+
///
1860+
/// let mut v = vec![1, 1, 2];
1861+
///
1862+
/// // Reserve additional space big enough for 10 elements.
1863+
/// v.reserve(10);
1864+
///
1865+
/// let (init, uninit) = v.split_at_spare_mut();
1866+
/// let sum = init.iter().copied().sum::<u32>();
1867+
///
1868+
/// // Fill in the next 4 elements.
1869+
/// uninit[0].write(sum);
1870+
/// uninit[1].write(sum * 2);
1871+
/// uninit[2].write(sum * 3);
1872+
/// uninit[3].write(sum * 4);
1873+
///
1874+
/// // Mark the 4 elements of the vector as being initialized.
1875+
/// unsafe {
1876+
/// let len = v.len();
1877+
/// v.set_len(len + 4);
1878+
/// }
1879+
///
1880+
/// assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
1881+
/// ```
1882+
#[unstable(feature = "vec_split_at_spare", issue = "81944")]
18311883
#[inline]
1832-
fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
1884+
pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
18331885
let ptr = self.as_mut_ptr();
18341886

18351887
// Safety:

0 commit comments

Comments
 (0)