use crate::matrices::views::{DataLayout, MatrixMut, MatrixRef, NoInteriorMutability};
use crate::matrices::{Column, Row};
use crate::tensors::views::reverse_indexes;
use std::marker::PhantomData;
#[derive(Clone, Debug)]
pub struct MatrixReverse<T, S> {
source: S,
rows: bool,
columns: bool,
_type: PhantomData<T>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
pub struct Reverse {
pub rows: bool,
pub columns: bool,
}
impl<T, S> MatrixReverse<T, S>
where
S: MatrixRef<T>,
{
pub fn from(source: S, reverse: Reverse) -> MatrixReverse<T, S> {
MatrixReverse {
source,
rows: reverse.rows,
columns: reverse.columns,
_type: PhantomData,
}
}
#[allow(dead_code)]
pub fn source(self) -> S {
self.source
}
#[allow(dead_code)]
pub fn source_ref(&self) -> &S {
&self.source
}
#[allow(dead_code)]
pub fn source_ref_mut(&mut self) -> &mut S {
&mut self.source
}
}
unsafe impl<T, S> NoInteriorMutability for MatrixReverse<T, S> where S: NoInteriorMutability {}
unsafe impl<T, S> MatrixRef<T> for MatrixReverse<T, S>
where
S: MatrixRef<T>,
{
fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
if self.source.view_rows() == 0 || self.source.view_columns() == 0 {
return None;
}
let [row, column] = reverse_indexes(
&[row, column],
&[
("row", self.source.view_rows()),
("column", self.source.view_columns()),
],
&[self.rows, self.columns],
);
self.source.try_get_reference(row, column)
}
fn view_rows(&self) -> Row {
self.source.view_rows()
}
fn view_columns(&self) -> Column {
self.source.view_columns()
}
unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
unsafe {
let [row, column] = reverse_indexes(
&[row, column],
&[
("row", self.source.view_rows()),
("column", self.source.view_columns()),
],
&[self.rows, self.columns],
);
self.source.get_reference_unchecked(row, column)
}
}
fn data_layout(&self) -> DataLayout {
DataLayout::Other
}
}
unsafe impl<T, S> MatrixMut<T> for MatrixReverse<T, S>
where
S: MatrixMut<T>,
{
fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T> {
if self.source.view_rows() == 0 || self.source.view_columns() == 0 {
return None;
}
let [row, column] = reverse_indexes(
&[row, column],
&[
("row", self.source.view_rows()),
("column", self.source.view_columns()),
],
&[self.rows, self.columns],
);
self.source.try_get_reference_mut(row, column)
}
unsafe fn get_reference_unchecked_mut(&mut self, row: Row, column: Column) -> &mut T {
unsafe {
let [row, column] = reverse_indexes(
&[row, column],
&[
("row", self.source.view_rows()),
("column", self.source.view_columns()),
],
&[self.rows, self.columns],
);
self.source.get_reference_unchecked_mut(row, column)
}
}
}