From b4b637f1479e1d689bfb2d5639b4de7118a28ff9 Mon Sep 17 00:00:00 2001 From: bluss Date: Wed, 21 Apr 2021 23:09:03 +0200 Subject: [PATCH] move_into: Add conversion .into_maybe_uninit() for array views --- src/impl_owned_array.rs | 21 +++++++++++++++++++++ src/impl_views/conversions.rs | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs index e91a7f61b..5c88ff6a5 100644 --- a/src/impl_owned_array.rs +++ b/src/impl_owned_array.rs @@ -168,6 +168,27 @@ impl Array /// drop of any such element, other elements may be leaked. /// /// ***Panics*** if the shapes don't agree. + /// + /// ## Example + /// + /// ``` + /// use ndarray::Array; + /// + /// // Usage example of move_into in safe code + /// let mut a = Array::zeros((10, 10)); + /// let b = Array::from_iter(0..100).into_shape((10, 10)).unwrap(); + /// // make an MaybeUninit view so that we can *overwrite* into it. + /// b.move_into(a.view_mut().into_maybe_uninit()); + /// + /// // Usage example using uninit + /// let mut a = Array::uninit((10, 10)); + /// let b = Array::from_iter(0..100).into_shape((10, 10)).unwrap(); + /// b.move_into(&mut a); + /// unsafe { + /// // we can now promise we have fully initialized `a`. + /// let a = a.assume_init(); + /// } + /// ``` pub fn move_into<'a, AM>(self, new_array: AM) where AM: Into, D>>, diff --git a/src/impl_views/conversions.rs b/src/impl_views/conversions.rs index cfd7f9aa0..b5f4cd76d 100644 --- a/src/impl_views/conversions.rs +++ b/src/impl_views/conversions.rs @@ -7,6 +7,7 @@ // except according to those terms. use alloc::slice; +use std::mem::MaybeUninit; use crate::imp_prelude::*; @@ -133,6 +134,21 @@ where self.into_raw_view_mut().cast::>().deref_into_view() } } + + /// Return the array view as a view of `MaybeUninit` elements + /// + /// This conversion leaves the elements as they were (presumably initialized), but + /// they are represented with the `MaybeUninit` type. Effectively this means that + /// the elements can be overwritten without dropping the old element in its place. + /// (In some situations this is not what you want, while for `Copy` elements it makes + /// no difference at all.) + pub fn into_maybe_uninit(self) -> ArrayViewMut<'a, MaybeUninit, D> { + // Safe because: A and MaybeUninit have the same representation; + // and we can go from initialized to (maybe) not unconditionally. + unsafe { + self.into_raw_view_mut().cast::>().deref_into_view_mut() + } + } } /// Private array view methods