pub unsafe trait ConstIndex<T, const N: usize> {
fn i(self, index: usize) -> T;
}
use crate::Vector;
unsafe impl<'a, T, const N: usize> ConstIndex<&'a T, N> for &'a Vector<T, N> {
fn i(self, index: usize) -> &'a T { &self.inner[index] }
}
unsafe impl<'a, T, const N: usize> ConstIndex<T, N> for Vector<T, N>
where
T: Copy,
{
fn i(self, index: usize) -> T { *&self.inner[index] }
}
unsafe impl<'a, T, const N: usize> ConstIndex<&'a mut T, N> for &'a mut Vector<T, N> {
fn i(self, index: usize) -> &'a mut T { &mut self.inner[index] }
}
use crate::VectorView;
unsafe impl<'a, T, const M: usize, const N: usize> ConstIndex<&'a T, M>
for VectorView<'a, T, M, N>
{
fn i(self, index: usize) -> &'a T {
let row = &self.matrix[index];
&row[self.row]
}
}
unsafe impl<'a, T, const M: usize, const N: usize> ConstIndex<VectorView<'a, T, M, N>, N>
for crate::TransposedMatrixView<'a, T, M, N>
{
fn i(self, index: usize) -> VectorView<'a, T, M, N> {
debug_assert!(index <= M);
VectorView {
row: index,
matrix: self.matrix,
}
}
}
pub struct ConstIterator<T, C: ConstIndex<T, N>, const N: usize> {
pub(crate) pos: usize,
pub(crate) content: C,
pub(crate) marker: core::marker::PhantomData<T>,
}
impl<T, C: ConstIndex<T, N> + Copy, const N: usize> Iterator for ConstIterator<T, C, N> {
type Item = T;
fn next(&mut self) -> Option<T> {
if self.pos < N {
let ret = self.content.i(self.pos);
self.pos += 1;
Some(ret)
} else {
None
}
}
}
impl<C, T, const N: usize> From<C> for ConstIterator<T, C, N>
where
C: ConstIndex<T, N>,
{
fn from(content: C) -> Self {
Self {
pos: 0,
content,
marker: Default::default(),
}
}
}
pub struct ConstIteratorMut<'a, T, C, const N: usize> {
pos: usize,
content: *mut C,
marker: core::marker::PhantomData<&'a mut T>,
}
impl<'a, T: 'a, C: 'a, const N: usize> Iterator for ConstIteratorMut<'a, T, C, N>
where
&'a mut C: ConstIndex<&'a mut T, N>,
{
type Item = &'a mut T;
fn next(&mut self) -> Option<&'a mut T> {
if self.pos < N {
let content: &mut C = unsafe { core::mem::transmute(self.content) };
let ret = content.i(self.pos);
self.pos += 1;
Some(ret)
} else {
None
}
}
}
impl<'a, T, C: 'a, const N: usize> From<&'a mut C> for ConstIteratorMut<'a, T, C, N>
where
&'a mut C: ConstIndex<&'a mut T, N>,
{
fn from(content: &'a mut C) -> Self {
Self {
pos: 0,
content: content as *mut _,
marker: Default::default(),
}
}
}
#[test]
fn const_iter() {
use crate::Vector;
use rand::{thread_rng, Rng};
let mut rng = thread_rng();
let a: Vector<f32, 40> = rng.gen();
let iter: ConstIterator<&f32, _, 40> = ConstIterator {
pos: 0,
content: &a,
marker: Default::default(),
};
let _s: f32 = iter.sum();
}