xref: /wasmtime-44.0.1/crates/core/src/alloc/vec.rs (revision 439de7fb)
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,
672dccdfdSbjorn3     fmt, mem,
75c2795e4SNick Fitzgerald     num::NonZeroUsize,
8e0ee4552SNick Fitzgerald     ops::{Deref, DerefMut, Index, IndexMut},
95c2795e4SNick Fitzgerald     slice::SliceIndex,
10e0ee4552SNick Fitzgerald };
1172dccdfdSbjorn3 #[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> {
default() -> Self57e0ee4552SNick 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> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result65e0ee4552SNick 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 {
try_clone(&self) -> Result<Self, OutOfMemory>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`].
new() -> Self85c2112959SNick 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.
with_capacity(capacity: usize) -> Result<Self, OutOfMemory>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]
from_elem(elem: T, len: NonZeroUsize) -> Result<Self, OutOfMemory> where T: TryClone,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.
reserve(&mut self, additional: usize) -> Result<(), OutOfMemory>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.
reserve_exact(&mut self, additional: usize) -> Result<(), OutOfMemory>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`].
len(&self) -> usize139e0ee4552SNick Fitzgerald     pub fn len(&self) -> usize {
140e0ee4552SNick Fitzgerald         self.inner.len()
141e0ee4552SNick Fitzgerald     }
142e0ee4552SNick Fitzgerald 
143e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::capacity`].
capacity(&self) -> usize144e0ee4552SNick Fitzgerald     pub fn capacity(&self) -> usize {
145e0ee4552SNick Fitzgerald         self.inner.capacity()
146e0ee4552SNick Fitzgerald     }
147e0ee4552SNick Fitzgerald 
148e0ee4552SNick Fitzgerald     /// Same as [`std::vec::Vec::is_empty`].
is_empty(&self) -> bool149e0ee4552SNick 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.
push(&mut self, value: T) -> Result<(), OutOfMemory>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`].
pop(&mut self) -> Option<T>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`].
truncate(&mut self, len: usize)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.
resize(&mut self, new_len: usize, value: T) -> Result<(), OutOfMemory> where T: TryClone,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 
194*439de7fbSNick Fitzgerald     /// Same as [`std::vec::Vec::resize_with`] but returns an error on
195*439de7fbSNick Fitzgerald     /// allocation failure.
resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), OutOfMemory> where F: FnMut() -> T,196*439de7fbSNick Fitzgerald     pub fn resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), OutOfMemory>
197*439de7fbSNick Fitzgerald     where
198*439de7fbSNick Fitzgerald         F: FnMut() -> T,
199*439de7fbSNick Fitzgerald     {
200*439de7fbSNick Fitzgerald         let len = self.len();
201*439de7fbSNick Fitzgerald         if new_len > len {
202*439de7fbSNick Fitzgerald             self.reserve(new_len - len)?;
203*439de7fbSNick Fitzgerald         }
204*439de7fbSNick Fitzgerald         self.inner.resize_with(new_len, f);
205*439de7fbSNick Fitzgerald         Ok(())
206*439de7fbSNick Fitzgerald     }
207*439de7fbSNick Fitzgerald 
208837d02faSNick Fitzgerald     /// Same as [`std::vec::Vec::retain`].
retain<F>(&mut self, f: F) where F: FnMut(&T) -> bool,209837d02faSNick Fitzgerald     pub fn retain<F>(&mut self, f: F)
210837d02faSNick Fitzgerald     where
211837d02faSNick Fitzgerald         F: FnMut(&T) -> bool,
212837d02faSNick Fitzgerald     {
213837d02faSNick Fitzgerald         self.inner.retain(f);
214837d02faSNick Fitzgerald     }
215837d02faSNick Fitzgerald 
216837d02faSNick Fitzgerald     /// Same as [`std::vec::Vec::retain_mut`].
retain_mut<F>(&mut self, f: F) where F: FnMut(&mut T) -> bool,217837d02faSNick Fitzgerald     pub fn retain_mut<F>(&mut self, f: F)
218837d02faSNick Fitzgerald     where
219837d02faSNick Fitzgerald         F: FnMut(&mut T) -> bool,
220837d02faSNick Fitzgerald     {
221837d02faSNick Fitzgerald         self.inner.retain_mut(f);
222837d02faSNick Fitzgerald     }
223837d02faSNick Fitzgerald 
2245999e5beSNick Fitzgerald     /// Same as [`std::vec::Vec::into_raw_parts`].
into_raw_parts(mut self) -> (*mut T, usize, usize)2255999e5beSNick Fitzgerald     pub fn into_raw_parts(mut self) -> (*mut T, usize, usize) {
2265999e5beSNick Fitzgerald         // NB: Can't use `Vec::into_raw_parts` until our MSRV is >= 1.93.
22728f6f5e7SAlex Crichton         #[cfg(not(miri))]
22828f6f5e7SAlex Crichton         {
2295999e5beSNick Fitzgerald             let ptr = self.as_mut_ptr();
2305999e5beSNick Fitzgerald             let len = self.len();
2315999e5beSNick Fitzgerald             let cap = self.capacity();
23235483cc4SNick Fitzgerald             mem::forget(self);
2335999e5beSNick Fitzgerald             (ptr, len, cap)
2345999e5beSNick Fitzgerald         }
23528f6f5e7SAlex Crichton         // NB: Miri requires using `into_raw_parts`, but always run on nightly,
23628f6f5e7SAlex Crichton         // so it's fine to use there.
23728f6f5e7SAlex Crichton         #[cfg(miri)]
23828f6f5e7SAlex Crichton         {
23928f6f5e7SAlex Crichton             let _ = &mut self;
24028f6f5e7SAlex Crichton             self.inner.into_raw_parts()
24128f6f5e7SAlex Crichton         }
24228f6f5e7SAlex Crichton     }
2435999e5beSNick Fitzgerald 
2445999e5beSNick Fitzgerald     /// Same as [`std::vec::Vec::from_raw_parts`].
from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self2455999e5beSNick Fitzgerald     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
246183891f0SNick Fitzgerald         TryVec {
2475999e5beSNick Fitzgerald             // Safety: Same as our unsafe contract.
2485999e5beSNick Fitzgerald             inner: unsafe { StdVec::from_raw_parts(ptr, length, capacity) },
2495999e5beSNick Fitzgerald         }
2505999e5beSNick Fitzgerald     }
2515999e5beSNick Fitzgerald 
252342710aeSNick Fitzgerald     /// Same as [`std::vec::Vec::drain`].
drain<R>(&mut self, range: R) -> std_alloc::vec::Drain<'_, T> where R: core::ops::RangeBounds<usize>,253342710aeSNick Fitzgerald     pub fn drain<R>(&mut self, range: R) -> std_alloc::vec::Drain<'_, T>
254342710aeSNick Fitzgerald     where
255342710aeSNick Fitzgerald         R: core::ops::RangeBounds<usize>,
256342710aeSNick Fitzgerald     {
257342710aeSNick Fitzgerald         self.inner.drain(range)
258342710aeSNick Fitzgerald     }
25928f6f5e7SAlex Crichton 
2600c673b70SNick Fitzgerald     /// Same as [`std::vec::Vec::shrink_to_fit`] but returns an error on
2610c673b70SNick Fitzgerald     /// allocation failure.
shrink_to_fit(&mut self) -> Result<(), OutOfMemory>2620c673b70SNick Fitzgerald     pub fn shrink_to_fit(&mut self) -> Result<(), OutOfMemory> {
2630c673b70SNick Fitzgerald         // If our length is already equal to our capacity, then there is nothing
2640c673b70SNick Fitzgerald         // to shrink.
2650c673b70SNick Fitzgerald         if self.len() == self.capacity() {
2660c673b70SNick Fitzgerald             return Ok(());
2670c673b70SNick Fitzgerald         }
2680c673b70SNick Fitzgerald 
26928f6f5e7SAlex Crichton         // `realloc` requires a non-zero original layout as well as a non-zero
27028f6f5e7SAlex Crichton         // destination layout, so this guard ensures that the sizes below are
2710c673b70SNick Fitzgerald         // all nonzero. This handles a few cases:
27228f6f5e7SAlex Crichton         //
27328f6f5e7SAlex Crichton         // * If `len == cap == 0` then no allocation has ever been made.
27428f6f5e7SAlex Crichton         // * If `len == 0` and `cap != 0` then this function effectively frees
27528f6f5e7SAlex Crichton         //   the memory.
27628f6f5e7SAlex Crichton         // * If `T` is a zero-sized type then nothing's been allocated either.
27728f6f5e7SAlex Crichton         //
27828f6f5e7SAlex Crichton         // In all of these cases delegate to the standard library's
2790c673b70SNick Fitzgerald         // `shrink_to_fit` which is guaranteed to not perform a `realloc`.
2800c673b70SNick Fitzgerald         if self.is_empty() || mem::size_of::<T>() == 0 {
2810c673b70SNick Fitzgerald             self.inner.shrink_to_fit();
2820c673b70SNick Fitzgerald             return Ok(());
28328f6f5e7SAlex Crichton         }
28428f6f5e7SAlex Crichton 
2850c673b70SNick Fitzgerald         let (ptr, len, cap) = mem::take(self).into_raw_parts();
28628f6f5e7SAlex Crichton         let layout = Layout::array::<T>(cap).unwrap();
2870c673b70SNick Fitzgerald         let new_size = Layout::array::<T>(len).unwrap().size();
28828f6f5e7SAlex Crichton 
28928f6f5e7SAlex Crichton         // SAFETY: `ptr` was previously allocated in the global allocator,
29028f6f5e7SAlex Crichton         // `layout` has a nonzero size and matches the current allocation of
29128f6f5e7SAlex Crichton         // `ptr`, `new_size` is nonzero, and `new_size` is a valid array size
29228f6f5e7SAlex Crichton         // for `len` elements given its constructor.
2930c673b70SNick Fitzgerald         let result = unsafe { try_realloc(ptr.cast(), layout, new_size) };
29428f6f5e7SAlex Crichton 
29528f6f5e7SAlex Crichton         match result {
29628f6f5e7SAlex Crichton             Ok(ptr) => {
2970c673b70SNick Fitzgerald                 // SAFETY: `result` is allocated with the global allocator and
2980c673b70SNick Fitzgerald                 // has room for exactly `[T; len]`.
2990c673b70SNick Fitzgerald                 *self = unsafe { Self::from_raw_parts(ptr.cast::<T>().as_ptr(), len, len) };
3000c673b70SNick Fitzgerald                 Ok(())
30128f6f5e7SAlex Crichton             }
30228f6f5e7SAlex Crichton             Err(oom) => {
30328f6f5e7SAlex Crichton                 // SAFETY: If reallocation fails then it's guaranteed that the
30428f6f5e7SAlex Crichton                 // original allocation is not tampered with, so it's safe to
3050c673b70SNick Fitzgerald                 // reassemble the original vector.
306183891f0SNick Fitzgerald                 *self = unsafe { TryVec::from_raw_parts(ptr, len, cap) };
30728f6f5e7SAlex Crichton                 Err(oom)
30828f6f5e7SAlex Crichton             }
30928f6f5e7SAlex Crichton         }
31028f6f5e7SAlex Crichton     }
3110c673b70SNick Fitzgerald 
3120c673b70SNick Fitzgerald     /// Same as [`std::vec::Vec::into_boxed_slice`] but returns an error on
3130c673b70SNick Fitzgerald     /// allocation failure.
into_boxed_slice(mut self) -> Result<Box<[T]>, OutOfMemory>3140c673b70SNick Fitzgerald     pub fn into_boxed_slice(mut self) -> Result<Box<[T]>, OutOfMemory> {
3150c673b70SNick Fitzgerald         self.shrink_to_fit()?;
3160c673b70SNick Fitzgerald 
3170c673b70SNick Fitzgerald         // Once we've shrunken the allocation to just the actual length, we can
3180c673b70SNick Fitzgerald         // use `std`'s `into_boxed_slice` without fear of `realloc`.
3190c673b70SNick Fitzgerald         Ok(self.inner.into_boxed_slice())
3200c673b70SNick Fitzgerald     }
321763ace02SNick Fitzgerald 
322763ace02SNick Fitzgerald     /// Same as [`std::vec::Vec::clear`].
clear(&mut self)323763ace02SNick Fitzgerald     pub fn clear(&mut self) {
324763ace02SNick Fitzgerald         self.inner.clear();
325763ace02SNick Fitzgerald     }
3262283e84fSAlex Crichton 
3272283e84fSAlex Crichton     /// Same as [`std::vec::Vec::as_mut_ptr`].
3282283e84fSAlex Crichton     //
3292283e84fSAlex Crichton     // Note that this is technically inherited through the `DerefMut` impl but
3302283e84fSAlex Crichton     // that converts `&mut Self` to `&mut [T]` which invalidates all previously
3312283e84fSAlex Crichton     // derived pointers. This causes problems in Miri so by having an inherent
3322283e84fSAlex Crichton     // method here it means that the borrow scope matches what we want with
3332283e84fSAlex Crichton     // Miri.
as_mut_ptr(&mut self) -> *mut T3342283e84fSAlex Crichton     pub fn as_mut_ptr(&mut self) -> *mut T {
3352283e84fSAlex Crichton         self.inner.as_mut_ptr()
3362283e84fSAlex Crichton     }
337e0ee4552SNick Fitzgerald }
338e0ee4552SNick Fitzgerald 
339183891f0SNick Fitzgerald impl<T> Deref for TryVec<T> {
340e0ee4552SNick Fitzgerald     type Target = [T];
341e0ee4552SNick Fitzgerald 
deref(&self) -> &Self::Target342e0ee4552SNick Fitzgerald     fn deref(&self) -> &Self::Target {
343e0ee4552SNick Fitzgerald         &self.inner
344e0ee4552SNick Fitzgerald     }
345e0ee4552SNick Fitzgerald }
346e0ee4552SNick Fitzgerald 
347183891f0SNick Fitzgerald impl<T> DerefMut for TryVec<T> {
deref_mut(&mut self) -> &mut Self::Target348e0ee4552SNick Fitzgerald     fn deref_mut(&mut self) -> &mut Self::Target {
349e0ee4552SNick Fitzgerald         &mut self.inner
350e0ee4552SNick Fitzgerald     }
351e0ee4552SNick Fitzgerald }
352e0ee4552SNick Fitzgerald 
353183891f0SNick Fitzgerald impl<T> AsRef<[T]> for TryVec<T> {
as_ref(&self) -> &[T]354cfd8a4d2SNick Fitzgerald     fn as_ref(&self) -> &[T] {
355cfd8a4d2SNick Fitzgerald         self
356cfd8a4d2SNick Fitzgerald     }
357cfd8a4d2SNick Fitzgerald }
358cfd8a4d2SNick Fitzgerald 
359183891f0SNick Fitzgerald impl<T> Borrow<[T]> for TryVec<T> {
borrow(&self) -> &[T]360cfd8a4d2SNick Fitzgerald     fn borrow(&self) -> &[T] {
361cfd8a4d2SNick Fitzgerald         self
362cfd8a4d2SNick Fitzgerald     }
363cfd8a4d2SNick Fitzgerald }
364cfd8a4d2SNick Fitzgerald 
365183891f0SNick Fitzgerald impl<T, I> Index<I> for TryVec<T>
3665c2795e4SNick Fitzgerald where
3675c2795e4SNick Fitzgerald     I: SliceIndex<[T]>,
3685c2795e4SNick Fitzgerald {
3695c2795e4SNick Fitzgerald     type Output = <I as SliceIndex<[T]>>::Output;
370e0ee4552SNick Fitzgerald 
index(&self, index: I) -> &Self::Output3715c2795e4SNick Fitzgerald     fn index(&self, index: I) -> &Self::Output {
372e0ee4552SNick Fitzgerald         &self.inner[index]
373e0ee4552SNick Fitzgerald     }
374e0ee4552SNick Fitzgerald }
375e0ee4552SNick Fitzgerald 
376183891f0SNick Fitzgerald impl<T, I> IndexMut<I> for TryVec<T>
3775c2795e4SNick Fitzgerald where
3785c2795e4SNick Fitzgerald     I: SliceIndex<[T]>,
3795c2795e4SNick Fitzgerald {
index_mut(&mut self, index: I) -> &mut Self::Output3805c2795e4SNick Fitzgerald     fn index_mut(&mut self, index: I) -> &mut Self::Output {
381e0ee4552SNick Fitzgerald         &mut self.inner[index]
382e0ee4552SNick Fitzgerald     }
383e0ee4552SNick Fitzgerald }
384e0ee4552SNick Fitzgerald 
385183891f0SNick Fitzgerald impl<T> IntoIterator for TryVec<T> {
3867b929e7fSNick Fitzgerald     type Item = T;
3877b929e7fSNick Fitzgerald     type IntoIter = std_alloc::vec::IntoIter<T>;
3887b929e7fSNick Fitzgerald 
into_iter(self) -> Self::IntoIter3897b929e7fSNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
3907b929e7fSNick Fitzgerald         self.inner.into_iter()
3917b929e7fSNick Fitzgerald     }
3927b929e7fSNick Fitzgerald }
3937b929e7fSNick Fitzgerald 
394183891f0SNick Fitzgerald impl<'a, T> IntoIterator for &'a TryVec<T> {
395e0ee4552SNick Fitzgerald     type Item = &'a T;
396e0ee4552SNick Fitzgerald 
397e0ee4552SNick Fitzgerald     type IntoIter = core::slice::Iter<'a, T>;
398e0ee4552SNick Fitzgerald 
into_iter(self) -> Self::IntoIter399e0ee4552SNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
400e0ee4552SNick Fitzgerald         (**self).iter()
401e0ee4552SNick Fitzgerald     }
402e0ee4552SNick Fitzgerald }
403e0ee4552SNick Fitzgerald 
404183891f0SNick Fitzgerald impl<'a, T> IntoIterator for &'a mut TryVec<T> {
405e0ee4552SNick Fitzgerald     type Item = &'a mut T;
406e0ee4552SNick Fitzgerald 
407e0ee4552SNick Fitzgerald     type IntoIter = core::slice::IterMut<'a, T>;
408e0ee4552SNick Fitzgerald 
into_iter(self) -> Self::IntoIter409e0ee4552SNick Fitzgerald     fn into_iter(self) -> Self::IntoIter {
410e0ee4552SNick Fitzgerald         (**self).iter_mut()
411e0ee4552SNick Fitzgerald     }
412e0ee4552SNick Fitzgerald }
41328f6f5e7SAlex Crichton 
414183891f0SNick Fitzgerald impl<T> From<TryVec<T>> for StdVec<T> {
from(v: TryVec<T>) -> Self415183891f0SNick Fitzgerald     fn from(v: TryVec<T>) -> Self {
416efb98a9fSNick Fitzgerald         v.inner
417efb98a9fSNick Fitzgerald     }
418efb98a9fSNick Fitzgerald }
419efb98a9fSNick Fitzgerald 
420183891f0SNick Fitzgerald impl<T> From<StdVec<T>> for TryVec<T> {
from(inner: StdVec<T>) -> Self421282546d4SNick Fitzgerald     fn from(inner: StdVec<T>) -> Self {
422282546d4SNick Fitzgerald         Self { inner }
423282546d4SNick Fitzgerald     }
424282546d4SNick Fitzgerald }
425282546d4SNick Fitzgerald 
426183891f0SNick Fitzgerald impl<T> From<Box<[T]>> for TryVec<T> {
from(boxed_slice: Box<[T]>) -> Self42728f6f5e7SAlex Crichton     fn from(boxed_slice: Box<[T]>) -> Self {
42871c51d03SNick Fitzgerald         Self::from(StdVec::from(boxed_slice))
42928f6f5e7SAlex Crichton     }
43028f6f5e7SAlex Crichton }
43171c51d03SNick Fitzgerald 
43272dccdfdSbjorn3 #[cfg(feature = "serde")]
433183891f0SNick Fitzgerald impl<T> serde::ser::Serialize for TryVec<T>
43471c51d03SNick Fitzgerald where
43571c51d03SNick Fitzgerald     T: serde::ser::Serialize,
43671c51d03SNick Fitzgerald {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,43771c51d03SNick Fitzgerald     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43871c51d03SNick Fitzgerald     where
43971c51d03SNick Fitzgerald         S: serde::Serializer,
44071c51d03SNick Fitzgerald     {
44171c51d03SNick Fitzgerald         let mut seq = serializer.serialize_seq(Some(self.len()))?;
44271c51d03SNick Fitzgerald         for elem in self {
44371c51d03SNick Fitzgerald             seq.serialize_element(elem)?;
44471c51d03SNick Fitzgerald         }
44571c51d03SNick Fitzgerald         seq.end()
44671c51d03SNick Fitzgerald     }
44771c51d03SNick Fitzgerald }
44871c51d03SNick Fitzgerald 
44972dccdfdSbjorn3 #[cfg(feature = "serde")]
450183891f0SNick Fitzgerald impl<'de, T> serde::de::Deserialize<'de> for TryVec<T>
45171c51d03SNick Fitzgerald where
45271c51d03SNick Fitzgerald     T: serde::de::Deserialize<'de>,
45371c51d03SNick Fitzgerald {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>,45471c51d03SNick Fitzgerald     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45571c51d03SNick Fitzgerald     where
45671c51d03SNick Fitzgerald         D: serde::Deserializer<'de>,
45771c51d03SNick Fitzgerald     {
45872dccdfdSbjorn3         use core::marker::PhantomData;
45972dccdfdSbjorn3 
460183891f0SNick Fitzgerald         struct Visitor<T>(PhantomData<fn() -> TryVec<T>>);
46171c51d03SNick Fitzgerald 
46271c51d03SNick Fitzgerald         impl<'de, T> serde::de::Visitor<'de> for Visitor<T>
46371c51d03SNick Fitzgerald         where
46471c51d03SNick Fitzgerald             T: serde::de::Deserialize<'de>,
46571c51d03SNick Fitzgerald         {
466183891f0SNick Fitzgerald             type Value = TryVec<T>;
46771c51d03SNick Fitzgerald 
46871c51d03SNick Fitzgerald             fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
46971c51d03SNick Fitzgerald                 f.write_str("a `wasmtime_core::alloc::Vec` sequence")
47071c51d03SNick Fitzgerald             }
47171c51d03SNick Fitzgerald 
47271c51d03SNick Fitzgerald             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
47371c51d03SNick Fitzgerald             where
47471c51d03SNick Fitzgerald                 A: serde::de::SeqAccess<'de>,
47571c51d03SNick Fitzgerald             {
47671c51d03SNick Fitzgerald                 use serde::de::Error as _;
47771c51d03SNick Fitzgerald 
478183891f0SNick Fitzgerald                 let mut v = TryVec::new();
47971c51d03SNick Fitzgerald 
48071c51d03SNick Fitzgerald                 if let Some(len) = seq.size_hint() {
48171c51d03SNick Fitzgerald                     v.reserve_exact(len).map_err(|oom| A::Error::custom(oom))?;
48271c51d03SNick Fitzgerald                 }
48371c51d03SNick Fitzgerald 
48471c51d03SNick Fitzgerald                 while let Some(elem) = seq.next_element()? {
48571c51d03SNick Fitzgerald                     v.push(elem).map_err(|oom| A::Error::custom(oom))?;
48671c51d03SNick Fitzgerald                 }
48771c51d03SNick Fitzgerald 
48871c51d03SNick Fitzgerald                 Ok(v)
48971c51d03SNick Fitzgerald             }
49071c51d03SNick Fitzgerald         }
49171c51d03SNick Fitzgerald 
49271c51d03SNick Fitzgerald         deserializer.deserialize_seq(Visitor(PhantomData))
49371c51d03SNick Fitzgerald     }
49428f6f5e7SAlex Crichton }
49528f6f5e7SAlex Crichton 
49628f6f5e7SAlex Crichton #[cfg(test)]
49728f6f5e7SAlex Crichton mod tests {
498183891f0SNick Fitzgerald     use super::TryVec;
49928f6f5e7SAlex Crichton     use crate::error::OutOfMemory;
50028f6f5e7SAlex Crichton 
50128f6f5e7SAlex Crichton     #[test]
test_into_boxed_slice() -> Result<(), OutOfMemory>50228f6f5e7SAlex Crichton     fn test_into_boxed_slice() -> Result<(), OutOfMemory> {
503183891f0SNick Fitzgerald         assert_eq!(*TryVec::<i32>::new().into_boxed_slice()?, []);
50428f6f5e7SAlex Crichton 
505183891f0SNick Fitzgerald         let mut vec = TryVec::new();
50628f6f5e7SAlex Crichton         vec.push(1)?;
50728f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
50828f6f5e7SAlex Crichton 
509183891f0SNick Fitzgerald         let mut vec = TryVec::with_capacity(2)?;
51028f6f5e7SAlex Crichton         vec.push(1)?;
51128f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
51228f6f5e7SAlex Crichton 
513183891f0SNick Fitzgerald         let mut vec = TryVec::with_capacity(2)?;
51428f6f5e7SAlex Crichton         vec.push(1_u128)?;
51528f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [1]);
51628f6f5e7SAlex Crichton 
517183891f0SNick Fitzgerald         assert_eq!(*TryVec::<()>::new().into_boxed_slice()?, []);
51828f6f5e7SAlex Crichton 
519183891f0SNick Fitzgerald         let mut vec = TryVec::new();
52028f6f5e7SAlex Crichton         vec.push(())?;
52128f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, [()]);
52228f6f5e7SAlex Crichton 
523183891f0SNick Fitzgerald         let vec = TryVec::<i32>::with_capacity(2)?;
52428f6f5e7SAlex Crichton         assert_eq!(*vec.into_boxed_slice()?, []);
52528f6f5e7SAlex Crichton         Ok(())
52628f6f5e7SAlex Crichton     }
52728f6f5e7SAlex Crichton }
528