1 use std::ptr; 2 use std::slice; 3 4 use crate::CapacityError; 5 6 /// Implements basic arrayvec methods - based on a few required methods 7 /// for length and element access. 8 pub(crate) trait ArrayVecImpl { 9 type Item; 10 const CAPACITY: usize; 11 len(&self) -> usize12 fn len(&self) -> usize; 13 set_len(&mut self, new_len: usize)14 unsafe fn set_len(&mut self, new_len: usize); 15 16 /// Return a slice containing all elements of the vector. as_slice(&self) -> &[Self::Item]17 fn as_slice(&self) -> &[Self::Item] { 18 let len = self.len(); 19 unsafe { 20 slice::from_raw_parts(self.as_ptr(), len) 21 } 22 } 23 24 /// Return a mutable slice containing all elements of the vector. as_mut_slice(&mut self) -> &mut [Self::Item]25 fn as_mut_slice(&mut self) -> &mut [Self::Item] { 26 let len = self.len(); 27 unsafe { 28 std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) 29 } 30 } 31 32 /// Return a raw pointer to the vector's buffer. as_ptr(&self) -> *const Self::Item33 fn as_ptr(&self) -> *const Self::Item; 34 35 /// Return a raw mutable pointer to the vector's buffer. as_mut_ptr(&mut self) -> *mut Self::Item36 fn as_mut_ptr(&mut self) -> *mut Self::Item; 37 38 #[track_caller] push(&mut self, element: Self::Item)39 fn push(&mut self, element: Self::Item) { 40 self.try_push(element).unwrap() 41 } 42 try_push(&mut self, element: Self::Item) -> Result<(), CapacityError<Self::Item>>43 fn try_push(&mut self, element: Self::Item) -> Result<(), CapacityError<Self::Item>> { 44 if self.len() < Self::CAPACITY { 45 unsafe { 46 self.push_unchecked(element); 47 } 48 Ok(()) 49 } else { 50 Err(CapacityError::new(element)) 51 } 52 } 53 push_unchecked(&mut self, element: Self::Item)54 unsafe fn push_unchecked(&mut self, element: Self::Item) { 55 let len = self.len(); 56 debug_assert!(len < Self::CAPACITY); 57 ptr::write(self.as_mut_ptr().add(len), element); 58 self.set_len(len + 1); 59 } 60 pop(&mut self) -> Option<Self::Item>61 fn pop(&mut self) -> Option<Self::Item> { 62 if self.len() == 0 { 63 return None; 64 } 65 unsafe { 66 let new_len = self.len() - 1; 67 self.set_len(new_len); 68 Some(ptr::read(self.as_ptr().add(new_len))) 69 } 70 } 71 clear(&mut self)72 fn clear(&mut self) { 73 self.truncate(0) 74 } 75 truncate(&mut self, new_len: usize)76 fn truncate(&mut self, new_len: usize) { 77 unsafe { 78 let len = self.len(); 79 if new_len < len { 80 self.set_len(new_len); 81 let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len); 82 ptr::drop_in_place(tail); 83 } 84 } 85 } 86 } 87 88