Skip to content

Commit

Permalink
Add [Option<T>; N]::transpose
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Sep 25, 2024
1 parent 702987f commit 2c7a4ba
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use crate::iter::{self, FusedIterator, TrustedLen};
use crate::mem::MaybeUninit;
use crate::ops::{self, ControlFlow, Deref, DerefMut};
use crate::panicking::{panic, panic_display};
use crate::pin::Pin;
Expand Down Expand Up @@ -2545,3 +2546,41 @@ impl<T> Option<Option<T>> {
}
}
}

impl<T, const N: usize> [Option<T>; N] {
/// Transposes a `[Option<T>; N]` into a `Option<[T; N]>`.
///
/// # Examples
///
/// ```
/// #![feature(option_array_transpose)]
/// # use std::option::Option;
///
/// let data = [Some(0); 1000];
/// let data: Option<[u8; 1000]> = data.transpose();
/// assert_eq!(data, Some([0; 1000]));
///
/// let data = [Some(0), None];
/// let data: Option<[u8; 2]> = data.transpose();
/// assert_eq!(data, None);
/// ```
#[inline]
#[unstable(feature = "option_array_transpose", issue = "130828")]
pub fn transpose(self) -> Option<[T; N]> {
let mut array: MaybeUninit<[T; N]> = MaybeUninit::uninit();
let array_mut = array.as_mut_ptr();

for (i, e) in self.into_iter().enumerate() {
match e {
// SAFETY: `i` is always inbounds
Some(e) => unsafe {
*(*array_mut).get_unchecked_mut(i) = e;
},
None => return None,
}
}

// SAFETY: All the elements have been initialized
Some(unsafe { array.assume_init() })
}
}

0 comments on commit 2c7a4ba

Please sign in to comment.