diff options
| -rw-r--r-- | library/core/src/array/mod.rs | 53 | ||||
| -rw-r--r-- | src/librustc_hir/lang_items.rs | 1 |
2 files changed, 54 insertions, 0 deletions
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index c0bf3833b9c..b549cd8959f 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -364,3 +364,56 @@ macro_rules! array_impl_default { } array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} + +#[cfg(not(bootstrap))] +#[lang = "array"] +impl<T, const N: usize> [T; N] { + /// Returns an array of the same size as self, with `f` applied to each element. + /// + /// # Examples + /// ``` + /// let x = [1,2,3]; + /// let y = x.map(|v| v + 1); + /// assert_eq!(y, [2,3,4]); + /// ``` + #[unstable(feature = "array_map", issue = "77777")] + fn map<F, S>(self, f: F) -> [S; N] + where + F: FnMut(T) -> S, + { + use crate::mem::MaybeUninit; + struct Guard<T, const N: usize> { + dst: *mut T, + curr_init: usize, + } + + impl<T, const N: usize> Guard<T, N> { + fn new(dst: &mut [MaybeUninit<T>; N]) -> Self { + Guard { dst: dst as *mut _ as *mut T, curr_init: 0 } + } + } + + impl<T, const N: usize> Drop for Guard<T, N> { + fn drop(&mut self) { + debug_assert!(self.curr_init <= N); + + let initialized_part = + crate::ptr::slice_from_raw_parts_mut(self.dst, self.curr_init); + // SAFETY: this raw slice will contain only initialized objects + // that's why, it is allowed to drop it. + unsafe { + crate::ptr::drop_in_place(initialized_part); + } + } + } + let dst = MaybeUninit::uninit_array::<N>(); + let mut guard = Guard::new(&mut dst); + for (i, e) in self.into_iter().enumerate() { + dst[i] = MaybeUninit::new(f(e)); + guard.curr_init += 1; + } + // FIXME convert to crate::mem::transmute when works with generics + // unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) } + unsafe { (&mut dst as *mut _ as *mut [S; N]).read() } + } +} diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs index 7f473a45848..2f7edeb405f 100644 --- a/src/librustc_hir/lang_items.rs +++ b/src/librustc_hir/lang_items.rs @@ -165,6 +165,7 @@ language_item_table! { BoolImplItem, sym::bool, bool_impl, Target::Impl; CharImplItem, sym::char, char_impl, Target::Impl; StrImplItem, sym::str, str_impl, Target::Impl; + ArrayImplItem, sym::array, array_impl, Target::Impl; SliceImplItem, sym::slice, slice_impl, Target::Impl; SliceU8ImplItem, sym::slice_u8, slice_u8_impl, Target::Impl; StrAllocImplItem, sym::str_alloc, str_alloc_impl, Target::Impl; |
