|
557 | 557 | #![stable(feature = "rust1", since = "1.0.0")]
|
558 | 558 |
|
559 | 559 | use crate::iter::{self, FusedIterator, TrustedLen};
|
| 560 | +use crate::mem::MaybeUninit; |
560 | 561 | use crate::ops::{self, ControlFlow, Deref, DerefMut};
|
561 | 562 | use crate::panicking::{panic, panic_display};
|
562 | 563 | use crate::pin::Pin;
|
@@ -2545,3 +2546,41 @@ impl<T> Option<Option<T>> {
|
2545 | 2546 | }
|
2546 | 2547 | }
|
2547 | 2548 | }
|
| 2549 | + |
| 2550 | +impl<T, const N: usize> [Option<T>; N] { |
| 2551 | + /// Transposes a `[Option<T>; N]` into a `Option<[T; N]>`. |
| 2552 | + /// |
| 2553 | + /// # Examples |
| 2554 | + /// |
| 2555 | + /// ``` |
| 2556 | + /// #![feature(option_array_transpose)] |
| 2557 | + /// # use std::option::Option; |
| 2558 | + /// |
| 2559 | + /// let data = [Some(0); 1000]; |
| 2560 | + /// let data: Option<[u8; 1000]> = data.transpose(); |
| 2561 | + /// assert_eq!(data, Some([0; 1000])); |
| 2562 | + /// |
| 2563 | + /// let data = [Some(0), None]; |
| 2564 | + /// let data: Option<[u8; 2]> = data.transpose(); |
| 2565 | + /// assert_eq!(data, None); |
| 2566 | + /// ``` |
| 2567 | + #[inline] |
| 2568 | + #[unstable(feature = "option_array_transpose", issue = "130828")] |
| 2569 | + pub fn transpose(self) -> Option<[T; N]> { |
| 2570 | + let mut array: MaybeUninit<[T; N]> = MaybeUninit::uninit(); |
| 2571 | + let array_mut = array.as_mut_ptr(); |
| 2572 | + |
| 2573 | + for (i, e) in self.into_iter().enumerate() { |
| 2574 | + match e { |
| 2575 | + // SAFETY: `i` is always inbounds |
| 2576 | + Some(e) => unsafe { |
| 2577 | + *(*array_mut).get_unchecked_mut(i) = e; |
| 2578 | + }, |
| 2579 | + None => return None, |
| 2580 | + } |
| 2581 | + } |
| 2582 | + |
| 2583 | + // SAFETY: All the elements have been initialized |
| 2584 | + Some(unsafe { array.assume_init() }) |
| 2585 | + } |
| 2586 | +} |
0 commit comments