Revision control
Copy as Markdown
Other Tools
use std::ptr;
use std::slice;
use crate::CapacityError;
/// Implements basic arrayvec methods - based on a few required methods
/// for length and element access.
pub(crate) trait ArrayVecImpl {
type Item;
const CAPACITY: usize;
fn len(&self) -> usize;
unsafe fn set_len(&mut self, new_len: usize);
/// Return a slice containing all elements of the vector.
fn as_slice(&self) -> &[Self::Item] {
let len = self.len();
unsafe {
slice::from_raw_parts(self.as_ptr(), len)
}
}
/// Return a mutable slice containing all elements of the vector.
fn as_mut_slice(&mut self) -> &mut [Self::Item] {
let len = self.len();
unsafe {
std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
/// Return a raw pointer to the vector's buffer.
fn as_ptr(&self) -> *const Self::Item;
/// Return a raw mutable pointer to the vector's buffer.
fn as_mut_ptr(&mut self) -> *mut Self::Item;
#[track_caller]
fn push(&mut self, element: Self::Item) {
self.try_push(element).unwrap()
}
fn try_push(&mut self, element: Self::Item) -> Result<(), CapacityError<Self::Item>> {
if self.len() < Self::CAPACITY {
unsafe {
self.push_unchecked(element);
}
Ok(())
} else {
Err(CapacityError::new(element))
}
}
unsafe fn push_unchecked(&mut self, element: Self::Item) {
let len = self.len();
debug_assert!(len < Self::CAPACITY);
ptr::write(self.as_mut_ptr().add(len), element);
self.set_len(len + 1);
}
fn pop(&mut self) -> Option<Self::Item> {
if self.len() == 0 {
return None;
}
unsafe {
let new_len = self.len() - 1;
self.set_len(new_len);
Some(ptr::read(self.as_ptr().add(new_len)))
}
}
fn clear(&mut self) {
self.truncate(0)
}
fn truncate(&mut self, new_len: usize) {
unsafe {
let len = self.len();
if new_len < len {
self.set_len(new_len);
let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len);
ptr::drop_in_place(tail);
}
}
}
}