use core::{
iter::{FromIterator, IntoIterator},
mem::MaybeUninit,
ops::*,
};
#[repr(align(16))] #[derive(Copy, Clone)]
pub struct Vector<T, const N: usize> {
pub(crate) inner: [T; N],
}
pub type Matrix<T, const M: usize, const N: usize> = Vector<Vector<T, M>, N>;
impl<T, const N: usize> Vector<T, N> {
pub(crate) fn uninit_inner() -> MaybeUninit<[T; N]> { MaybeUninit::uninit() }
pub fn ascend(self) -> Vector<Self, 1> { Vector { inner: [self] } }
}
pub trait Stupidity<T> {
fn build_with_fn<F: FnMut(usize) -> T>(f: F) -> Self;
}
impl<T, const N: usize> Stupidity<T> for Vector<T, N> {
fn build_with_fn<F: FnMut(usize) -> T>(mut f: F) -> Self {
let mut inner = Self::uninit_inner();
let base = inner.as_mut_ptr() as *mut T;
for offset in 0..N {
let element = f(offset);
unsafe {
base.add(offset).write(element);
}
}
let inner = unsafe { inner.assume_init() };
Self { inner }
}
}
impl<T, const N: usize> Index<usize> for Vector<T, N> {
type Output = T;
fn index(&self, index: usize) -> &T { &self.inner[index] }
}
impl<T, const N: usize> IndexMut<usize> for Vector<T, N> {
fn index_mut(&mut self, index: usize) -> &mut T { &mut self.inner[index] }
}
impl<T, const N: usize> FromIterator<T> for Vector<T, N> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut iter = iter.into_iter();
Self::build_with_fn(|_| iter.next().unwrap())
}
}
pub struct IntoIter<T, const N: usize> {
pos: usize,
data: [MaybeUninit<T>; N],
}
impl<T, const N: usize> IntoIter<T, N> {
fn new(vector: Vector<T, N>) -> Self {
let data = unsafe {
let data =
core::ptr::read(&vector.inner as *const [T; N] as *const [MaybeUninit<T>; N]);
core::mem::forget(vector);
data
};
IntoIter { pos: 0, data }
}
}
impl<T, const N: usize> Iterator for IntoIter<T, N> {
type Item = T;
fn next(&mut self) -> Option<T> {
if self.pos == N {
None
} else {
let out = unsafe { self.data.get_unchecked(self.pos).assume_init_read() };
self.pos += 1;
Some(out)
}
}
}
impl<T, const N: usize> Drop for IntoIter<T, N> {
fn drop(&mut self) { for _item in self {} }
}
impl<T, const N: usize> IntoIterator for Vector<T, N> {
type Item = T;
type IntoIter = IntoIter<T, { N }>;
fn into_iter(self) -> Self::IntoIter { IntoIter::new(self) }
}
use crate::consts::ConstIterator;
impl<'a, T, const N: usize> IntoIterator for &'a Vector<T, N> {
type Item = &'a T;
type IntoIter = ConstIterator<&'a T, &'a Vector<T, N>, N>;
fn into_iter(self) -> Self::IntoIter { self.into() }
}
impl<T: Default, const N: usize> Default for Vector<T, N> {
fn default() -> Self { Self::build_with_fn(|_| T::default()) }
}
impl<T: PartialEq, const N: usize> PartialEq for Vector<T, N> {
fn eq(&self, other: &Self) -> bool { self.into_iter().zip(other).all(|(s, o)| s == o) }
}
impl<T: Eq, const N: usize> Eq for Vector<T, N> {}
use core::fmt::Debug;
impl<T: Debug, const N: usize> Debug for Vector<T, N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
f.write_str("Vector<")?;
Debug::fmt(&N, f)?;
f.write_str(">[")?;
for i in self {
i.fmt(f)?;
f.write_str(", ")?;
}
f.write_str("]")?;
Ok(())
}
}
use core::fmt::Display;
impl<T: Display + Debug, const N: usize> Display for Vector<T, N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::result::Result<(), core::fmt::Error> {
if f.alternate() {
Debug::fmt(self, f)?;
} else {
f.write_str("Vector[\n")?;
for i in self {
Display::fmt(i, f)?;
f.write_str(",\n")?;
}
f.write_str("]")?;
}
Ok(())
}
}