1 use crate::alloc::{TryClone, try_realloc}; 2 use crate::error::OutOfMemory; 3 use core::{ 4 fmt, mem, 5 ops::{Deref, DerefMut, Index, IndexMut}, 6 }; 7 use std_alloc::alloc::Layout; 8 use std_alloc::boxed::Box; 9 use std_alloc::vec::Vec as StdVec; 10 11 /// Like `std::vec::Vec` but all methods that allocate force handling allocation 12 /// failure. 13 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] 14 pub struct Vec<T> { 15 inner: StdVec<T>, 16 } 17 18 impl<T> Default for Vec<T> { 19 fn default() -> Self { 20 Self { 21 inner: Default::default(), 22 } 23 } 24 } 25 26 impl<T: fmt::Debug> fmt::Debug for Vec<T> { 27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 28 fmt::Debug::fmt(&self.inner, f) 29 } 30 } 31 32 impl<T> TryClone for Vec<T> 33 where 34 T: TryClone, 35 { 36 fn try_clone(&self) -> Result<Self, OutOfMemory> { 37 let mut v = Vec::with_capacity(self.len())?; 38 for x in self { 39 v.push(x.try_clone()?).expect("reserved capacity"); 40 } 41 Ok(v) 42 } 43 } 44 45 impl<T> Vec<T> { 46 /// Same as [`std::vec::Vec::new`]. 47 pub const fn new() -> Self { 48 Self { 49 inner: StdVec::new(), 50 } 51 } 52 53 /// Same as [`std::vec::Vec::with_capacity`] but returns an error on 54 /// allocation failure. 55 pub fn with_capacity(capacity: usize) -> Result<Self, OutOfMemory> { 56 let mut v = Self::new(); 57 v.reserve(capacity)?; 58 Ok(v) 59 } 60 61 /// Same as [`std::vec::Vec::reserve`] but returns an error on allocation 62 /// failure. 63 pub fn reserve(&mut self, additional: usize) -> Result<(), OutOfMemory> { 64 self.inner.try_reserve(additional).map_err(|_| { 65 OutOfMemory::new( 66 self.len() 67 .saturating_add(additional) 68 .saturating_mul(mem::size_of::<T>()), 69 ) 70 }) 71 } 72 73 /// Same as [`std::vec::Vec::reserve_exact`] but returns an error on allocation 74 /// failure. 75 pub fn reserve_exact(&mut self, additional: usize) -> Result<(), OutOfMemory> { 76 self.inner 77 .try_reserve_exact(additional) 78 .map_err(|_| OutOfMemory::new(self.len().saturating_add(additional))) 79 } 80 81 /// Same as [`std::vec::Vec::len`]. 82 pub fn len(&self) -> usize { 83 self.inner.len() 84 } 85 86 /// Same as [`std::vec::Vec::capacity`]. 87 pub fn capacity(&self) -> usize { 88 self.inner.capacity() 89 } 90 91 /// Same as [`std::vec::Vec::is_empty`]. 92 pub fn is_empty(&self) -> bool { 93 self.inner.is_empty() 94 } 95 96 /// Same as [`std::vec::Vec::push`] but returns an error on allocation 97 /// failure. 98 pub fn push(&mut self, value: T) -> Result<(), OutOfMemory> { 99 self.reserve(1)?; 100 self.inner.push(value); 101 Ok(()) 102 } 103 104 /// Same as [`std::vec::Vec::pop`]. 105 pub fn pop(&mut self) -> Option<T> { 106 self.inner.pop() 107 } 108 109 /// Same as [`std::vec::Vec::into_raw_parts`]. 110 pub fn into_raw_parts(mut self) -> (*mut T, usize, usize) { 111 // NB: Can't use `Vec::into_raw_parts` until our MSRV is >= 1.93. 112 #[cfg(not(miri))] 113 { 114 let ptr = self.as_mut_ptr(); 115 let len = self.len(); 116 let cap = self.capacity(); 117 mem::forget(self); 118 (ptr, len, cap) 119 } 120 // NB: Miri requires using `into_raw_parts`, but always run on nightly, 121 // so it's fine to use there. 122 #[cfg(miri)] 123 { 124 let _ = &mut self; 125 self.inner.into_raw_parts() 126 } 127 } 128 129 /// Same as [`std::vec::Vec::from_raw_parts`]. 130 pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { 131 Vec { 132 // Safety: Same as our unsafe contract. 133 inner: unsafe { StdVec::from_raw_parts(ptr, length, capacity) }, 134 } 135 } 136 137 /// Same as [`std::vec::Vec::drain`]. 138 pub fn drain<R>(&mut self, range: R) -> std_alloc::vec::Drain<'_, T> 139 where 140 R: core::ops::RangeBounds<usize>, 141 { 142 self.inner.drain(range) 143 } 144 145 /// Same as [`std::vec::Vec::shrink_to_fit`] but returns an error on 146 /// allocation failure. 147 pub fn shrink_to_fit(&mut self) -> Result<(), OutOfMemory> { 148 // If our length is already equal to our capacity, then there is nothing 149 // to shrink. 150 if self.len() == self.capacity() { 151 return Ok(()); 152 } 153 154 // `realloc` requires a non-zero original layout as well as a non-zero 155 // destination layout, so this guard ensures that the sizes below are 156 // all nonzero. This handles a few cases: 157 // 158 // * If `len == cap == 0` then no allocation has ever been made. 159 // * If `len == 0` and `cap != 0` then this function effectively frees 160 // the memory. 161 // * If `T` is a zero-sized type then nothing's been allocated either. 162 // 163 // In all of these cases delegate to the standard library's 164 // `shrink_to_fit` which is guaranteed to not perform a `realloc`. 165 if self.is_empty() || mem::size_of::<T>() == 0 { 166 self.inner.shrink_to_fit(); 167 return Ok(()); 168 } 169 170 let (ptr, len, cap) = mem::take(self).into_raw_parts(); 171 let layout = Layout::array::<T>(cap).unwrap(); 172 let new_size = Layout::array::<T>(len).unwrap().size(); 173 174 // SAFETY: `ptr` was previously allocated in the global allocator, 175 // `layout` has a nonzero size and matches the current allocation of 176 // `ptr`, `new_size` is nonzero, and `new_size` is a valid array size 177 // for `len` elements given its constructor. 178 let result = unsafe { try_realloc(ptr.cast(), layout, new_size) }; 179 180 match result { 181 Ok(ptr) => { 182 // SAFETY: `result` is allocated with the global allocator and 183 // has room for exactly `[T; len]`. 184 *self = unsafe { Self::from_raw_parts(ptr.cast::<T>().as_ptr(), len, len) }; 185 Ok(()) 186 } 187 Err(oom) => { 188 // SAFETY: If reallocation fails then it's guaranteed that the 189 // original allocation is not tampered with, so it's safe to 190 // reassemble the original vector. 191 *self = unsafe { Vec::from_raw_parts(ptr, len, cap) }; 192 Err(oom) 193 } 194 } 195 } 196 197 /// Same as [`std::vec::Vec::into_boxed_slice`] but returns an error on 198 /// allocation failure. 199 pub fn into_boxed_slice(mut self) -> Result<Box<[T]>, OutOfMemory> { 200 self.shrink_to_fit()?; 201 202 // Once we've shrunken the allocation to just the actual length, we can 203 // use `std`'s `into_boxed_slice` without fear of `realloc`. 204 Ok(self.inner.into_boxed_slice()) 205 } 206 } 207 208 impl<T> Deref for Vec<T> { 209 type Target = [T]; 210 211 fn deref(&self) -> &Self::Target { 212 &self.inner 213 } 214 } 215 216 impl<T> DerefMut for Vec<T> { 217 fn deref_mut(&mut self) -> &mut Self::Target { 218 &mut self.inner 219 } 220 } 221 222 impl<T> Index<usize> for Vec<T> { 223 type Output = T; 224 225 fn index(&self, index: usize) -> &Self::Output { 226 &self.inner[index] 227 } 228 } 229 230 impl<T> IndexMut<usize> for Vec<T> { 231 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 232 &mut self.inner[index] 233 } 234 } 235 236 impl<T> IntoIterator for Vec<T> { 237 type Item = T; 238 type IntoIter = std_alloc::vec::IntoIter<T>; 239 240 fn into_iter(self) -> Self::IntoIter { 241 self.inner.into_iter() 242 } 243 } 244 245 impl<'a, T> IntoIterator for &'a Vec<T> { 246 type Item = &'a T; 247 248 type IntoIter = core::slice::Iter<'a, T>; 249 250 fn into_iter(self) -> Self::IntoIter { 251 (**self).iter() 252 } 253 } 254 255 impl<'a, T> IntoIterator for &'a mut Vec<T> { 256 type Item = &'a mut T; 257 258 type IntoIter = core::slice::IterMut<'a, T>; 259 260 fn into_iter(self) -> Self::IntoIter { 261 (**self).iter_mut() 262 } 263 } 264 265 impl<T> From<Box<[T]>> for Vec<T> { 266 fn from(boxed_slice: Box<[T]>) -> Self { 267 Vec { 268 inner: StdVec::from(boxed_slice), 269 } 270 } 271 } 272 273 #[cfg(test)] 274 mod tests { 275 use super::Vec; 276 use crate::error::OutOfMemory; 277 278 #[test] 279 fn test_into_boxed_slice() -> Result<(), OutOfMemory> { 280 assert_eq!(*Vec::<i32>::new().into_boxed_slice()?, []); 281 282 let mut vec = Vec::new(); 283 vec.push(1)?; 284 assert_eq!(*vec.into_boxed_slice()?, [1]); 285 286 let mut vec = Vec::with_capacity(2)?; 287 vec.push(1)?; 288 assert_eq!(*vec.into_boxed_slice()?, [1]); 289 290 let mut vec = Vec::with_capacity(2)?; 291 vec.push(1_u128)?; 292 assert_eq!(*vec.into_boxed_slice()?, [1]); 293 294 assert_eq!(*Vec::<()>::new().into_boxed_slice()?, []); 295 296 let mut vec = Vec::new(); 297 vec.push(())?; 298 assert_eq!(*vec.into_boxed_slice()?, [()]); 299 300 let vec = Vec::<i32>::with_capacity(2)?; 301 assert_eq!(*vec.into_boxed_slice()?, []); 302 Ok(()) 303 } 304 } 305