#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
use std::ops::{Index, IndexMut};
#[doc(hidden)]
pub mod matrix;
#[doc(hidden)]
pub mod reftrix;
#[doc(hidden)]
pub mod stacktrix;
#[derive(Debug, Clone, Copy)]
pub struct ColumnPrio;
#[derive(Debug, Clone, Copy)]
pub struct RowPrio;
pub use matrix::Matrix;
pub use reftrix::Reftrix;
pub use stacktrix::Stacktrix;
pub trait ColumnPrioMatrix<T> {
fn insert(&mut self, row: usize, col: usize, value: T);
fn get(&self, row: usize, col: usize) -> &T;
fn get_mut(&mut self, row: usize, col: usize) -> &mut T;
fn fill_col(&mut self, col: usize, data: &[T]);
fn fill_row(&mut self, row: usize, data: &[T]);
fn get_column(&self, col: usize) -> &[T];
fn get_mut_column(&mut self, col: usize) -> &mut [T];
fn get_row(&self, row: usize) -> IntermittentSlice<'_, T>;
fn get_mut_row(&mut self, row: usize) -> IntermittentSliceMut<'_, T>;
fn rows(&self) -> IterIntermittentSlices<'_, T>;
fn rows_mut(&mut self) -> IterMutIntermittentSlices<'_, T>;
fn cols(&self) -> IterSlices<'_, T>;
fn cols_mut(&mut self) -> IterSlicesMut<'_, T>;
fn apply_all(&mut self, f: fn(_: &mut T));
fn pretty_print(&self);
}
pub trait RowPrioMatrix<T> {
fn insert(&mut self, row: usize, col: usize, value: T);
fn get(&self, row: usize, col: usize) -> &T;
fn get_mut(&mut self, row: usize, col: usize) -> &mut T;
fn fill_row(&mut self, row: usize, data: &[T]);
fn fill_col(&mut self, col: usize, data: &[T]);
fn get_column(&self, col: usize) -> IntermittentSlice<'_, T>;
fn get_mut_column(&mut self, col: usize) -> IntermittentSliceMut<'_, T>;
fn get_row(&self, row: usize) -> &[T];
fn get_mut_row(&mut self, row: usize) -> &mut [T];
fn rows(&self) -> IterSlices<'_, T>;
fn rows_mut(&mut self) -> IterSlicesMut<'_, T>;
fn cols(&self) -> IterIntermittentSlices<'_, T>;
fn cols_mut(&mut self) -> IterMutIntermittentSlices<'_, T>;
fn apply_all(&mut self, f: fn(_: &mut T));
fn pretty_print(&self);
}
pub struct IntermittentSlice<'a, T> {
start: &'a T,
slices: usize,
len: usize,
}
impl<'a, T> Index<usize> for IntermittentSlice<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
if index >= self.len {
panic!("Index {index} out of bounds {}", self.len);
}
unsafe { &*((self.start as *const T).add(index * self.slices)) }
}
}
pub struct IntermittentSliceMut<'a, T> {
start: &'a mut T,
slices: usize,
len: usize,
}
impl<'a, T> IntermittentSliceMut<'a, T> {
pub fn swap(&mut self, a: usize, b: usize) {
unsafe {
std::mem::swap(
&mut *(&mut self[a] as *mut T),
&mut *(&mut self[b] as *mut T),
);
}
}
}
impl<'a, T> Index<usize> for IntermittentSliceMut<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
if index >= self.len {
panic!("Index {index} out of bounds {}", self.len);
}
unsafe { &*((self.start as *const T).add(index * self.slices)) }
}
}
impl<'a, T> IndexMut<usize> for IntermittentSliceMut<'a, T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
if index >= self.len {
panic!("Index {index} out of bounds {}", self.len);
}
unsafe { &mut *((self.start as *mut T).add(index * self.slices)) }
}
}
#[doc(hidden)]
pub struct IntermittentSliceMutIntoItterator<'a, T> {
row: IntermittentSliceMut<'a, T>,
index: usize,
}
impl<'a, T> IntoIterator for IntermittentSliceMut<'a, T> {
type Item = &'a mut T;
type IntoIter = IntermittentSliceMutIntoItterator<'a, T>;
fn into_iter(self) -> Self::IntoIter {
IntermittentSliceMutIntoItterator {
row: self,
index: 0,
}
}
}
impl<'a, T> Iterator for IntermittentSliceMutIntoItterator<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.row.len {
return None;
}
unsafe {
let next = &mut *((self.row.start as *mut T).add(self.index * self.row.slices));
self.index += 1;
Some(next)
}
}
}
#[doc(hidden)]
pub struct IntermittentSliceIntoItterator<'a, T> {
row: IntermittentSlice<'a, T>,
index: usize,
}
impl<'a, T> IntoIterator for IntermittentSlice<'a, T> {
type Item = &'a T;
type IntoIter = IntermittentSliceIntoItterator<'a, T>;
fn into_iter(self) -> Self::IntoIter {
IntermittentSliceIntoItterator {
row: self,
index: 0,
}
}
}
impl<'a, T> Iterator for IntermittentSliceIntoItterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.row.len {
return None;
}
unsafe {
let next = &*((self.row.start as *const T).add(self.index * self.row.slices));
self.index += 1;
Some(next)
}
}
}
pub struct IterIntermittentSlices<'a, T> {
slice_index: usize,
matrix_buffer: &'a [T],
slices: usize,
len: usize,
}
impl<'a, T> Iterator for IterIntermittentSlices<'a, T> {
type Item = IntermittentSlice<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.slice_index >= self.slices {
return None;
};
let r = IntermittentSlice {
start: &self.matrix_buffer[self.slice_index],
slices: self.slices,
len: self.len,
};
self.slice_index += 1;
Some(r)
}
}
pub struct IterMutIntermittentSlices<'a, T> {
slice_index: usize,
matrix_buffer: &'a mut [T],
slices: usize,
len: usize,
}
impl<'a, T> Iterator for IterMutIntermittentSlices<'a, T>
where
Self: 'a,
{
type Item = IntermittentSliceMut<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.slice_index >= self.slices {
return None;
};
let row = IntermittentSliceMut {
start: unsafe { std::mem::transmute(&mut self.matrix_buffer[self.slice_index]) },
slices: self.slices,
len: self.len,
};
self.slice_index += 1;
Some(row)
}
}
pub struct IterSlices<'a, T> {
matrix_buffer: &'a [T],
len: usize,
}
impl<'a, T> Iterator for IterSlices<'a, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.matrix_buffer.is_empty() {
return None;
};
let (r, rest) = self.matrix_buffer.split_at(self.len);
self.matrix_buffer = rest;
Some(r)
}
}
pub struct IterSlicesMut<'a, T> {
matrix_buffer: &'a mut [T],
len: usize,
}
impl<'a, T> Iterator for IterSlicesMut<'a, T> {
type Item = &'a mut [T];
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if self.matrix_buffer.is_empty() {
return None;
};
let (r, rest): (&mut [T], &mut [T]) =
std::mem::transmute(self.matrix_buffer.split_at_mut(self.len));
self.matrix_buffer = rest;
Some(r)
}
}
}