|
36 | 36 | use core::borrow::{Borrow, BorrowMut};
|
37 | 37 | use core::fmt;
|
38 | 38 | use core::iter::FusedIterator;
|
39 |
| -use core::mem::MaybeUninit; |
| 39 | +use core::mem::{ManuallyDrop, MaybeUninit}; |
40 | 40 | use core::{ptr, slice};
|
41 | 41 |
|
42 | 42 | use crate::storage::{OwnedStorage, Storage, ViewStorage};
|
@@ -950,6 +950,50 @@ where
|
950 | 950 | }
|
951 | 951 | }
|
952 | 952 |
|
| 953 | +impl<T, const NS: usize, const ND: usize> TryFrom<[T; NS]> for Deque<T, ND> { |
| 954 | + /// Converts a `[T; NS]` into a `Deque<T, ND>`. |
| 955 | + /// |
| 956 | + /// ``` |
| 957 | + /// use heapless::Deque; |
| 958 | + /// |
| 959 | + /// let deq1 = Deque::<u8, 4>::try_from([1, 2, 3, 4]).unwrap(); |
| 960 | + /// let mut deq2 = Deque::<u8, 4>::new(); |
| 961 | + /// deq2.push_back(1).unwrap(); |
| 962 | + /// deq2.push_back(2).unwrap(); |
| 963 | + /// deq2.push_back(3).unwrap(); |
| 964 | + /// deq2.push_back(4).unwrap(); |
| 965 | + /// |
| 966 | + /// // todo change to `assert_eq!(deq1, deq2);` when PR #521 is merged. |
| 967 | + /// assert_eq!(deq1.len(), deq2.len()); |
| 968 | + /// for (i, e1) in deq1.iter().enumerate() { |
| 969 | + /// assert_eq!(Some(e1), deq2.get(i)); |
| 970 | + /// } |
| 971 | + /// ``` |
| 972 | + type Error = (); |
| 973 | + |
| 974 | + fn try_from(value: [T; NS]) -> Result<Self, Self::Error> { |
| 975 | + if NS > ND { |
| 976 | + return Err(()); |
| 977 | + } |
| 978 | + |
| 979 | + let mut deq = Self::default(); |
| 980 | + let value = ManuallyDrop::new(value); |
| 981 | + |
| 982 | + if size_of::<T>() != 0 { |
| 983 | + // SAFETY: We already ensured that value fits in deq. |
| 984 | + unsafe { |
| 985 | + ptr::copy_nonoverlapping(value.as_ptr(), deq.buffer.as_mut_ptr() as *mut T, NS); |
| 986 | + } |
| 987 | + } |
| 988 | + |
| 989 | + deq.front = 0; |
| 990 | + deq.back = NS; |
| 991 | + deq.full = NS == ND; |
| 992 | + |
| 993 | + Ok(deq) |
| 994 | + } |
| 995 | +} |
| 996 | + |
953 | 997 | #[cfg(test)]
|
954 | 998 | mod tests {
|
955 | 999 | use static_assertions::assert_not_impl_any;
|
|
0 commit comments