|
55 | 55 | #![stable(feature = "rust1", since = "1.0.0")]
|
56 | 56 |
|
57 | 57 | use core::cmp::{self, Ordering};
|
| 58 | +use core::convert::TryFrom; |
58 | 59 | use core::fmt;
|
59 | 60 | use core::hash::{Hash, Hasher};
|
60 | 61 | use core::intrinsics::{arith_offset, assume};
|
@@ -2771,6 +2772,57 @@ impl From<&str> for Vec<u8> {
|
2771 | 2772 | }
|
2772 | 2773 | }
|
2773 | 2774 |
|
| 2775 | +#[stable(feature = "array_try_from_vec", since = "1.47.0")] |
| 2776 | +impl<T, const N: usize> TryFrom<Vec<T>> for [T; N] { |
| 2777 | + type Error = Vec<T>; |
| 2778 | + |
| 2779 | + /// Gets the entire contents of the `Vec<T>` as an array, |
| 2780 | + /// if its size exactly matches that of the requested array. |
| 2781 | + /// |
| 2782 | + /// # Examples |
| 2783 | + /// |
| 2784 | + /// ``` |
| 2785 | + /// use std::convert::TryInto; |
| 2786 | + /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3])); |
| 2787 | + /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([])); |
| 2788 | + /// ``` |
| 2789 | + /// |
| 2790 | + /// If the length doesn't match, the input comes back in `Err`: |
| 2791 | + /// ``` |
| 2792 | + /// use std::convert::TryInto; |
| 2793 | + /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into(); |
| 2794 | + /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); |
| 2795 | + /// ``` |
| 2796 | + /// |
| 2797 | + /// If you're fine with just getting a prefix of the `Vec<T>`, |
| 2798 | + /// you can call [`.truncate(N)`](Vec::truncate) first. |
| 2799 | + /// ``` |
| 2800 | + /// use std::convert::TryInto; |
| 2801 | + /// let mut v = String::from("hello world").into_bytes(); |
| 2802 | + /// v.sort(); |
| 2803 | + /// v.truncate(2); |
| 2804 | + /// let [a, b]: [_; 2] = v.try_into().unwrap(); |
| 2805 | + /// assert_eq!(a, b' '); |
| 2806 | + /// assert_eq!(b, b'd'); |
| 2807 | + /// ``` |
| 2808 | + fn try_from(mut vec: Vec<T>) -> Result<[T; N], Vec<T>> { |
| 2809 | + if vec.len() != N { |
| 2810 | + return Err(vec); |
| 2811 | + } |
| 2812 | + |
| 2813 | + // SAFETY: `.set_len(0)` is always sound. |
| 2814 | + unsafe { vec.set_len(0) }; |
| 2815 | + |
| 2816 | + // SAFETY: A `Vec`'s pointer is always aligned property, and |
| 2817 | + // the alignment the array needs is the same as the items. |
| 2818 | + // We checked earlier that we have sufficient items. |
| 2819 | + // The items will not double-drop as the `set_len` |
| 2820 | + // tells the `Vec` not to also drop them. |
| 2821 | + let array = unsafe { ptr::read(vec.as_ptr() as *const [T; N]) }; |
| 2822 | + Ok(array) |
| 2823 | + } |
| 2824 | +} |
| 2825 | + |
2774 | 2826 | ////////////////////////////////////////////////////////////////////////////////
|
2775 | 2827 | // Clone-on-write
|
2776 | 2828 | ////////////////////////////////////////////////////////////////////////////////
|
|
0 commit comments