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