use alloc::format;
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};
pub mod polymorphic_vec;
pub mod relocatable_vec;
pub mod static_vec;
use iceoryx2_log::fail;
pub use polymorphic_vec::*;
pub use relocatable_vec::*;
pub use static_vec::*;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum VectorModificationError {
OutOfBounds,
InsertWouldExceedCapacity,
}
impl core::fmt::Display for VectorModificationError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "VectorModificationError::{self:?}")
}
}
impl core::error::Error for VectorModificationError {}
pub(crate) mod internal {
use super::*;
#[doc(hidden)]
pub trait VectorView<T> {
fn data(&self) -> &[MaybeUninit<T>];
unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>];
unsafe fn set_len(&mut self, len: u64);
}
}
pub trait Vector<T>: Deref<Target = [T]> + DerefMut + internal::VectorView<T> {
fn as_mut_slice(&mut self) -> &mut [T] {
let len = self.len();
unsafe {
core::mem::transmute::<&mut [MaybeUninit<T>], &mut [T]>(&mut self.data_mut()[0..len])
}
}
fn as_slice(&self) -> &[T] {
let len = self.len();
unsafe { core::mem::transmute::<&[MaybeUninit<T>], &[T]>(&self.data()[0..len]) }
}
fn capacity(&self) -> usize;
fn clear(&mut self) {
let len = self.len();
let data = unsafe { self.data_mut() };
for idx in (0..len).rev() {
unsafe { data[idx].assume_init_drop() };
}
unsafe { self.set_len(0) };
}
fn extend_from_slice(&mut self, other: &[T]) -> Result<(), VectorModificationError>
where
T: Clone,
{
if self.capacity() < self.len() + other.len() {
let origin = format!(
"Vector::<{}>::extend_from_slice()",
core::any::type_name::<T>()
);
fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
"Unable to extend vector from slice with length {} since it would exceed the vectors capacity of {}.",
other.len(), self.capacity());
}
let len = self.len();
let data = unsafe { self.data_mut() };
for (i, element) in other.iter().enumerate() {
data[i + len].write(element.clone());
}
unsafe { self.set_len(self.len() as u64 + other.len() as u64) };
Ok(())
}
unsafe fn extend_from_slice_unchecked(&mut self, other: &[T])
where
T: Clone,
{
let len = self.len();
let data = unsafe { self.data_mut() };
for (i, element) in other.iter().enumerate() {
data[i + len].write(element.clone());
}
unsafe { self.set_len(self.len() as u64 + other.len() as u64) };
}
fn insert(&mut self, index: usize, element: T) -> Result<(), VectorModificationError> {
if self.is_full() {
let origin = format!("Vector::<{}>::insert()", core::any::type_name::<T>());
fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
"Failed to insert element into vector since it would exceed the vectors capacity of {}.",
self.capacity());
}
let len = self.len();
if index > len {
let origin = format!("Vector::<{}>::insert()", core::any::type_name::<T>());
fail!(from origin, with VectorModificationError::OutOfBounds,
"Failed to insert element into vector of length {} since the index {} is out-of-bounds.",
self.len(), index);
}
let data = unsafe { self.data_mut() };
if index != len {
let ptr = data.as_mut_ptr();
unsafe { core::ptr::copy(ptr.add(index), ptr.add(index + 1), len - index) };
}
data[index].write(element);
unsafe { self.set_len(len as u64 + 1) };
Ok(())
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn is_full(&self) -> bool {
self.len() == self.capacity()
}
fn len(&self) -> usize;
fn pop(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
let len = self.len();
let data = unsafe { self.data_mut() };
let value = core::mem::replace(&mut data[len - 1], MaybeUninit::uninit());
unsafe { self.set_len(len as u64 - 1) };
Some(unsafe { value.assume_init() })
}
fn push(&mut self, value: T) -> Result<(), VectorModificationError> {
if self.is_full() {
let origin = format!("Vector::<{}>::push()", core::any::type_name::<T>());
fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
"Failed to push element into vector since it would exceed the vectors capacity of {}.",
self.capacity());
}
unsafe { self.push_unchecked(value) };
Ok(())
}
unsafe fn push_unchecked(&mut self, value: T) {
let len = self.len();
unsafe { self.data_mut()[len].write(value) };
unsafe { self.set_len(len as u64 + 1) };
}
fn remove(&mut self, index: usize) -> Option<T> {
let len = self.len();
if len <= index {
return None;
}
let data = unsafe { self.data_mut() };
let value = unsafe { core::ptr::read(data[index].as_ptr()) };
let ptr = data.as_mut_ptr();
unsafe { core::ptr::copy(ptr.add(index + 1), ptr.add(index), len - index - 1) };
unsafe { self.set_len(len as u64 - 1) };
Some(value)
}
fn resize(&mut self, new_len: usize, value: T) -> Result<(), VectorModificationError>
where
T: Clone,
{
self.resize_with(new_len, || value.clone())
}
fn resize_with<F: FnMut() -> T>(
&mut self,
new_len: usize,
mut f: F,
) -> Result<(), VectorModificationError> {
let capacity = self.capacity();
if capacity < new_len {
let origin = format!("Vector::<{}>::resize_with()", core::any::type_name::<T>());
fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
"Failed to resize vector to {} since it would exceed the vectors capacity of {}.",
new_len, self.capacity());
}
if new_len < self.len() {
self.truncate(new_len);
} else {
let len = self.len();
let data = unsafe { self.data_mut() };
for item in data.iter_mut().take(new_len).skip(len) {
item.write(f());
}
unsafe { self.set_len(new_len as u64) };
}
Ok(())
}
fn truncate(&mut self, new_len: usize) {
let len = self.len();
if len <= new_len {
return;
}
let data = unsafe { self.data_mut() };
for idx in (new_len..len).rev() {
unsafe { data[idx].assume_init_drop() };
}
unsafe { self.set_len(new_len as u64) };
}
}