mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-12 07:44:18 +00:00
These are required as this goes across the IPC boundary. Signed-off-by: Sean Cross <sean@xobs.io>
153 lines
3.8 KiB
Rust
153 lines
3.8 KiB
Rust
use std::mem::MaybeUninit;
|
|
|
|
pub struct Vec<T, const N: usize> {
|
|
length: usize,
|
|
buffer: [MaybeUninit<T>; N],
|
|
}
|
|
|
|
unsafe impl<T, const N: usize> crate::IpcSafe for Vec<T, N> {}
|
|
|
|
impl<T, const N: usize> Vec<T, N> {
|
|
pub fn new() -> Self {
|
|
let buffer = [const { MaybeUninit::uninit() }; N];
|
|
Vec { buffer, length: 0 }
|
|
}
|
|
|
|
pub fn push(&mut self, value: T) {
|
|
if self.length < N {
|
|
self.buffer[self.length] = MaybeUninit::new(value);
|
|
self.length += 1;
|
|
}
|
|
}
|
|
|
|
pub fn pop(&mut self) -> Option<T> {
|
|
assert!(self.length <= self.buffer.len());
|
|
if self.length > 0 {
|
|
self.length -= 1;
|
|
unsafe { Some(self.buffer[self.length].as_ptr().read()) }
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
assert!(self.length <= self.buffer.len());
|
|
self.length
|
|
}
|
|
|
|
pub fn as_slice(&self) -> &[T] {
|
|
assert!(self.length <= self.buffer.len());
|
|
unsafe { core::slice::from_raw_parts(self.buffer.as_ptr() as *const T, self.length) }
|
|
}
|
|
|
|
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
|
assert!(self.length <= self.buffer.len());
|
|
unsafe { core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as *mut T, self.length) }
|
|
}
|
|
|
|
pub fn clear(&mut self) {
|
|
assert!(self.length <= self.buffer.len());
|
|
for i in 0..self.length {
|
|
unsafe {
|
|
core::ptr::drop_in_place(&mut self.buffer[i]);
|
|
}
|
|
}
|
|
self.length = 0;
|
|
}
|
|
|
|
pub fn iter(&self) -> core::slice::Iter<'_, T> { self.as_slice().iter() }
|
|
|
|
pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> { self.as_mut_slice().iter_mut() }
|
|
|
|
pub fn resize(&mut self, new_len: usize, value: T)
|
|
where
|
|
T: Clone,
|
|
{
|
|
assert!(self.length <= self.buffer.len());
|
|
if new_len > self.length {
|
|
for _ in self.length..new_len {
|
|
self.push(value.clone());
|
|
}
|
|
} else {
|
|
self.length = new_len;
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> Drop for Vec<T, N> {
|
|
fn drop(&mut self) { self.clear(); }
|
|
}
|
|
|
|
impl<T, const N: usize> core::fmt::Debug for Vec<T, N>
|
|
where
|
|
T: core::fmt::Debug,
|
|
{
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
f.debug_list().entries(self.iter()).finish()
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> Default for Vec<T, N> {
|
|
fn default() -> Self { Vec::new() }
|
|
}
|
|
|
|
impl<T, const N: usize> core::ops::Deref for Vec<T, N> {
|
|
type Target = [T];
|
|
|
|
fn deref(&self) -> &Self::Target { self.as_slice() }
|
|
}
|
|
|
|
impl<T, const N: usize> core::ops::DerefMut for Vec<T, N> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() }
|
|
}
|
|
|
|
impl<T, const N: usize> From<&[T]> for Vec<T, N>
|
|
where
|
|
T: Clone,
|
|
{
|
|
fn from(value: &[T]) -> Self {
|
|
let mut vec = Vec::new();
|
|
for item in value {
|
|
vec.push(item.clone());
|
|
}
|
|
vec
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> From<&mut [T]> for Vec<T, N>
|
|
where
|
|
T: Clone,
|
|
{
|
|
fn from(value: &mut [T]) -> Self {
|
|
let mut vec = Vec::new();
|
|
for item in value {
|
|
vec.push(item.clone());
|
|
}
|
|
vec
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> core::fmt::Display for Vec<T, N>
|
|
where
|
|
T: core::fmt::Display,
|
|
{
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
for (i, item) in self.iter().enumerate() {
|
|
if i > 0 {
|
|
write!(f, ", ")?;
|
|
}
|
|
write!(f, "{}", item)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl<T, const N: usize> core::ops::Index<usize> for Vec<T, N> {
|
|
type Output = T;
|
|
|
|
fn index(&self, index: usize) -> &Self::Output { &self.as_slice()[index] }
|
|
}
|
|
|
|
impl<T, const N: usize> core::ops::IndexMut<usize> for Vec<T, N> {
|
|
fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.as_mut_slice()[index] }
|
|
}
|