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