diff options
| author | Aljoscha Meyer <AljoschaMeyer@users.noreply.github.com> | 2024-07-06 09:09:10 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-06 09:09:10 +0200 |
| commit | 2c14dd3b12d29749465a84429a4643da5c4e3934 (patch) | |
| tree | e6e8381f290f3969a7e9121220bb853a5ee4e744 | |
| parent | 51917e2e69702e5752bce6a4f3bfd285d0f4ae39 (diff) | |
| download | rust-2c14dd3b12d29749465a84429a4643da5c4e3934.tar.gz rust-2c14dd3b12d29749465a84429a4643da5c4e3934.zip | |
Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in
The methods for fallible slice allocation in a given allocator were missing, which was an oversight according to https://github.com/rust-lang/wg-allocators/issues/130 This PR adds them as `try_new_uninit_slice_in` and `try_new_zeroed_slice_in`. Also adds missing punctuation to the doc comments of ` try_new_uninit_slice` and `try_new_zeroed_slice`
| -rw-r--r-- | library/alloc/src/boxed.rs | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1ec095a46f7..d67b0ac37eb 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -704,7 +704,7 @@ impl<T> Box<[T]> { } /// Constructs a new boxed slice with uninitialized contents. Returns an error if - /// the allocation fails + /// the allocation fails. /// /// # Examples /// @@ -739,7 +739,7 @@ impl<T> Box<[T]> { } /// Constructs a new boxed slice with uninitialized contents, with the memory - /// being filled with `0` bytes. Returns an error if the allocation fails + /// 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. @@ -831,6 +831,79 @@ impl<T, A: Allocator> Box<[T], A> { pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> { unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } } + + /// Constructs a new boxed slice with uninitialized contents in the provided allocator. Returns an error if + /// the allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api, new_uninit)] + /// + /// use std::alloc::System; + /// + /// let mut values = Box::<[u32]>::try_new_uninit_slice(3, System)?; + /// let values = unsafe { + /// // Deferred initialization: + /// values[0].as_mut_ptr().write(1); + /// values[1].as_mut_ptr().write(2); + /// values[2].as_mut_ptr().write(3); + /// values.assume_init() + /// }; + /// + /// assert_eq!(*values, [1, 2, 3]); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn try_new_uninit_slice_in(len: usize, alloc: A) -> Result<Box<[mem::MaybeUninit<T>], A>, AllocError> { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { + let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + Global.allocate(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } + } + + /// Constructs a new boxed slice with uninitialized contents in the provided allocator, 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)] + /// + /// use std::alloc::System; + /// + /// let values = Box::<[u32]>::try_new_zeroed_slice(3, System)?; + /// 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_in(len: usize, alloc: A) -> Result<Box<[mem::MaybeUninit<T>], A>, AllocError> { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { + let layout = match Layout::array::<mem::MaybeUninit<T>>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + Global.allocate_zeroed(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } + } } impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { |
