xref: /wasmtime-44.0.1/crates/core/src/alloc/vec.rs (revision 72dccdfd)
1b8e97b5bSNick Fitzgerald use crate::alloc::{TryClone, try_realloc};
2e0ee4552SNick Fitzgerald use crate::error::OutOfMemory;
3cfd8a4d2SNick Fitzgerald use core::borrow::Borrow;
4e0ee4552SNick Fitzgerald use core::{
55c2795e4SNick Fitzgerald     cmp::Ordering,
6*72dccdfdSbjorn3     fmt, mem,
75c2795e4SNick Fitzgerald     num::NonZeroUsize,
8e0ee4552SNick Fitzgerald     ops::{Deref, DerefMut, Index, IndexMut},
95c2795e4SNick Fitzgerald     slice::SliceIndex,
10e0ee4552SNick Fitzgerald };
11*72dccdfdSbjorn3 #[cfg(feature = "serde")]
1271c51d03SNick Fitzgerald use serde::ser::SerializeSeq;
1328f6f5e7SAlex Crichton use std_alloc::alloc::Layout;
1428f6f5e7SAlex Crichton use std_alloc::boxed::Box;
15e0ee4552SNick Fitzgerald use std_alloc::vec::Vec as StdVec;
16e0ee4552SNick Fitzgerald 
1783cf59f2SNick Fitzgerald /// Same as the [`std::vec!`] macro but returns an error on allocation failure.
1883cf59f2SNick Fitzgerald #[macro_export]
19183891f0SNick Fitzgerald macro_rules! try_vec {
2083cf59f2SNick Fitzgerald     ( $( $elem:expr ),* ) => {{
2183cf59f2SNick Fitzgerald         let len = $crate::private_len!( $( $elem ),* );
22183891f0SNick Fitzgerald         $crate::alloc::TryVec::with_capacity(len).and_then(|mut v| {
2383cf59f2SNick Fitzgerald             $( v.push($elem)?; )*
2483cf59f2SNick Fitzgerald             let _ = &mut v;
2583cf59f2SNick Fitzgerald             Ok(v)
2683cf59f2SNick Fitzgerald         })
2783cf59f2SNick Fitzgerald     }};
2883cf59f2SNick Fitzgerald 
2983cf59f2SNick Fitzgerald     ( $elem:expr; $len:expr ) => {{
3083cf59f2SNick Fitzgerald         let len: usize = $len;
3183cf59f2SNick Fitzgerald         if let Some(len) = ::core::num::NonZeroUsize::new(len) {
3283cf59f2SNick Fitzgerald             let elem = $elem;
33183891f0SNick Fitzgerald             $crate::alloc::TryVec::from_elem(elem, len)
3483cf59f2SNick Fitzgerald         } else {
35183891f0SNick Fitzgerald             Ok($crate::alloc::TryVec::new())
3683cf59f2SNick Fitzgerald         }
3783cf59f2SNick Fitzgerald     }};
3883cf59f2SNick Fitzgerald 
3983cf59f2SNick Fitzgerald }
4083cf59f2SNick Fitzgerald 
4183cf59f2SNick Fitzgerald // Only for use by the `vec!` macro.
4283cf59f2SNick Fitzgerald #[doc(hidden)]
4383cf59f2SNick Fitzgerald #[macro_export]
4483cf59f2SNick Fitzgerald macro_rules! private_len {
4583cf59f2SNick Fitzgerald     ( ) => { 0 };
4683cf59f2SNick Fitzgerald     ( $e:expr $( , $es:expr )* ) => { 1 + $crate::private_len!( $( $es ),* ) };
4783cf59f2SNick Fitzgerald }
4883cf59f2SNick Fitzgerald 
49e0ee4552SNick Fitzgerald /// Like `std::vec::Vec` but all methods that allocate force handling allocation
50e0ee4552SNick Fitzgerald /// failure.
518a8a9237SNick Fitzgerald #[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
52183891f0SNick Fitzgerald pub struct TryVec<T> {
53e0ee4552SNick Fitzgerald     inner: StdVec<T>,
54e0ee4552SNick Fitzgerald }
55e0ee4552SNick Fitzgerald 
56183891f0SNick Fitzgerald impl<T> Default for TryVec<T> {
57e0ee4552SNick Fitzgerald     fn default() -> Self {
58e0ee4552SNick Fitzgerald         Self {
59e0ee4552SNick Fitzgerald             inner: Default::default(),
60e0ee4552SNick Fitzgerald         }
61e0ee4552SNick Fitzgerald     }
62e0ee4552SNick Fitzgerald }
63e0ee4552SNick Fitzgerald 
64183891f0SNick Fitzgerald impl<T: fmt::Debug> fmt::Debug for TryVec<T> {
65e0ee4552SNick Fitzgerald     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66e0ee4552SNick Fitzgerald         fmt::Debug::fmt(&self.inner, f)
67e0ee4552SNick Fitzgerald     }
68e0ee4552SNick Fitzgerald }
69e0ee4552SNick Fitzgerald 
70183891f0SNick Fitzgerald impl<T> TryClone for TryVec<T>
71b8e97b5bSNick Fitzgerald where
72b8e97b5bSNick Fitzgerald     T: TryClone,
73b8e97b5bSNick Fitzgerald {
74b8e97b5bSNick Fitzgerald     fn try_clone(&self) -> Result<Self, OutOfMemory> {
75183891f0SNick Fitzgerald         let mut v = TryVec::with_capacity(self.len())?;
76b8e97b5bSNick Fitzgerald         for x in self {
77b8e97b5bSNick Fitzgerald             v.push(x.try_clone()?).expect("reserved capacity");
78b8e97b5bSNick Fitzgerald         }
79b8e97b5bSNick Fitzgerald         Ok(v)
80b8e97b5bSNick Fitzgerald     }
81b8e97b5bSNick Fitzgerald }
82b8e97b5bSNick Fitzgerald 
83183891f0SNick Fitzgerald impl<T> TryVec<T> {
84e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::new`].
85c2112959SNick Fitzgerald     pub const fn new() -> Self {
86c2112959SNick Fitzgerald         Self {
87c2112959SNick Fitzgerald             inner: StdVec::new(),
88c2112959SNick Fitzgerald         }
89e0ee4552SNick Fitzgerald     }
90e0ee4552SNick Fitzgerald 
91e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::with_capacity`] but returns an error on
92e0ee4552SNick Fitzgerald     /// allocation failure.
93e0ee4552SNick Fitzgerald     pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {
94e0ee4552SNick Fitzgerald         let mut v = Self::new();
95e0ee4552SNick Fitzgerald         v.reserve(capacity)?;
96e0ee4552SNick Fitzgerald         Ok(v)
97e0ee4552SNick Fitzgerald     }
98e0ee4552SNick Fitzgerald 
9983cf59f2SNick Fitzgerald     // For use with the `vec!` macro.
10083cf59f2SNick Fitzgerald     #[doc(hidden)]
10183cf59f2SNick Fitzgerald     #[inline]
10283cf59f2SNick Fitzgerald     pub fn from_elem(elem: T, len: NonZeroUsize) -> Result<Self, OutOfMemory>
10383cf59f2SNick Fitzgerald     where
10483cf59f2SNick Fitzgerald         T: TryClone,
10583cf59f2SNick Fitzgerald     {
10683cf59f2SNick Fitzgerald         let mut v = Self::with_capacity(len.get())?;
10783cf59f2SNick Fitzgerald 
10883cf59f2SNick Fitzgerald         // Minimize calls to `TryClone` by always pushing `elem` itself as the
10983cf59f2SNick Fitzgerald         // last element.
11083cf59f2SNick Fitzgerald         for _ in 0..len.get() - 1 {
11183cf59f2SNick Fitzgerald             v.push(elem.try_clone()?)?;
11283cf59f2SNick Fitzgerald         }
11383cf59f2SNick Fitzgerald         v.push(elem)?;
11483cf59f2SNick Fitzgerald 
11583cf59f2SNick Fitzgerald         Ok(v)
11683cf59f2SNick Fitzgerald     }
11783cf59f2SNick Fitzgerald 
118e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::reserve`] but returns an error on allocation
119e0ee4552SNick Fitzgerald     /// failure.
120e0ee4552SNick Fitzgerald     pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> {
121e0ee4552SNick Fitzgerald         self.inner.try_reserve(additional).map_err(|_| {
122e0ee4552SNick Fitzgerald             OutOfMemory::new(
123e0ee4552SNick Fitzgerald                 self.len()
124e0ee4552SNick Fitzgerald                     .saturating_add(additional)
12535483cc4SNick Fitzgerald                     .saturating_mul(mem::size_of::<T>()),
126e0ee4552SNick Fitzgerald             )
127e0ee4552SNick Fitzgerald         })
128e0ee4552SNick Fitzgerald     }
129e0ee4552SNick Fitzgerald 
130e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::reserve_exact`] but returns an error on allocation
131e0ee4552SNick Fitzgerald     /// failure.
132e0ee4552SNick Fitzgerald     pub fn reserve_exact(&mut self, additional: usize) -> Result<(), OutOfMemory> {
133e0ee4552SNick Fitzgerald         self.inner
134e0ee4552SNick Fitzgerald             .try_reserve_exact(additional)
135e0ee4552SNick Fitzgerald             .map_err(|_| OutOfMemory::new(self.len().saturating_add(additional)))
136e0ee4552SNick Fitzgerald     }
137e0ee4552SNick Fitzgerald 
138e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::len`].
139e0ee4552SNick Fitzgerald     pub fn len(&self) -> usize {
140e0ee4552SNick Fitzgerald         self.inner.len()
141e0ee4552SNick Fitzgerald     }
142e0ee4552SNick Fitzgerald 
143e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::capacity`].
144e0ee4552SNick Fitzgerald     pub fn capacity(&self) -> usize {
145e0ee4552SNick Fitzgerald         self.inner.capacity()
146e0ee4552SNick Fitzgerald     }
147e0ee4552SNick Fitzgerald 
148e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::is_empty`].
149e0ee4552SNick Fitzgerald     pub fn is_empty(&self) -> bool {
150e0ee4552SNick Fitzgerald         self.inner.is_empty()
151e0ee4552SNick Fitzgerald     }
152e0ee4552SNick Fitzgerald 
153e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::push`] but returns an error on allocation
154e0ee4552SNick Fitzgerald     /// failure.
155e0ee4552SNick Fitzgerald     pub fn push(&mut self, value: T) -> Result<(), OutOfMemory> {
156e0ee4552SNick Fitzgerald         self.reserve(1)?;
157e0ee4552SNick Fitzgerald         self.inner.push(value);
158e0ee4552SNick Fitzgerald         Ok(())
159e0ee4552SNick Fitzgerald     }
160342710aeSNick Fitzgerald 
1619cc85ab9SNick Fitzgerald     /// Same as [`std::vec::Vec::pop`].
1629cc85ab9SNick Fitzgerald     pub fn pop(&mut self) -> Option<T> {
1639cc85ab9SNick Fitzgerald         self.inner.pop()
1649cc85ab9SNick Fitzgerald     }
1659cc85ab9SNick Fitzgerald 
1669ead02e7SNick Fitzgerald     /// Same as [`std::vec::Vec::truncate`].
1679ead02e7SNick Fitzgerald     pub fn truncate(&mut self, len: usize) {
1689ead02e7SNick Fitzgerald         self.inner.truncate(len);
1699ead02e7SNick Fitzgerald     }
1709ead02e7SNick Fitzgerald 
1719ead02e7SNick Fitzgerald     /// Same as [`std::vec::Vec::resize`] but returns an error on allocation
1729ead02e7SNick Fitzgerald     /// failure.
1739ead02e7SNick Fitzgerald     pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), OutOfMemory>
1749ead02e7SNick Fitzgerald     where
1759ead02e7SNick Fitzgerald         T: TryClone,
1769ead02e7SNick Fitzgerald     {
1779ead02e7SNick Fitzgerald         match new_len.cmp(&self.len()) {
1789ead02e7SNick Fitzgerald             Ordering::Less => self.truncate(new_len),
1799ead02e7SNick Fitzgerald             Ordering::Equal => {}
1809ead02e7SNick Fitzgerald             Ordering::Greater => {
1819ead02e7SNick Fitzgerald                 let delta = new_len - self.len();
1829ead02e7SNick Fitzgerald                 self.reserve(delta)?;
1839ead02e7SNick Fitzgerald                 // Minimize `try_clone` calls by always pushing `value` directly
1849ead02e7SNick Fitzgerald                 // as the last element.
1859ead02e7SNick Fitzgerald                 for _ in 0..delta - 1 {
1869ead02e7SNick Fitzgerald                     self.push(value.try_clone()?)?;
1879ead02e7SNick Fitzgerald                 }
1889ead02e7SNick Fitzgerald                 self.push(value)?;
1899ead02e7SNick Fitzgerald             }
1909ead02e7SNick Fitzgerald         }
1919ead02e7SNick Fitzgerald         Ok(())
1929ead02e7SNick Fitzgerald     }
1939ead02e7SNick Fitzgerald 
1945999e5beSNick Fitzgerald     /// Same as [`std::vec::Vec::into_raw_parts`].
1955999e5beSNick Fitzgerald     pub fn into_raw_parts(mut self) -> (*mut T, usize, usize) {
1965999e5beSNick Fitzgerald         // NB: Can't use `Vec::into_raw_parts` until our MSRV is >= 1.93.
19728f6f5e7SAlex Crichton         #[cfg(not(miri))]
19828f6f5e7SAlex Crichton         {
1995999e5beSNick Fitzgerald             let ptr = self.as_mut_ptr();
2005999e5beSNick Fitzgerald             let len = self.len();
2015999e5beSNick Fitzgerald             let cap = self.capacity();
20235483cc4SNick Fitzgerald             mem::forget(self);
2035999e5beSNick Fitzgerald             (ptr, len, cap)
2045999e5beSNick Fitzgerald         }
20528f6f5e7SAlex Crichton         // NB: Miri requires using `into_raw_parts`, but always run on nightly,
20628f6f5e7SAlex Crichton         // so it's fine to use there.
20728f6f5e7SAlex Crichton         #[cfg(miri)]
20828f6f5e7SAlex Crichton         {
20928f6f5e7SAlex Crichton             let _ = &mut self;
21028f6f5e7SAlex Crichton             self.inner.into_raw_parts()
21128f6f5e7SAlex Crichton         }
21228f6f5e7SAlex Crichton     }
2135999e5beSNick Fitzgerald 
2145999e5beSNick Fitzgerald     /// Same as [`std::vec::Vec::from_raw_parts`].
2155999e5beSNick Fitzgerald     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
216183891f0SNick Fitzgerald         TryVec {
2175999e5beSNick Fitzgerald             // Safety: Same as our unsafe contract.
2185999e5beSNick Fitzgerald             inner: unsafe { StdVec::from_raw_parts(ptr, length, capacity) },
2195999e5beSNick Fitzgerald         }
2205999e5beSNick Fitzgerald     }
2215999e5beSNick Fitzgerald 
222342710aeSNick Fitzgerald     /// Same as [`std::vec::Vec::drain`].
223342710aeSNick Fitzgerald     pub fn drain<R>(&mut self, range: R) -> std_alloc::vec::Drain<'_, T>
224342710aeSNick Fitzgerald     where
225342710aeSNick Fitzgerald         R: core::ops::RangeBounds<usize>,
226342710aeSNick Fitzgerald     {
227342710aeSNick Fitzgerald         self.inner.drain(range)
228342710aeSNick Fitzgerald     }
22928f6f5e7SAlex Crichton 
2300c673b70SNick Fitzgerald     /// Same as [`std::vec::Vec::shrink_to_fit`] but returns an error on
2310c673b70SNick Fitzgerald     /// allocation failure.
2320c673b70SNick Fitzgerald     pub fn shrink_to_fit(&mut self) -> Result<(), OutOfMemory> {
2330c673b70SNick Fitzgerald         // If our length is already equal to our capacity, then there is nothing
2340c673b70SNick Fitzgerald         // to shrink.
2350c673b70SNick Fitzgerald         if self.len() == self.capacity() {
2360c673b70SNick Fitzgerald             return Ok(());
2370c673b70SNick Fitzgerald         }
2380c673b70SNick Fitzgerald 
23928f6f5e7SAlex Crichton         // `realloc` requires a non-zero original layout as well as a non-zero
24028f6f5e7SAlex Crichton         // destination layout, so this guard ensures that the sizes below are
2410c673b70SNick Fitzgerald         // all nonzero. This handles a few cases:
24228f6f5e7SAlex Crichton         //
24328f6f5e7SAlex Crichton         // * If `len == cap == 0` then no allocation has ever been made.
24428f6f5e7SAlex Crichton         // * If `len == 0` and `cap != 0` then this function effectively frees
24528f6f5e7SAlex Crichton         //   the memory.
24628f6f5e7SAlex Crichton         // * If `T` is a zero-sized type then nothing's been allocated either.
24728f6f5e7SAlex Crichton         //
24828f6f5e7SAlex Crichton         // In all of these cases delegate to the standard library's
2490c673b70SNick Fitzgerald         // `shrink_to_fit` which is guaranteed to not perform a `realloc`.
2500c673b70SNick Fitzgerald         if self.is_empty() || mem::size_of::<T>() == 0 {
2510c673b70SNick Fitzgerald             self.inner.shrink_to_fit();
2520c673b70SNick Fitzgerald             return Ok(());
25328f6f5e7SAlex Crichton         }
25428f6f5e7SAlex Crichton 
2550c673b70SNick Fitzgerald         let (ptr, len, cap) = mem::take(self).into_raw_parts();
25628f6f5e7SAlex Crichton         let layout = Layout::array::<T>(cap).unwrap();
2570c673b70SNick Fitzgerald         let new_size = Layout::array::<T>(len).unwrap().size();
25828f6f5e7SAlex Crichton 
25928f6f5e7SAlex Crichton         // SAFETY: `ptr` was previously allocated in the global allocator,
26028f6f5e7SAlex Crichton         // `layout` has a nonzero size and matches the current allocation of
26128f6f5e7SAlex Crichton         // `ptr`, `new_size` is nonzero, and `new_size` is a valid array size
26228f6f5e7SAlex Crichton         // for `len` elements given its constructor.
2630c673b70SNick Fitzgerald         let result = unsafe { try_realloc(ptr.cast(), layout, new_size) };
26428f6f5e7SAlex Crichton 
26528f6f5e7SAlex Crichton         match result {
26628f6f5e7SAlex Crichton             Ok(ptr) => {
2670c673b70SNick Fitzgerald                 // SAFETY: `result` is allocated with the global allocator and
2680c673b70SNick Fitzgerald                 // has room for exactly `[T; len]`.
2690c673b70SNick Fitzgerald                 *self = unsafe { Self::from_raw_parts(ptr.cast::<T>().as_ptr(), len, len) };
2700c673b70SNick Fitzgerald                 Ok(())
27128f6f5e7SAlex Crichton             }
27228f6f5e7SAlex Crichton             Err(oom) => {
27328f6f5e7SAlex Crichton                 // SAFETY: If reallocation fails then it's guaranteed that the
27428f6f5e7SAlex Crichton                 // original allocation is not tampered with, so it's safe to
2750c673b70SNick Fitzgerald                 // reassemble the original vector.
276183891f0SNick Fitzgerald                 *self = unsafe { TryVec::from_raw_parts(ptr, len, cap) };
27728f6f5e7SAlex Crichton                 Err(oom)
27828f6f5e7SAlex Crichton             }
27928f6f5e7SAlex Crichton         }
28028f6f5e7SAlex Crichton     }
2810c673b70SNick Fitzgerald 
2820c673b70SNick Fitzgerald     /// Same as [`std::vec::Vec::into_boxed_slice`] but returns an error on
2830c673b70SNick Fitzgerald     /// allocation failure.
2840c673b70SNick Fitzgerald     pub fn into_boxed_slice(mut self) -> Result<Box<[T]>, OutOfMemory> {
2850c673b70SNick Fitzgerald         self.shrink_to_fit()?;
2860c673b70SNick Fitzgerald 
2870c673b70SNick Fitzgerald         // Once we've shrunken the allocation to just the actual length, we can
2880c673b70SNick Fitzgerald         // use `std`'s `into_boxed_slice` without fear of `realloc`.
2890c673b70SNick Fitzgerald         Ok(self.inner.into_boxed_slice())
2900c673b70SNick Fitzgerald     }
291763ace02SNick Fitzgerald 
292763ace02SNick Fitzgerald     /// Same as [`std::vec::Vec::clear`].
293763ace02SNick Fitzgerald     pub fn clear(&mut self) {
294763ace02SNick Fitzgerald         self.inner.clear();
295763ace02SNick Fitzgerald     }
296e0ee4552SNick Fitzgerald }
297e0ee4552SNick Fitzgerald 
298183891f0SNick Fitzgerald impl<T> Deref for TryVec<T> {
299e0ee4552SNick Fitzgerald     type Target = [T];
300e0ee4552SNick Fitzgerald 
301e0ee4552SNick Fitzgerald     fn deref(&self) -> &Self::Target {
302e0ee4552SNick Fitzgerald         &self.inner
303e0ee4552SNick Fitzgerald     }
304e0ee4552SNick Fitzgerald }
305e0ee4552SNick Fitzgerald 
306183891f0SNick Fitzgerald impl<T> DerefMut for TryVec<T> {
307e0ee4552SNick Fitzgerald     fn deref_mut(&mut self) -> &mut Self::Target {
308e0ee4552SNick Fitzgerald         &mut self.inner
309e0ee4552SNick Fitzgerald     }
310e0ee4552SNick Fitzgerald }
311e0ee4552SNick Fitzgerald 
312183891f0SNick Fitzgerald impl<T> AsRef<[T]> for TryVec<T> {
313cfd8a4d2SNick Fitzgerald     fn as_ref(&self) -> &[T] {
314cfd8a4d2SNick Fitzgerald         self
315cfd8a4d2SNick Fitzgerald     }
316cfd8a4d2SNick Fitzgerald }
317cfd8a4d2SNick Fitzgerald 
318183891f0SNick Fitzgerald impl<T> Borrow<[T]> for TryVec<T> {
319cfd8a4d2SNick Fitzgerald     fn borrow(&self) -> &[T] {
320cfd8a4d2SNick Fitzgerald         self
321cfd8a4d2SNick Fitzgerald     }
322cfd8a4d2SNick Fitzgerald }
323cfd8a4d2SNick Fitzgerald 
324183891f0SNick Fitzgerald impl<T, I> Index<I> for TryVec<T>
3255c2795e4SNick Fitzgerald where
3265c2795e4SNick Fitzgerald     I: SliceIndex<[T]>,
3275c2795e4SNick Fitzgerald {
3285c2795e4SNick Fitzgerald     type Output = <I as SliceIndex<[T]>>::Output;
329e0ee4552SNick Fitzgerald 
3305c2795e4SNick Fitzgerald     fn index(&self, index: I) -> &Self::Output {
331e0ee4552SNick Fitzgerald         &self.inner[index]
332e0ee4552SNick Fitzgerald     }
333e0ee4552SNick Fitzgerald }
334e0ee4552SNick Fitzgerald 
335183891f0SNick Fitzgerald impl<T, I> IndexMut<I> for TryVec<T>
3365c2795e4SNick Fitzgerald where
3375c2795e4SNick Fitzgerald     I: SliceIndex<[T]>,
3385c2795e4SNick Fitzgerald {
3395c2795e4SNick Fitzgerald     fn index_mut(&mut self, index: I) -> &mut Self::Output {
340e0ee4552SNick Fitzgerald         &mut self.inner[index]
341e0ee4552SNick Fitzgerald     }
342e0ee4552SNick Fitzgerald }
343e0ee4552SNick Fitzgerald 
344183891f0SNick Fitzgerald impl<T> IntoIterator for TryVec<T> {
3457b929e7fSNick Fitzgerald     type Item = T;
3467b929e7fSNick Fitzgerald     type IntoIter = std_alloc::vec::IntoIter<T>;
3477b929e7fSNick Fitzgerald 
3487b929e7fSNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
3497b929e7fSNick Fitzgerald         self.inner.into_iter()
3507b929e7fSNick Fitzgerald     }
3517b929e7fSNick Fitzgerald }
3527b929e7fSNick Fitzgerald 
353183891f0SNick Fitzgerald impl<'a, T> IntoIterator for &'a TryVec<T> {
354e0ee4552SNick Fitzgerald     type Item = &'a T;
355e0ee4552SNick Fitzgerald 
356e0ee4552SNick Fitzgerald     type IntoIter = core::slice::Iter<'a, T>;
357e0ee4552SNick Fitzgerald 
358e0ee4552SNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
359e0ee4552SNick Fitzgerald         (**self).iter()
360e0ee4552SNick Fitzgerald     }
361e0ee4552SNick Fitzgerald }
362e0ee4552SNick Fitzgerald 
363183891f0SNick Fitzgerald impl<'a, T> IntoIterator for &'a mut TryVec<T> {
364e0ee4552SNick Fitzgerald     type Item = &'a mut T;
365e0ee4552SNick Fitzgerald 
366e0ee4552SNick Fitzgerald     type IntoIter = core::slice::IterMut<'a, T>;
367e0ee4552SNick Fitzgerald 
368e0ee4552SNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
369e0ee4552SNick Fitzgerald         (**self).iter_mut()
370e0ee4552SNick Fitzgerald     }
371e0ee4552SNick Fitzgerald }
37228f6f5e7SAlex Crichton 
373183891f0SNick Fitzgerald impl<T> From<TryVec<T>> for StdVec<T> {
374183891f0SNick Fitzgerald     fn from(v: TryVec<T>) -> Self {
375efb98a9fSNick Fitzgerald         v.inner
376efb98a9fSNick Fitzgerald     }
377efb98a9fSNick Fitzgerald }
378efb98a9fSNick Fitzgerald 
379183891f0SNick Fitzgerald impl<T> From<StdVec<T>> for TryVec<T> {
380282546d4SNick Fitzgerald     fn from(inner: StdVec<T>) -> Self {
381282546d4SNick Fitzgerald         Self { inner }
382282546d4SNick Fitzgerald     }
383282546d4SNick Fitzgerald }
384282546d4SNick Fitzgerald 
385183891f0SNick Fitzgerald impl<T> From<Box<[T]>> for TryVec<T> {
38628f6f5e7SAlex Crichton     fn from(boxed_slice: Box<[T]>) -> Self {
38771c51d03SNick Fitzgerald         Self::from(StdVec::from(boxed_slice))
38828f6f5e7SAlex Crichton     }
38928f6f5e7SAlex Crichton }
39071c51d03SNick Fitzgerald 
391*72dccdfdSbjorn3 #[cfg(feature = "serde")]
392183891f0SNick Fitzgerald impl<T> serde::ser::Serialize for TryVec<T>
39371c51d03SNick Fitzgerald where
39471c51d03SNick Fitzgerald     T: serde::ser::Serialize,
39571c51d03SNick Fitzgerald {
39671c51d03SNick Fitzgerald     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39771c51d03SNick Fitzgerald     where
39871c51d03SNick Fitzgerald         S: serde::Serializer,
39971c51d03SNick Fitzgerald     {
40071c51d03SNick Fitzgerald         let mut seq = serializer.serialize_seq(Some(self.len()))?;
40171c51d03SNick Fitzgerald         for elem in self {
40271c51d03SNick Fitzgerald             seq.serialize_element(elem)?;
40371c51d03SNick Fitzgerald         }
40471c51d03SNick Fitzgerald         seq.end()
40571c51d03SNick Fitzgerald     }
40671c51d03SNick Fitzgerald }
40771c51d03SNick Fitzgerald 
408*72dccdfdSbjorn3 #[cfg(feature = "serde")]
409183891f0SNick Fitzgerald impl<'de, T> serde::de::Deserialize<'de> for TryVec<T>
41071c51d03SNick Fitzgerald where
41171c51d03SNick Fitzgerald     T: serde::de::Deserialize<'de>,
41271c51d03SNick Fitzgerald {
41371c51d03SNick Fitzgerald     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41471c51d03SNick Fitzgerald     where
41571c51d03SNick Fitzgerald         D: serde::Deserializer<'de>,
41671c51d03SNick Fitzgerald     {
417*72dccdfdSbjorn3         use core::marker::PhantomData;
418*72dccdfdSbjorn3 
419183891f0SNick Fitzgerald         struct Visitor<T>(PhantomData<fn() -> TryVec<T>>);
42071c51d03SNick Fitzgerald 
42171c51d03SNick Fitzgerald         impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
42271c51d03SNick Fitzgerald         where
42371c51d03SNick Fitzgerald             T: serde::de::Deserialize<'de>,
42471c51d03SNick Fitzgerald         {
425183891f0SNick Fitzgerald             type Value = TryVec<T>;
42671c51d03SNick Fitzgerald 
42771c51d03SNick Fitzgerald             fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
42871c51d03SNick Fitzgerald                 f.write_str("a `wasmtime_core::alloc::Vec` sequence")
42971c51d03SNick Fitzgerald             }
43071c51d03SNick Fitzgerald 
43171c51d03SNick Fitzgerald             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
43271c51d03SNick Fitzgerald             where
43371c51d03SNick Fitzgerald                 A: serde::de::SeqAccess<'de>,
43471c51d03SNick Fitzgerald             {
43571c51d03SNick Fitzgerald                 use serde::de::Error as _;
43671c51d03SNick Fitzgerald 
437183891f0SNick Fitzgerald                 let mut v = TryVec::new();
43871c51d03SNick Fitzgerald 
43971c51d03SNick Fitzgerald                 if let Some(len) = seq.size_hint() {
44071c51d03SNick Fitzgerald                     v.reserve_exact(len).map_err(|oom| A::Error::custom(oom))?;
44171c51d03SNick Fitzgerald                 }
44271c51d03SNick Fitzgerald 
44371c51d03SNick Fitzgerald                 while let Some(elem) = seq.next_element()? {
44471c51d03SNick Fitzgerald                     v.push(elem).map_err(|oom| A::Error::custom(oom))?;
44571c51d03SNick Fitzgerald                 }
44671c51d03SNick Fitzgerald 
44771c51d03SNick Fitzgerald                 Ok(v)
44871c51d03SNick Fitzgerald             }
44971c51d03SNick Fitzgerald         }
45071c51d03SNick Fitzgerald 
45171c51d03SNick Fitzgerald         deserializer.deserialize_seq(Visitor(PhantomData))
45271c51d03SNick Fitzgerald     }
45328f6f5e7SAlex Crichton }
45428f6f5e7SAlex Crichton 
45528f6f5e7SAlex Crichton #[cfg(test)]
45628f6f5e7SAlex Crichton mod tests {
457183891f0SNick Fitzgerald     use super::TryVec;
45828f6f5e7SAlex Crichton     use crate::error::OutOfMemory;
45928f6f5e7SAlex Crichton 
46028f6f5e7SAlex Crichton     #[test]
46128f6f5e7SAlex Crichton     fn test_into_boxed_slice() -> Result<(), OutOfMemory> {
462183891f0SNick Fitzgerald         assert_eq!(*TryVec::<i32>::new().into_boxed_slice()?, []);
46328f6f5e7SAlex Crichton 
464183891f0SNick Fitzgerald         let mut vec = TryVec::new();
46528f6f5e7SAlex Crichton         vec.push(1)?;
46628f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
46728f6f5e7SAlex Crichton 
468183891f0SNick Fitzgerald         let mut vec = TryVec::with_capacity(2)?;
46928f6f5e7SAlex Crichton         vec.push(1)?;
47028f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
47128f6f5e7SAlex Crichton 
472183891f0SNick Fitzgerald         let mut vec = TryVec::with_capacity(2)?;
47328f6f5e7SAlex Crichton         vec.push(1_u128)?;
47428f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
47528f6f5e7SAlex Crichton 
476183891f0SNick Fitzgerald         assert_eq!(*TryVec::<()>::new().into_boxed_slice()?, []);
47728f6f5e7SAlex Crichton 
478183891f0SNick Fitzgerald         let mut vec = TryVec::new();
47928f6f5e7SAlex Crichton         vec.push(())?;
48028f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [()]);
48128f6f5e7SAlex Crichton 
482183891f0SNick Fitzgerald         let vec = TryVec::<i32>::with_capacity(2)?;
48328f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, []);
48428f6f5e7SAlex Crichton         Ok(())
48528f6f5e7SAlex Crichton     }
48628f6f5e7SAlex Crichton }
487