about summary refs log tree commit diff
path: root/library/core/src/array
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2023-12-19 19:30:52 +0100
committerjoboet <jonasboettiger@icloud.com>2024-06-19 17:29:53 +0200
commit3d4f8b1f450e883b18c17bc56a1de575dd06f148 (patch)
tree9731c755ce41aeb9e39faee0eecb6245e4c9d80b /library/core/src/array
parent3186d17d56f9803b739a2c0aabd23aafd8791485 (diff)
downloadrust-3d4f8b1f450e883b18c17bc56a1de575dd06f148.tar.gz
rust-3d4f8b1f450e883b18c17bc56a1de575dd06f148.zip
core: implement `array::repeat`
Diffstat (limited to 'library/core/src/array')
-rw-r--r--library/core/src/array/mod.rs36
1 files changed, 36 insertions, 0 deletions
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<T: Clone, const N: usize>(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::<N>();
+            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.
 ///