mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Add recommend changes to array
Switch from indexing to zip, and also use `write` on `MaybeUninit`. Add array_map feature to core/src/lib Attempt to fix issue of no such feature Update w/ pickfire's review This changes a couple of names around, adds another small test of variable size, and hides the rustdoc #![feature(..)]. Fmt doctest Add suggestions from lcnr
This commit is contained in:
parent
f6411e4c66
commit
56a651ca15
@ -372,27 +372,28 @@ impl<T, const N: usize> [T; N] {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// let x = [1,2,3];
|
/// # #![feature(array_map)]
|
||||||
|
/// let x = [1, 2, 3];
|
||||||
/// let y = x.map(|v| v + 1);
|
/// let y = x.map(|v| v + 1);
|
||||||
/// assert_eq!(y, [2,3,4]);
|
/// assert_eq!(y, [2, 3, 4]);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "array_map", issue = "77777")]
|
#[unstable(feature = "array_map", issue = "77777")]
|
||||||
pub fn map<F, S>(self, mut f: F) -> [S; N]
|
pub fn map<F, U>(self, mut f: F) -> [U; N]
|
||||||
where
|
where
|
||||||
F: FnMut(T) -> S,
|
F: FnMut(T) -> U,
|
||||||
{
|
{
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
struct Guard<T, const N: usize> {
|
struct Guard<T, const N: usize> {
|
||||||
dst: *mut T,
|
dst: *mut T,
|
||||||
curr_init: usize,
|
initialized: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, const N: usize> Drop for Guard<T, N> {
|
impl<T, const N: usize> Drop for Guard<T, N> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
debug_assert!(self.curr_init <= N);
|
debug_assert!(self.initialized <= N);
|
||||||
|
|
||||||
let initialized_part =
|
let initialized_part =
|
||||||
crate::ptr::slice_from_raw_parts_mut(self.dst, self.curr_init);
|
crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
|
||||||
// SAFETY: this raw slice will contain only initialized objects
|
// SAFETY: this raw slice will contain only initialized objects
|
||||||
// that's why, it is allowed to drop it.
|
// that's why, it is allowed to drop it.
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -401,16 +402,16 @@ impl<T, const N: usize> [T; N] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut dst = MaybeUninit::uninit_array::<N>();
|
let mut dst = MaybeUninit::uninit_array::<N>();
|
||||||
let mut guard: Guard<S, N> = Guard { dst: &mut dst as *mut _ as *mut S, curr_init: 0 };
|
let mut guard: Guard<U, N> = Guard { dst: &mut dst as *mut _ as *mut U, initialized: 0 };
|
||||||
for (i, e) in IntoIter::new(self).enumerate() {
|
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
|
||||||
dst[i] = MaybeUninit::new(f(e));
|
dst.write(f(src));
|
||||||
guard.curr_init += 1;
|
guard.initialized += 1;
|
||||||
}
|
}
|
||||||
// FIXME convert to crate::mem::transmute when works with generics
|
// FIXME: Convert to crate::mem::transmute once it works with generics.
|
||||||
// unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
|
// unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
|
||||||
crate::mem::forget(guard);
|
crate::mem::forget(guard);
|
||||||
// SAFETY: At this point we've properly initialized the whole array
|
// SAFETY: At this point we've properly initialized the whole array
|
||||||
// and we just need to cast it to the correct type
|
// and we just need to cast it to the correct type.
|
||||||
unsafe { (&mut dst as *mut _ as *mut [S; N]).read() }
|
unsafe { (&mut dst as *mut _ as *mut [U; N]).read() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,7 @@
|
|||||||
#![feature(abi_unadjusted)]
|
#![feature(abi_unadjusted)]
|
||||||
#![feature(adx_target_feature)]
|
#![feature(adx_target_feature)]
|
||||||
#![feature(maybe_uninit_slice)]
|
#![feature(maybe_uninit_slice)]
|
||||||
|
#![feature(maybe_uninit_extra)]
|
||||||
#![feature(external_doc)]
|
#![feature(external_doc)]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(const_caller_location)]
|
#![feature(const_caller_location)]
|
||||||
|
@ -296,4 +296,8 @@ fn array_map() {
|
|||||||
let a = [1, 2, 3];
|
let a = [1, 2, 3];
|
||||||
let b = a.map(|v| v + 1);
|
let b = a.map(|v| v + 1);
|
||||||
assert_eq!(b, [2, 3, 4]);
|
assert_eq!(b, [2, 3, 4]);
|
||||||
|
|
||||||
|
let a = [1u8, 2, 3];
|
||||||
|
let b = a.map(|v| v as u64);
|
||||||
|
assert_eq!(b, [1, 2, 3]);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user