From 3d4f8b1f450e883b18c17bc56a1de575dd06f148 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 19 Dec 2023 19:30:52 +0100 Subject: core: implement `array::repeat` --- library/core/src/array/mod.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'library/core/src/array') diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 2569ce23707..fdb707bf51d 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -10,6 +10,7 @@ use crate::convert::Infallible; use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; +use crate::intrinsics::transmute_unchecked; use crate::iter::UncheckedIterator; use crate::mem::{self, MaybeUninit}; use crate::ops::{ @@ -27,6 +28,41 @@ pub(crate) use drain::drain_array_with; #[stable(feature = "array_value_iter", since = "1.51.0")] pub use iter::IntoIter; +/// Creates an array of type `[T; N]` by repeatedly cloning a value. +/// +/// The value will be used as the last element of the resulting array, so it +/// will be cloned N - 1 times. If N is zero, the value will be dropped. +/// +/// # Example +/// +/// Creating muliple copies of a string: +/// ```rust +/// #![feature(array_repeat)] +/// +/// use std::array; +/// +/// let string = "Hello there!".to_string(); +/// let strings = array::repeat(string); +/// assert_eq!(strings, ["Hello there!", "Hello there!"]); +/// ``` +#[inline] +#[unstable(feature = "array_repeat", issue = "none")] +pub fn repeat(val: T) -> [T; N] { + match N { + // SAFETY: we know N to be 0 at this point. + 0 => unsafe { transmute_unchecked::<[T; 0], [T; N]>([]) }, + // SAFETY: we know N to be 1 at this point. + 1 => unsafe { transmute_unchecked::<[T; 1], [T; N]>([val]) }, + _ => { + let mut array = MaybeUninit::uninit_array::(); + try_from_fn_erased(&mut array[..N - 1], NeverShortCircuit::wrap_mut_1(|_| val.clone())); + array[N - 1].write(val); + // SAFETY: all elements were initialized. + unsafe { MaybeUninit::array_assume_init(array) } + } + } +} + /// Creates an array of type [T; N], where each element `T` is the returned value from `cb` /// using that element's index. /// -- cgit 1.4.1-3-g733a5 From 39a918002e67e21330ac9103d471dc1701382c31 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 20 Dec 2023 00:14:25 +0100 Subject: core: simplify implementation of `array::repeat`, address other nits --- library/core/src/array/mod.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'library/core/src/array') diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index fdb707bf51d..63b79d5256d 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -10,8 +10,7 @@ use crate::convert::Infallible; use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; -use crate::intrinsics::transmute_unchecked; -use crate::iter::UncheckedIterator; +use crate::iter::{repeat_n, UncheckedIterator}; use crate::mem::{self, MaybeUninit}; use crate::ops::{ ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try, @@ -30,12 +29,16 @@ pub use iter::IntoIter; /// Creates an array of type `[T; N]` by repeatedly cloning a value. /// -/// The value will be used as the last element of the resulting array, so it -/// will be cloned N - 1 times. If N is zero, the value will be dropped. +/// This is the same as `[val; N]`, but it also works for types that do not +/// implement [`Copy`]. +/// +/// The provided value will be used as an element of the resulting array and +/// will be cloned N - 1 times to fill up the rest. If N is zero, the value +/// will be dropped. /// /// # Example /// -/// Creating muliple copies of a string: +/// Creating muliple copies of a `String`: /// ```rust /// #![feature(array_repeat)] /// @@ -48,19 +51,7 @@ pub use iter::IntoIter; #[inline] #[unstable(feature = "array_repeat", issue = "none")] pub fn repeat(val: T) -> [T; N] { - match N { - // SAFETY: we know N to be 0 at this point. - 0 => unsafe { transmute_unchecked::<[T; 0], [T; N]>([]) }, - // SAFETY: we know N to be 1 at this point. - 1 => unsafe { transmute_unchecked::<[T; 1], [T; N]>([val]) }, - _ => { - let mut array = MaybeUninit::uninit_array::(); - try_from_fn_erased(&mut array[..N - 1], NeverShortCircuit::wrap_mut_1(|_| val.clone())); - array[N - 1].write(val); - // SAFETY: all elements were initialized. - unsafe { MaybeUninit::array_assume_init(array) } - } - } + from_trusted_iterator(repeat_n(val, N)) } /// Creates an array of type [T; N], where each element `T` is the returned value from `cb` -- cgit 1.4.1-3-g733a5 From e1aacea74dcdd53095af1618e6466ae8475458ac Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 19 Jun 2024 17:48:00 +0200 Subject: core: add tracking issue for `array::repeat` --- library/core/src/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'library/core/src/array') diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 63b79d5256d..3e4eadbb7c9 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -49,7 +49,7 @@ pub use iter::IntoIter; /// assert_eq!(strings, ["Hello there!", "Hello there!"]); /// ``` #[inline] -#[unstable(feature = "array_repeat", issue = "none")] +#[unstable(feature = "array_repeat", issue = "126695")] pub fn repeat(val: T) -> [T; N] { from_trusted_iterator(repeat_n(val, N)) } -- cgit 1.4.1-3-g733a5