#![no_std]
use core::{
fmt,
mem::{replace, MaybeUninit},
ops::{Deref, DerefMut},
ptr,
};
unsafe fn take<T>(dest: &mut MaybeUninit<T>) -> T {
replace(dest, MaybeUninit::uninit()).assume_init()
}
pub struct Array<T, const N: usize> {
len: usize,
data: [MaybeUninit<T>; N],
}
impl<T, const N: usize> Array<T, N> {
pub fn new() -> Self {
Self::default()
}
pub fn capacity(&self) -> usize {
N
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_full(&self) -> bool {
self.len >= N
}
pub fn remaing(&self) -> usize {
N - self.len
}
pub fn push(&mut self, val: T) {
self.data[self.len] = MaybeUninit::new(val);
self.len += 1;
}
pub fn pop(&mut self) -> T {
self.len -= 1;
unsafe { take(&mut self.data[self.len]) }
}
pub fn clear(&mut self) {
for slot in &mut self.data[0..self.len] {
unsafe {
ptr::drop_in_place(slot.as_mut_ptr());
}
}
self.len = 0;
}
pub fn insert(&mut self, index: usize, val: T) {
assert!(index <= self.len);
for i in (index..self.len).rev() {
self.data[i + 1] = replace(&mut self.data[i], MaybeUninit::uninit());
}
self.data[index] = MaybeUninit::new(val);
self.len += 1;
}
pub fn remove(&mut self, index: usize) -> T {
assert!(index < self.len);
let value = unsafe { take(&mut self.data[index]) };
self.len -= 1;
for i in index..self.len {
self.data[i] = replace(&mut self.data[i + 1], MaybeUninit::uninit());
}
value
}
}
impl<T, const N: usize> Default for Array<T, N> {
fn default() -> Self {
Self {
len: 0,
data: unsafe { MaybeUninit::uninit().assume_init() },
}
}
}
impl<T, const N: usize> AsRef<[T]> for Array<T, N> {
fn as_ref(&self) -> &[T] {
unsafe { &*(&self.data[..self.len] as *const [MaybeUninit<T>] as *const [T]) }
}
}
impl<T, const N: usize> AsMut<[T]> for Array<T, N> {
fn as_mut(&mut self) -> &mut [T] {
unsafe { &mut *(&mut self.data[..self.len] as *mut [MaybeUninit<T>] as *mut [T]) }
}
}
impl<T, const N: usize> Deref for Array<T, N> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl<T, const N: usize> DerefMut for Array<T, N> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut()
}
}
impl<T, const N: usize> Drop for Array<T, N> {
fn drop(&mut self) {
self.clear();
}
}
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<T, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Array")
.field("len", &self.len)
.field("data", &self.as_ref())
.finish()
}
}
impl<T: Clone, const N: usize> From<&[T]> for Array<T, N> {
fn from(values: &[T]) -> Self {
let mut array = Self::default();
for val in values {
array.push(val.clone());
}
array
}
}
impl<T, const N: usize, const S: usize> From<[T; S]> for Array<T, N> {
fn from(values: [T; S]) -> Self {
let mut array = Self::default();
for val in values {
array.push(val);
}
array
}
}