|
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};
|
@@ -2754,6 +2755,57 @@ impl From<&str> for Vec<u8> {
|
2754 | 2755 | }
|
2755 | 2756 | }
|
2756 | 2757 |
|
| 2758 | +#[stable(feature = "array_try_from_vec", since = "1.48.0")] |
| 2759 | +impl<T, const N: usize> TryFrom<Vec<T>> for [T; N] { |
| 2760 | + type Error = Vec<T>; |
| 2761 | + |
| 2762 | + /// Gets the entire contents of the `Vec<T>` as an array, |
| 2763 | + /// if its size exactly matches that of the requested array. |
| 2764 | + /// |
| 2765 | + /// # Examples |
| 2766 | + /// |
| 2767 | + /// ``` |
| 2768 | + /// use std::convert::TryInto; |
| 2769 | + /// assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3])); |
| 2770 | + /// assert_eq!(<Vec<i32>>::new().try_into(), Ok([])); |
| 2771 | + /// ``` |
| 2772 | + /// |
| 2773 | + /// If the length doesn't match, the input comes back in `Err`: |
| 2774 | + /// ``` |
| 2775 | + /// use std::convert::TryInto; |
| 2776 | + /// let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into(); |
| 2777 | + /// assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); |
| 2778 | + /// ``` |
| 2779 | + /// |
| 2780 | + /// If you're fine with just getting a prefix of the `Vec<T>`, |
| 2781 | + /// you can call [`.truncate(N)`](Vec::truncate) first. |
| 2782 | + /// ``` |
| 2783 | + /// use std::convert::TryInto; |
| 2784 | + /// let mut v = String::from("hello world").into_bytes(); |
| 2785 | + /// v.sort(); |
| 2786 | + /// v.truncate(2); |
| 2787 | + /// let [a, b]: [_; 2] = v.try_into().unwrap(); |
| 2788 | + /// assert_eq!(a, b' '); |
| 2789 | + /// assert_eq!(b, b'd'); |
| 2790 | + /// ``` |
| 2791 | + fn try_from(mut vec: Vec<T>) -> Result<[T; N], Vec<T>> { |
| 2792 | + if vec.len() != N { |
| 2793 | + return Err(vec); |
| 2794 | + } |
| 2795 | + |
| 2796 | + // SAFETY: `.set_len(0)` is always sound. |
| 2797 | + unsafe { vec.set_len(0) }; |
| 2798 | + |
| 2799 | + // SAFETY: A `Vec`'s pointer is always aligned properly, and |
| 2800 | + // the alignment the array needs is the same as the items. |
| 2801 | + // We checked earlier that we have sufficient items. |
| 2802 | + // The items will not double-drop as the `set_len` |
| 2803 | + // tells the `Vec` not to also drop them. |
| 2804 | + let array = unsafe { ptr::read(vec.as_ptr() as *const [T; N]) }; |
| 2805 | + Ok(array) |
| 2806 | + } |
| 2807 | +} |
| 2808 | + |
2757 | 2809 | ////////////////////////////////////////////////////////////////////////////////
|
2758 | 2810 | // Clone-on-write
|
2759 | 2811 | ////////////////////////////////////////////////////////////////////////////////
|
|
0 commit comments