core/array/
mod.rs

1//! Utilities for the array primitive type.
2//!
3//! *[See also the array primitive type](array).*
4
5#![stable(feature = "core_array", since = "1.35.0")]
6
7use crate::borrow::{Borrow, BorrowMut};
8use crate::cmp::Ordering;
9use crate::convert::Infallible;
10use crate::error::Error;
11use crate::fmt;
12use crate::hash::{self, Hash};
13use crate::intrinsics::transmute_unchecked;
14use crate::iter::{UncheckedIterator, repeat_n};
15use crate::mem::{self, MaybeUninit};
16use crate::ops::{
17    ChangeOutputType, ControlFlow, FromResidual, Index, IndexMut, NeverShortCircuit, Residual, Try,
18};
19use crate::ptr::{null, null_mut};
20use crate::slice::{Iter, IterMut};
21
22mod ascii;
23mod drain;
24mod equality;
25mod iter;
26
27pub(crate) use drain::drain_array_with;
28#[stable(feature = "array_value_iter", since = "1.51.0")]
29pub use iter::IntoIter;
30
31/// Creates an array of type `[T; N]` by repeatedly cloning a value.
32///
33/// This is the same as `[val; N]`, but it also works for types that do not
34/// implement [`Copy`].
35///
36/// The provided value will be used as an element of the resulting array and
37/// will be cloned N - 1 times to fill up the rest. If N is zero, the value
38/// will be dropped.
39///
40/// # Example
41///
42/// Creating multiple copies of a `String`:
43/// ```rust
44/// #![feature(array_repeat)]
45///
46/// use std::array;
47///
48/// let string = "Hello there!".to_string();
49/// let strings = array::repeat(string);
50/// assert_eq!(strings, ["Hello there!", "Hello there!"]);
51/// ```
52#[inline]
53#[unstable(feature = "array_repeat", issue = "126695")]
54pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
55    from_trusted_iterator(repeat_n(val, N))
56}
57
58/// Creates an array where each element is produced by calling `f` with
59/// that element's index while walking forward through the array.
60///
61/// This is essentially the same as writing
62/// ```text
63/// [f(0), f(1), f(2), …, f(N - 2), f(N - 1)]
64/// ```
65/// and is similar to `(0..i).map(f)`, just for arrays not iterators.
66///
67/// If `N == 0`, this produces an empty array without ever calling `f`.
68///
69/// # Example
70///
71/// ```rust
72/// // type inference is helping us here, the way `from_fn` knows how many
73/// // elements to produce is the length of array down there: only arrays of
74/// // equal lengths can be compared, so the const generic parameter `N` is
75/// // inferred to be 5, thus creating array of 5 elements.
76///
77/// let array = core::array::from_fn(|i| i);
78/// // indexes are:    0  1  2  3  4
79/// assert_eq!(array, [0, 1, 2, 3, 4]);
80///
81/// let array2: [usize; 8] = core::array::from_fn(|i| i * 2);
82/// // indexes are:     0  1  2  3  4  5   6   7
83/// assert_eq!(array2, [0, 2, 4, 6, 8, 10, 12, 14]);
84///
85/// let bool_arr = core::array::from_fn::<_, 5, _>(|i| i % 2 == 0);
86/// // indexes are:       0     1      2     3      4
87/// assert_eq!(bool_arr, [true, false, true, false, true]);
88/// ```
89///
90/// You can also capture things, for example to create an array full of clones
91/// where you can't just use `[item; N]` because it's not `Copy`:
92/// ```
93/// # // TBH `array::repeat` would be better for this, but it's not stable yet.
94/// let my_string = String::from("Hello");
95/// let clones: [String; 42] = std::array::from_fn(|_| my_string.clone());
96/// assert!(clones.iter().all(|x| *x == my_string));
97/// ```
98///
99/// The array is generated in ascending index order, starting from the front
100/// and going towards the back, so you can use closures with mutable state:
101/// ```
102/// let mut state = 1;
103/// let a = std::array::from_fn(|_| { let x = state; state *= 2; x });
104/// assert_eq!(a, [1, 2, 4, 8, 16, 32]);
105/// ```
106#[inline]
107#[stable(feature = "array_from_fn", since = "1.63.0")]
108pub fn from_fn<T, const N: usize, F>(f: F) -> [T; N]
109where
110    F: FnMut(usize) -> T,
111{
112    try_from_fn(NeverShortCircuit::wrap_mut_1(f)).0
113}
114
115/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
116/// Unlike [`from_fn`], where the element creation can't fail, this version will return an error
117/// if any element creation was unsuccessful.
118///
119/// The return type of this function depends on the return type of the closure.
120/// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N], E>`.
121/// If you return `Option<T>` from the closure, you'll get an `Option<[T; N]>`.
122///
123/// # Arguments
124///
125/// * `cb`: Callback where the passed argument is the current array index.
126///
127/// # Example
128///
129/// ```rust
130/// #![feature(array_try_from_fn)]
131///
132/// let array: Result<[u8; 5], _> = std::array::try_from_fn(|i| i.try_into());
133/// assert_eq!(array, Ok([0, 1, 2, 3, 4]));
134///
135/// let array: Result<[i8; 200], _> = std::array::try_from_fn(|i| i.try_into());
136/// assert!(array.is_err());
137///
138/// let array: Option<[_; 4]> = std::array::try_from_fn(|i| i.checked_add(100));
139/// assert_eq!(array, Some([100, 101, 102, 103]));
140///
141/// let array: Option<[_; 4]> = std::array::try_from_fn(|i| i.checked_sub(100));
142/// assert_eq!(array, None);
143/// ```
144#[inline]
145#[unstable(feature = "array_try_from_fn", issue = "89379")]
146pub fn try_from_fn<R, const N: usize, F>(cb: F) -> ChangeOutputType<R, [R::Output; N]>
147where
148    F: FnMut(usize) -> R,
149    R: Try,
150    R::Residual: Residual<[R::Output; N]>,
151{
152    let mut array = [const { MaybeUninit::uninit() }; N];
153    match try_from_fn_erased(&mut array, cb) {
154        ControlFlow::Break(r) => FromResidual::from_residual(r),
155        ControlFlow::Continue(()) => {
156            // SAFETY: All elements of the array were populated.
157            try { unsafe { MaybeUninit::array_assume_init(array) } }
158        }
159    }
160}
161
162/// Converts a reference to `T` into a reference to an array of length 1 (without copying).
163#[stable(feature = "array_from_ref", since = "1.53.0")]
164#[rustc_const_stable(feature = "const_array_from_ref_shared", since = "1.63.0")]
165pub const fn from_ref<T>(s: &T) -> &[T; 1] {
166    // SAFETY: Converting `&T` to `&[T; 1]` is sound.
167    unsafe { &*(s as *const T).cast::<[T; 1]>() }
168}
169
170/// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying).
171#[stable(feature = "array_from_ref", since = "1.53.0")]
172#[rustc_const_stable(feature = "const_array_from_ref", since = "1.83.0")]
173pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
174    // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound.
175    unsafe { &mut *(s as *mut T).cast::<[T; 1]>() }
176}
177
178/// The error type returned when a conversion from a slice to an array fails.
179#[stable(feature = "try_from", since = "1.34.0")]
180#[derive(Debug, Copy, Clone)]
181pub struct TryFromSliceError(());
182
183#[stable(feature = "core_array", since = "1.35.0")]
184impl fmt::Display for TryFromSliceError {
185    #[inline]
186    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187        #[allow(deprecated)]
188        self.description().fmt(f)
189    }
190}
191
192#[stable(feature = "try_from", since = "1.34.0")]
193impl Error for TryFromSliceError {
194    #[allow(deprecated)]
195    fn description(&self) -> &str {
196        "could not convert slice to array"
197    }
198}
199
200#[stable(feature = "try_from_slice_error", since = "1.36.0")]
201impl From<Infallible> for TryFromSliceError {
202    fn from(x: Infallible) -> TryFromSliceError {
203        match x {}
204    }
205}
206
207#[stable(feature = "rust1", since = "1.0.0")]
208impl<T, const N: usize> AsRef<[T]> for [T; N] {
209    #[inline]
210    fn as_ref(&self) -> &[T] {
211        &self[..]
212    }
213}
214
215#[stable(feature = "rust1", since = "1.0.0")]
216impl<T, const N: usize> AsMut<[T]> for [T; N] {
217    #[inline]
218    fn as_mut(&mut self) -> &mut [T] {
219        &mut self[..]
220    }
221}
222
223#[stable(feature = "array_borrow", since = "1.4.0")]
224impl<T, const N: usize> Borrow<[T]> for [T; N] {
225    fn borrow(&self) -> &[T] {
226        self
227    }
228}
229
230#[stable(feature = "array_borrow", since = "1.4.0")]
231impl<T, const N: usize> BorrowMut<[T]> for [T; N] {
232    fn borrow_mut(&mut self) -> &mut [T] {
233        self
234    }
235}
236
237/// Tries to create an array `[T; N]` by copying from a slice `&[T]`.
238/// Succeeds if `slice.len() == N`.
239///
240/// ```
241/// let bytes: [u8; 3] = [1, 0, 2];
242///
243/// let bytes_head: [u8; 2] = <[u8; 2]>::try_from(&bytes[0..2]).unwrap();
244/// assert_eq!(1, u16::from_le_bytes(bytes_head));
245///
246/// let bytes_tail: [u8; 2] = bytes[1..3].try_into().unwrap();
247/// assert_eq!(512, u16::from_le_bytes(bytes_tail));
248/// ```
249#[stable(feature = "try_from", since = "1.34.0")]
250impl<T, const N: usize> TryFrom<&[T]> for [T; N]
251where
252    T: Copy,
253{
254    type Error = TryFromSliceError;
255
256    #[inline]
257    fn try_from(slice: &[T]) -> Result<[T; N], TryFromSliceError> {
258        <&Self>::try_from(slice).copied()
259    }
260}
261
262/// Tries to create an array `[T; N]` by copying from a mutable slice `&mut [T]`.
263/// Succeeds if `slice.len() == N`.
264///
265/// ```
266/// let mut bytes: [u8; 3] = [1, 0, 2];
267///
268/// let bytes_head: [u8; 2] = <[u8; 2]>::try_from(&mut bytes[0..2]).unwrap();
269/// assert_eq!(1, u16::from_le_bytes(bytes_head));
270///
271/// let bytes_tail: [u8; 2] = (&mut bytes[1..3]).try_into().unwrap();
272/// assert_eq!(512, u16::from_le_bytes(bytes_tail));
273/// ```
274#[stable(feature = "try_from_mut_slice_to_array", since = "1.59.0")]
275impl<T, const N: usize> TryFrom<&mut [T]> for [T; N]
276where
277    T: Copy,
278{
279    type Error = TryFromSliceError;
280
281    #[inline]
282    fn try_from(slice: &mut [T]) -> Result<[T; N], TryFromSliceError> {
283        <Self>::try_from(&*slice)
284    }
285}
286
287/// Tries to create an array ref `&[T; N]` from a slice ref `&[T]`. Succeeds if
288/// `slice.len() == N`.
289///
290/// ```
291/// let bytes: [u8; 3] = [1, 0, 2];
292///
293/// let bytes_head: &[u8; 2] = <&[u8; 2]>::try_from(&bytes[0..2]).unwrap();
294/// assert_eq!(1, u16::from_le_bytes(*bytes_head));
295///
296/// let bytes_tail: &[u8; 2] = bytes[1..3].try_into().unwrap();
297/// assert_eq!(512, u16::from_le_bytes(*bytes_tail));
298/// ```
299#[stable(feature = "try_from", since = "1.34.0")]
300impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
301    type Error = TryFromSliceError;
302
303    #[inline]
304    fn try_from(slice: &'a [T]) -> Result<&'a [T; N], TryFromSliceError> {
305        slice.as_array().ok_or(TryFromSliceError(()))
306    }
307}
308
309/// Tries to create a mutable array ref `&mut [T; N]` from a mutable slice ref
310/// `&mut [T]`. Succeeds if `slice.len() == N`.
311///
312/// ```
313/// let mut bytes: [u8; 3] = [1, 0, 2];
314///
315/// let bytes_head: &mut [u8; 2] = <&mut [u8; 2]>::try_from(&mut bytes[0..2]).unwrap();
316/// assert_eq!(1, u16::from_le_bytes(*bytes_head));
317///
318/// let bytes_tail: &mut [u8; 2] = (&mut bytes[1..3]).try_into().unwrap();
319/// assert_eq!(512, u16::from_le_bytes(*bytes_tail));
320/// ```
321#[stable(feature = "try_from", since = "1.34.0")]
322impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N] {
323    type Error = TryFromSliceError;
324
325    #[inline]
326    fn try_from(slice: &'a mut [T]) -> Result<&'a mut [T; N], TryFromSliceError> {
327        slice.as_mut_array().ok_or(TryFromSliceError(()))
328    }
329}
330
331/// The hash of an array is the same as that of the corresponding slice,
332/// as required by the `Borrow` implementation.
333///
334/// ```
335/// use std::hash::BuildHasher;
336///
337/// let b = std::hash::RandomState::new();
338/// let a: [u8; 3] = [0xa8, 0x3c, 0x09];
339/// let s: &[u8] = &[0xa8, 0x3c, 0x09];
340/// assert_eq!(b.hash_one(a), b.hash_one(s));
341/// ```
342#[stable(feature = "rust1", since = "1.0.0")]
343impl<T: Hash, const N: usize> Hash for [T; N] {
344    fn hash<H: hash::Hasher>(&self, state: &mut H) {
345        Hash::hash(&self[..], state)
346    }
347}
348
349#[stable(feature = "rust1", since = "1.0.0")]
350impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N] {
351    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352        fmt::Debug::fmt(&&self[..], f)
353    }
354}
355
356#[stable(feature = "rust1", since = "1.0.0")]
357impl<'a, T, const N: usize> IntoIterator for &'a [T; N] {
358    type Item = &'a T;
359    type IntoIter = Iter<'a, T>;
360
361    fn into_iter(self) -> Iter<'a, T> {
362        self.iter()
363    }
364}
365
366#[stable(feature = "rust1", since = "1.0.0")]
367impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
368    type Item = &'a mut T;
369    type IntoIter = IterMut<'a, T>;
370
371    fn into_iter(self) -> IterMut<'a, T> {
372        self.iter_mut()
373    }
374}
375
376#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
377impl<T, I, const N: usize> Index<I> for [T; N]
378where
379    [T]: Index<I>,
380{
381    type Output = <[T] as Index<I>>::Output;
382
383    #[inline]
384    fn index(&self, index: I) -> &Self::Output {
385        Index::index(self as &[T], index)
386    }
387}
388
389#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
390impl<T, I, const N: usize> IndexMut<I> for [T; N]
391where
392    [T]: IndexMut<I>,
393{
394    #[inline]
395    fn index_mut(&mut self, index: I) -> &mut Self::Output {
396        IndexMut::index_mut(self as &mut [T], index)
397    }
398}
399
400/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
401#[stable(feature = "rust1", since = "1.0.0")]
402impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] {
403    #[inline]
404    fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
405        PartialOrd::partial_cmp(&&self[..], &&other[..])
406    }
407    #[inline]
408    fn lt(&self, other: &[T; N]) -> bool {
409        PartialOrd::lt(&&self[..], &&other[..])
410    }
411    #[inline]
412    fn le(&self, other: &[T; N]) -> bool {
413        PartialOrd::le(&&self[..], &&other[..])
414    }
415    #[inline]
416    fn ge(&self, other: &[T; N]) -> bool {
417        PartialOrd::ge(&&self[..], &&other[..])
418    }
419    #[inline]
420    fn gt(&self, other: &[T; N]) -> bool {
421        PartialOrd::gt(&&self[..], &&other[..])
422    }
423}
424
425/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
426#[stable(feature = "rust1", since = "1.0.0")]
427impl<T: Ord, const N: usize> Ord for [T; N] {
428    #[inline]
429    fn cmp(&self, other: &[T; N]) -> Ordering {
430        Ord::cmp(&&self[..], &&other[..])
431    }
432}
433
434#[stable(feature = "copy_clone_array_lib", since = "1.58.0")]
435impl<T: Copy, const N: usize> Copy for [T; N] {}
436
437#[stable(feature = "copy_clone_array_lib", since = "1.58.0")]
438impl<T: Clone, const N: usize> Clone for [T; N] {
439    #[inline]
440    fn clone(&self) -> Self {
441        SpecArrayClone::clone(self)
442    }
443
444    #[inline]
445    fn clone_from(&mut self, other: &Self) {
446        self.clone_from_slice(other);
447    }
448}
449
450trait SpecArrayClone: Clone {
451    fn clone<const N: usize>(array: &[Self; N]) -> [Self; N];
452}
453
454impl<T: Clone> SpecArrayClone for T {
455    #[inline]
456    default fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
457        from_trusted_iterator(array.iter().cloned())
458    }
459}
460
461impl<T: Copy> SpecArrayClone for T {
462    #[inline]
463    fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
464        *array
465    }
466}
467
468// The Default impls cannot be done with const generics because `[T; 0]` doesn't
469// require Default to be implemented, and having different impl blocks for
470// different numbers isn't supported yet.
471
472macro_rules! array_impl_default {
473    {$n:expr, $t:ident $($ts:ident)*} => {
474        #[stable(since = "1.4.0", feature = "array_default")]
475        impl<T> Default for [T; $n] where T: Default {
476            fn default() -> [T; $n] {
477                [$t::default(), $($ts::default()),*]
478            }
479        }
480        array_impl_default!{($n - 1), $($ts)*}
481    };
482    {$n:expr,} => {
483        #[stable(since = "1.4.0", feature = "array_default")]
484        impl<T> Default for [T; $n] {
485            fn default() -> [T; $n] { [] }
486        }
487    };
488}
489
490array_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}
491
492impl<T, const N: usize> [T; N] {
493    /// Returns an array of the same size as `self`, with function `f` applied to each element
494    /// in order.
495    ///
496    /// If you don't necessarily need a new fixed-size array, consider using
497    /// [`Iterator::map`] instead.
498    ///
499    ///
500    /// # Note on performance and stack usage
501    ///
502    /// Unfortunately, usages of this method are currently not always optimized
503    /// as well as they could be. This mainly concerns large arrays, as mapping
504    /// over small arrays seem to be optimized just fine. Also note that in
505    /// debug mode (i.e. without any optimizations), this method can use a lot
506    /// of stack space (a few times the size of the array or more).
507    ///
508    /// Therefore, in performance-critical code, try to avoid using this method
509    /// on large arrays or check the emitted code. Also try to avoid chained
510    /// maps (e.g. `arr.map(...).map(...)`).
511    ///
512    /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
513    /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
514    /// really need a new array of the same size as the result. Rust's lazy
515    /// iterators tend to get optimized very well.
516    ///
517    ///
518    /// # Examples
519    ///
520    /// ```
521    /// let x = [1, 2, 3];
522    /// let y = x.map(|v| v + 1);
523    /// assert_eq!(y, [2, 3, 4]);
524    ///
525    /// let x = [1, 2, 3];
526    /// let mut temp = 0;
527    /// let y = x.map(|v| { temp += 1; v * temp });
528    /// assert_eq!(y, [1, 4, 9]);
529    ///
530    /// let x = ["Ferris", "Bueller's", "Day", "Off"];
531    /// let y = x.map(|v| v.len());
532    /// assert_eq!(y, [6, 9, 3, 3]);
533    /// ```
534    #[stable(feature = "array_map", since = "1.55.0")]
535    pub fn map<F, U>(self, f: F) -> [U; N]
536    where
537        F: FnMut(T) -> U,
538    {
539        self.try_map(NeverShortCircuit::wrap_mut_1(f)).0
540    }
541
542    /// A fallible function `f` applied to each element on array `self` in order to
543    /// return an array the same size as `self` or the first error encountered.
544    ///
545    /// The return type of this function depends on the return type of the closure.
546    /// If you return `Result<T, E>` from the closure, you'll get a `Result<[T; N], E>`.
547    /// If you return `Option<T>` from the closure, you'll get an `Option<[T; N]>`.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// #![feature(array_try_map)]
553    ///
554    /// let a = ["1", "2", "3"];
555    /// let b = a.try_map(|v| v.parse::<u32>()).unwrap().map(|v| v + 1);
556    /// assert_eq!(b, [2, 3, 4]);
557    ///
558    /// let a = ["1", "2a", "3"];
559    /// let b = a.try_map(|v| v.parse::<u32>());
560    /// assert!(b.is_err());
561    ///
562    /// use std::num::NonZero;
563    ///
564    /// let z = [1, 2, 0, 3, 4];
565    /// assert_eq!(z.try_map(NonZero::new), None);
566    ///
567    /// let a = [1, 2, 3];
568    /// let b = a.try_map(NonZero::new);
569    /// let c = b.map(|x| x.map(NonZero::get));
570    /// assert_eq!(c, Some(a));
571    /// ```
572    #[unstable(feature = "array_try_map", issue = "79711")]
573    pub fn try_map<R>(self, f: impl FnMut(T) -> R) -> ChangeOutputType<R, [R::Output; N]>
574    where
575        R: Try<Residual: Residual<[R::Output; N]>>,
576    {
577        drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
578    }
579
580    /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
581    #[stable(feature = "array_as_slice", since = "1.57.0")]
582    #[rustc_const_stable(feature = "array_as_slice", since = "1.57.0")]
583    pub const fn as_slice(&self) -> &[T] {
584        self
585    }
586
587    /// Returns a mutable slice containing the entire array. Equivalent to
588    /// `&mut s[..]`.
589    #[stable(feature = "array_as_slice", since = "1.57.0")]
590    #[rustc_const_unstable(feature = "const_array_as_mut_slice", issue = "133333")]
591    pub const fn as_mut_slice(&mut self) -> &mut [T] {
592        self
593    }
594
595    /// Borrows each element and returns an array of references with the same
596    /// size as `self`.
597    ///
598    ///
599    /// # Example
600    ///
601    /// ```
602    /// let floats = [3.1, 2.7, -1.0];
603    /// let float_refs: [&f64; 3] = floats.each_ref();
604    /// assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
605    /// ```
606    ///
607    /// This method is particularly useful if combined with other methods, like
608    /// [`map`](#method.map). This way, you can avoid moving the original
609    /// array if its elements are not [`Copy`].
610    ///
611    /// ```
612    /// let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
613    /// let is_ascii = strings.each_ref().map(|s| s.is_ascii());
614    /// assert_eq!(is_ascii, [true, false, true]);
615    ///
616    /// // We can still access the original array: it has not been moved.
617    /// assert_eq!(strings.len(), 3);
618    /// ```
619    #[stable(feature = "array_methods", since = "1.77.0")]
620    #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
621    pub const fn each_ref(&self) -> [&T; N] {
622        let mut buf = [null::<T>(); N];
623
624        // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
625        let mut i = 0;
626        while i < N {
627            buf[i] = &raw const self[i];
628
629            i += 1;
630        }
631
632        // SAFETY: `*const T` has the same layout as `&T`, and we've also initialised each pointer as a valid reference.
633        unsafe { transmute_unchecked(buf) }
634    }
635
636    /// Borrows each element mutably and returns an array of mutable references
637    /// with the same size as `self`.
638    ///
639    ///
640    /// # Example
641    ///
642    /// ```
643    ///
644    /// let mut floats = [3.1, 2.7, -1.0];
645    /// let float_refs: [&mut f64; 3] = floats.each_mut();
646    /// *float_refs[0] = 0.0;
647    /// assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
648    /// assert_eq!(floats, [0.0, 2.7, -1.0]);
649    /// ```
650    #[stable(feature = "array_methods", since = "1.77.0")]
651    #[rustc_const_unstable(feature = "const_array_each_ref", issue = "133289")]
652    pub const fn each_mut(&mut self) -> [&mut T; N] {
653        let mut buf = [null_mut::<T>(); N];
654
655        // FIXME(const-hack): We would like to simply use iterators for this (as in the original implementation), but this is not allowed in constant expressions.
656        let mut i = 0;
657        while i < N {
658            buf[i] = &raw mut self[i];
659
660            i += 1;
661        }
662
663        // SAFETY: `*mut T` has the same layout as `&mut T`, and we've also initialised each pointer as a valid reference.
664        unsafe { transmute_unchecked(buf) }
665    }
666
667    /// Divides one array reference into two at an index.
668    ///
669    /// The first will contain all indices from `[0, M)` (excluding
670    /// the index `M` itself) and the second will contain all
671    /// indices from `[M, N)` (excluding the index `N` itself).
672    ///
673    /// # Panics
674    ///
675    /// Panics if `M > N`.
676    ///
677    /// # Examples
678    ///
679    /// ```
680    /// #![feature(split_array)]
681    ///
682    /// let v = [1, 2, 3, 4, 5, 6];
683    ///
684    /// {
685    ///    let (left, right) = v.split_array_ref::<0>();
686    ///    assert_eq!(left, &[]);
687    ///    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
688    /// }
689    ///
690    /// {
691    ///     let (left, right) = v.split_array_ref::<2>();
692    ///     assert_eq!(left, &[1, 2]);
693    ///     assert_eq!(right, &[3, 4, 5, 6]);
694    /// }
695    ///
696    /// {
697    ///     let (left, right) = v.split_array_ref::<6>();
698    ///     assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
699    ///     assert_eq!(right, &[]);
700    /// }
701    /// ```
702    #[unstable(
703        feature = "split_array",
704        reason = "return type should have array as 2nd element",
705        issue = "90091"
706    )]
707    #[inline]
708    pub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T]) {
709        (&self[..]).split_first_chunk::<M>().unwrap()
710    }
711
712    /// Divides one mutable array reference into two at an index.
713    ///
714    /// The first will contain all indices from `[0, M)` (excluding
715    /// the index `M` itself) and the second will contain all
716    /// indices from `[M, N)` (excluding the index `N` itself).
717    ///
718    /// # Panics
719    ///
720    /// Panics if `M > N`.
721    ///
722    /// # Examples
723    ///
724    /// ```
725    /// #![feature(split_array)]
726    ///
727    /// let mut v = [1, 0, 3, 0, 5, 6];
728    /// let (left, right) = v.split_array_mut::<2>();
729    /// assert_eq!(left, &mut [1, 0][..]);
730    /// assert_eq!(right, &mut [3, 0, 5, 6]);
731    /// left[1] = 2;
732    /// right[1] = 4;
733    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
734    /// ```
735    #[unstable(
736        feature = "split_array",
737        reason = "return type should have array as 2nd element",
738        issue = "90091"
739    )]
740    #[inline]
741    pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
742        (&mut self[..]).split_first_chunk_mut::<M>().unwrap()
743    }
744
745    /// Divides one array reference into two at an index from the end.
746    ///
747    /// The first will contain all indices from `[0, N - M)` (excluding
748    /// the index `N - M` itself) and the second will contain all
749    /// indices from `[N - M, N)` (excluding the index `N` itself).
750    ///
751    /// # Panics
752    ///
753    /// Panics if `M > N`.
754    ///
755    /// # Examples
756    ///
757    /// ```
758    /// #![feature(split_array)]
759    ///
760    /// let v = [1, 2, 3, 4, 5, 6];
761    ///
762    /// {
763    ///    let (left, right) = v.rsplit_array_ref::<0>();
764    ///    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
765    ///    assert_eq!(right, &[]);
766    /// }
767    ///
768    /// {
769    ///     let (left, right) = v.rsplit_array_ref::<2>();
770    ///     assert_eq!(left, &[1, 2, 3, 4]);
771    ///     assert_eq!(right, &[5, 6]);
772    /// }
773    ///
774    /// {
775    ///     let (left, right) = v.rsplit_array_ref::<6>();
776    ///     assert_eq!(left, &[]);
777    ///     assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
778    /// }
779    /// ```
780    #[unstable(
781        feature = "split_array",
782        reason = "return type should have array as 2nd element",
783        issue = "90091"
784    )]
785    #[inline]
786    pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M]) {
787        (&self[..]).split_last_chunk::<M>().unwrap()
788    }
789
790    /// Divides one mutable array reference into two at an index from the end.
791    ///
792    /// The first will contain all indices from `[0, N - M)` (excluding
793    /// the index `N - M` itself) and the second will contain all
794    /// indices from `[N - M, N)` (excluding the index `N` itself).
795    ///
796    /// # Panics
797    ///
798    /// Panics if `M > N`.
799    ///
800    /// # Examples
801    ///
802    /// ```
803    /// #![feature(split_array)]
804    ///
805    /// let mut v = [1, 0, 3, 0, 5, 6];
806    /// let (left, right) = v.rsplit_array_mut::<4>();
807    /// assert_eq!(left, &mut [1, 0]);
808    /// assert_eq!(right, &mut [3, 0, 5, 6][..]);
809    /// left[1] = 2;
810    /// right[1] = 4;
811    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
812    /// ```
813    #[unstable(
814        feature = "split_array",
815        reason = "return type should have array as 2nd element",
816        issue = "90091"
817    )]
818    #[inline]
819    pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M]) {
820        (&mut self[..]).split_last_chunk_mut::<M>().unwrap()
821    }
822}
823
824/// Populate an array from the first `N` elements of `iter`
825///
826/// # Panics
827///
828/// If the iterator doesn't actually have enough items.
829///
830/// By depending on `TrustedLen`, however, we can do that check up-front (where
831/// it easily optimizes away) so it doesn't impact the loop that fills the array.
832#[inline]
833fn from_trusted_iterator<T, const N: usize>(iter: impl UncheckedIterator<Item = T>) -> [T; N] {
834    try_from_trusted_iterator(iter.map(NeverShortCircuit)).0
835}
836
837#[inline]
838fn try_from_trusted_iterator<T, R, const N: usize>(
839    iter: impl UncheckedIterator<Item = R>,
840) -> ChangeOutputType<R, [T; N]>
841where
842    R: Try<Output = T>,
843    R::Residual: Residual<[T; N]>,
844{
845    assert!(iter.size_hint().0 >= N);
846    fn next<T>(mut iter: impl UncheckedIterator<Item = T>) -> impl FnMut(usize) -> T {
847        move |_| {
848            // SAFETY: We know that `from_fn` will call this at most N times,
849            // and we checked to ensure that we have at least that many items.
850            unsafe { iter.next_unchecked() }
851        }
852    }
853
854    try_from_fn(next(iter))
855}
856
857/// Version of [`try_from_fn`] using a passed-in slice in order to avoid
858/// needing to monomorphize for every array length.
859///
860/// This takes a generator rather than an iterator so that *at the type level*
861/// it never needs to worry about running out of items.  When combined with
862/// an infallible `Try` type, that means the loop canonicalizes easily, allowing
863/// it to optimize well.
864///
865/// It would be *possible* to unify this and [`iter_next_chunk_erased`] into one
866/// function that does the union of both things, but last time it was that way
867/// it resulted in poor codegen from the "are there enough source items?" checks
868/// not optimizing away.  So if you give it a shot, make sure to watch what
869/// happens in the codegen tests.
870#[inline]
871fn try_from_fn_erased<T, R>(
872    buffer: &mut [MaybeUninit<T>],
873    mut generator: impl FnMut(usize) -> R,
874) -> ControlFlow<R::Residual>
875where
876    R: Try<Output = T>,
877{
878    let mut guard = Guard { array_mut: buffer, initialized: 0 };
879
880    while guard.initialized < guard.array_mut.len() {
881        let item = generator(guard.initialized).branch()?;
882
883        // SAFETY: The loop condition ensures we have space to push the item
884        unsafe { guard.push_unchecked(item) };
885    }
886
887    mem::forget(guard);
888    ControlFlow::Continue(())
889}
890
891/// Panic guard for incremental initialization of arrays.
892///
893/// Disarm the guard with `mem::forget` once the array has been initialized.
894///
895/// # Safety
896///
897/// All write accesses to this structure are unsafe and must maintain a correct
898/// count of `initialized` elements.
899///
900/// To minimize indirection fields are still pub but callers should at least use
901/// `push_unchecked` to signal that something unsafe is going on.
902struct Guard<'a, T> {
903    /// The array to be initialized.
904    pub array_mut: &'a mut [MaybeUninit<T>],
905    /// The number of items that have been initialized so far.
906    pub initialized: usize,
907}
908
909impl<T> Guard<'_, T> {
910    /// Adds an item to the array and updates the initialized item counter.
911    ///
912    /// # Safety
913    ///
914    /// No more than N elements must be initialized.
915    #[inline]
916    pub(crate) unsafe fn push_unchecked(&mut self, item: T) {
917        // SAFETY: If `initialized` was correct before and the caller does not
918        // invoke this method more than N times then writes will be in-bounds
919        // and slots will not be initialized more than once.
920        unsafe {
921            self.array_mut.get_unchecked_mut(self.initialized).write(item);
922            self.initialized = self.initialized.unchecked_add(1);
923        }
924    }
925}
926
927impl<T> Drop for Guard<'_, T> {
928    #[inline]
929    fn drop(&mut self) {
930        debug_assert!(self.initialized <= self.array_mut.len());
931
932        // SAFETY: this slice will contain only initialized objects.
933        unsafe {
934            self.array_mut.get_unchecked_mut(..self.initialized).assume_init_drop();
935        }
936    }
937}
938
939/// Pulls `N` items from `iter` and returns them as an array. If the iterator
940/// yields fewer than `N` items, `Err` is returned containing an iterator over
941/// the already yielded items.
942///
943/// Since the iterator is passed as a mutable reference and this function calls
944/// `next` at most `N` times, the iterator can still be used afterwards to
945/// retrieve the remaining items.
946///
947/// If `iter.next()` panicks, all items already yielded by the iterator are
948/// dropped.
949///
950/// Used for [`Iterator::next_chunk`].
951#[inline]
952pub(crate) fn iter_next_chunk<T, const N: usize>(
953    iter: &mut impl Iterator<Item = T>,
954) -> Result<[T; N], IntoIter<T, N>> {
955    let mut array = [const { MaybeUninit::uninit() }; N];
956    let r = iter_next_chunk_erased(&mut array, iter);
957    match r {
958        Ok(()) => {
959            // SAFETY: All elements of `array` were populated.
960            Ok(unsafe { MaybeUninit::array_assume_init(array) })
961        }
962        Err(initialized) => {
963            // SAFETY: Only the first `initialized` elements were populated
964            Err(unsafe { IntoIter::new_unchecked(array, 0..initialized) })
965        }
966    }
967}
968
969/// Version of [`iter_next_chunk`] using a passed-in slice in order to avoid
970/// needing to monomorphize for every array length.
971///
972/// Unfortunately this loop has two exit conditions, the buffer filling up
973/// or the iterator running out of items, making it tend to optimize poorly.
974#[inline]
975fn iter_next_chunk_erased<T>(
976    buffer: &mut [MaybeUninit<T>],
977    iter: &mut impl Iterator<Item = T>,
978) -> Result<(), usize> {
979    let mut guard = Guard { array_mut: buffer, initialized: 0 };
980    while guard.initialized < guard.array_mut.len() {
981        let Some(item) = iter.next() else {
982            // Unlike `try_from_fn_erased`, we want to keep the partial results,
983            // so we need to defuse the guard instead of using `?`.
984            let initialized = guard.initialized;
985            mem::forget(guard);
986            return Err(initialized);
987        };
988
989        // SAFETY: The loop condition ensures we have space to push the item
990        unsafe { guard.push_unchecked(item) };
991    }
992
993    mem::forget(guard);
994    Ok(())
995}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy