diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-12-03 06:24:11 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-03 06:24:11 +0100 |
| commit | 31003a3089cce2a918a9c8b73a77781d19c5f1d8 (patch) | |
| tree | 8e2318b63cfa60e6bf19534700afdb09bedd878e /library/alloc | |
| parent | ff23ad3179014ba258f2b540fb39dd0f26852b7a (diff) | |
| parent | 41e21aa1c27522c6b29c5b88e37b1f479f63e38c (diff) | |
| download | rust-31003a3089cce2a918a9c8b73a77781d19c5f1d8.tar.gz rust-31003a3089cce2a918a9c8b73a77781d19c5f1d8.zip | |
Rollup merge of #88906 - Kixunil:box-maybe-uninit-write, r=dtolnay
Implement write() method for Box<MaybeUninit<T>> This adds method similar to `MaybeUninit::write` main difference being it returns owned `Box`. This can be used to elide copy from stack safely, however it's not currently tested that the optimization actually occurs. Analogous methods are not provided for `Rc` and `Arc` as those need to handle the possibility of sharing. Some version of them may be added in the future. This was discussed in #63291 which this change extends.
Diffstat (limited to 'library/alloc')
| -rw-r--r-- | library/alloc/src/boxed.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f6332b072cf..0b72b3f0ee7 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -763,6 +763,42 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } + + /// Writes the value and converts to `Box<T, A>`. + /// + /// This method converts the box similarly to [`Box::assume_init`] but + /// writes `value` into it before conversion thus guaranteeing safety. + /// In some scenarios use of this method may improve performance because + /// the compiler may be able to optimize copying from stack. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_uninit)] + /// + /// let big_box = Box::<[usize; 1024]>::new_uninit(); + /// + /// let mut array = [0; 1024]; + /// for (i, place) in array.iter_mut().enumerate() { + /// *place = i; + /// } + /// + /// // The optimizer may be able to elide this copy, so previous code writes + /// // to heap directly. + /// let big_box = Box::write(big_box, array); + /// + /// for (i, x) in big_box.iter().enumerate() { + /// assert_eq!(*x, i); + /// } + /// ``` + #[unstable(feature = "new_uninit", issue = "63291")] + #[inline] + pub fn write(mut boxed: Self, value: T) -> Box<T, A> { + unsafe { + (*boxed).write(value); + boxed.assume_init() + } + } } impl<T, A: Allocator> Box<[mem::MaybeUninit<T>], A> { |
