From 1906c6f714502b1a0de46b9c217dc02570c3fd3e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 19 Oct 2019 00:48:21 +0200 Subject: [PATCH] Add `MaybeUninit` methods `uninit_array`, `slice_get_ref`, `slice_get_mut` --- src/libcore/mem/maybe_uninit.rs | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 03093139bc2..46b0fd3c3cb 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -258,6 +258,37 @@ impl MaybeUninit { MaybeUninit { uninit: () } } + /// Create a new array of `MaybeUninit` items, in an uninitialized state. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)] + /// use std::mem::MaybeUninit; + /// + /// let input = b"Foo"; + /// let f = u8::to_ascii_uppercase; + /// + /// let mut buffer: [MaybeUninit; 32] = MaybeUninit::uninit_array(); + /// let vec; + /// let output = if let Some(buffer) = buffer.get_mut(..input.len()) { + /// buffer.iter_mut().zip(input).for_each(|(a, b)| { a.write(f(b)); }); + /// unsafe { MaybeUninit::slice_get_ref(buffer) } + /// } else { + /// vec = input.iter().map(f).collect::>(); + /// &vec + /// }; + /// + /// assert_eq!(output, b"FOO"); + /// ``` + #[unstable(feature = "maybe_uninit_uninit_array", issue = "0")] + #[inline(always)] + pub fn uninit_array() -> [Self; LEN] { + unsafe { + MaybeUninit::<[MaybeUninit; LEN]>::uninit().assume_init() + } + } + /// A promotable constant, equivalent to `uninit()`. #[unstable(feature = "internal_uninit_const", issue = "0", reason = "hack to work around promotability")] @@ -690,6 +721,32 @@ impl MaybeUninit { &mut *self.value } + /// Get a slice of assume-initialized items. + /// + /// # Safety + /// + /// It is up to the caller to guarantee that the `MaybeUninit` items + /// really are in an initialized state. + /// Calling this when the content is not yet fully initialized causes undefined behavior. + #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")] + #[inline(always)] + pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] { + &*(slice as *const [Self] as *const [T]) + } + + /// Get a mutable slice of assume-initialized items. + /// + /// # Safety + /// + /// It is up to the caller to guarantee that the `MaybeUninit` items + /// really are in an initialized state. + /// Calling this when the content is not yet fully initialized causes undefined behavior. + #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")] + #[inline(always)] + pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] { + &mut *(slice as *mut [Self] as *mut [T]) + } + /// Gets a pointer to the first element of the array. #[unstable(feature = "maybe_uninit_slice", issue = "63569")] #[inline(always)]