diff options
| author | The8472 <git@infinite-source.de> | 2021-08-05 00:23:19 +0200 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2021-08-05 00:23:19 +0200 |
| commit | de91157389c4cf63ee6805e8490d0872fe2a7b33 (patch) | |
| tree | f60762dee327f1ac1778c801088836c6847b8731 | |
| parent | 6fe0886723c9e08b800c9951f1c6f6a57b2bf22c (diff) | |
| download | rust-de91157389c4cf63ee6805e8490d0872fe2a7b33.tar.gz rust-de91157389c4cf63ee6805e8490d0872fe2a7b33.zip | |
add Box::try_new_zeroed_slice()
Currently there is no API that allows fallible zero-allocation of a Vec. Vec.try_reserve is not appropriate for this job since it doesn't know whether it should zero or arbitrary uninitialized memory is fine. Since Box currently holds most of the zeroing/uninit/slice allocation APIs it's the best place to add yet another entry into this feature matrix.
| -rw-r--r-- | library/alloc/src/boxed.rs | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 53bfe02d0e7..e09cc227105 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -589,6 +589,38 @@ impl<T> Box<[T]> { pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } } + + /// Constructs a new boxed slice with uninitialized contents, with the memory + /// being filled with `0` bytes. Returns an error if the allocation fails + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api, new_uninit)] + /// + /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?; + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn try_new_zeroed_slice(len: usize) -> Result<Box<[mem::MaybeUninit<T>]>, AllocError> { + unsafe { + let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + let ptr = Global.allocate_zeroed(layout)?; + Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) + } + } } impl<T, A: Allocator> Box<[T], A> { |
