88 lines
2.3 KiB
Rust
88 lines
2.3 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|