|
@@ -0,0 +1,111 @@
|
|
|
+use std::fmt::{Debug, Formatter};
|
|
|
+use std::marker::PhantomData;
|
|
|
+use crate::{GenericMatrix, Matrix, Numeric};
|
|
|
+use crate::types::matrix::matrices_are_equal;
|
|
|
+
|
|
|
+pub struct View<
|
|
|
+ 'a,
|
|
|
+ T: Numeric,
|
|
|
+ const ROWS: usize,
|
|
|
+ const COLUMNS: usize,
|
|
|
+ const BASE_ROWS: usize,
|
|
|
+ const BASE_COLUMNS: usize,
|
|
|
+ M: Matrix<T, BASE_ROWS, BASE_COLUMNS>
|
|
|
+> {
|
|
|
+ base: &'a M,
|
|
|
+ origin: (usize, usize),
|
|
|
+ phantom: PhantomData<*const T>,
|
|
|
+}
|
|
|
+
|
|
|
+impl<
|
|
|
+ 'a,
|
|
|
+ T: Numeric,
|
|
|
+ const ROWS: usize,
|
|
|
+ const COLUMNS: usize,
|
|
|
+ const BASE_ROWS: usize,
|
|
|
+ const BASE_COLUMNS: usize,
|
|
|
+ M: Matrix<T, BASE_ROWS, BASE_COLUMNS>
|
|
|
+> Debug for View<'a, T, ROWS, COLUMNS, BASE_ROWS, BASE_COLUMNS, M> {
|
|
|
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
+ let mut mat = GenericMatrix::<T, ROWS, COLUMNS>::new();
|
|
|
+ for r in 0..ROWS {
|
|
|
+ for c in 0..COLUMNS {
|
|
|
+ mat.data[r][c] = self.get(r, c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ f
|
|
|
+ .debug_struct("View")
|
|
|
+ .field("data", &mat.data)
|
|
|
+ .finish()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<
|
|
|
+ 'a,
|
|
|
+ T: Numeric,
|
|
|
+ const ROWS: usize,
|
|
|
+ const COLUMNS: usize,
|
|
|
+ const BASE_ROWS: usize,
|
|
|
+ const BASE_COLUMNS: usize,
|
|
|
+ M: Matrix<T, BASE_ROWS, BASE_COLUMNS>
|
|
|
+> View<'a, T, ROWS, COLUMNS, BASE_ROWS, BASE_COLUMNS, M> {
|
|
|
+ pub fn new(base: &'a M, origin: (usize, usize)) -> Self {
|
|
|
+ Self {
|
|
|
+ base,
|
|
|
+ origin,
|
|
|
+ phantom: PhantomData,
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<
|
|
|
+ 'a,
|
|
|
+ T: Numeric,
|
|
|
+ const ROWS: usize,
|
|
|
+ const COLUMNS: usize,
|
|
|
+ const BASE_ROWS: usize,
|
|
|
+ const BASE_COLUMNS: usize,
|
|
|
+ M: Matrix<T, BASE_ROWS, BASE_COLUMNS>
|
|
|
+> Matrix<T, ROWS, COLUMNS> for View<'a, T, ROWS, COLUMNS, BASE_ROWS, BASE_COLUMNS, M> {
|
|
|
+ fn get(&self, row: usize, col: usize) -> T {
|
|
|
+ let (base_row, base_col) = self.origin;
|
|
|
+ self.base.get(base_row + row, base_col + col)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set(&mut self, row: usize, col: usize, value: T) {
|
|
|
+ let (base_row, base_col) = self.origin;
|
|
|
+ assert_eq!(self.base.get(base_row + row, base_col + col), value);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<
|
|
|
+ 'a,
|
|
|
+ T: Numeric,
|
|
|
+ const ROWS: usize,
|
|
|
+ const COLUMNS: usize,
|
|
|
+ const BASE_ROWS: usize,
|
|
|
+ const BASE_COLUMNS: usize,
|
|
|
+ M: Matrix<T, BASE_ROWS, BASE_COLUMNS>,
|
|
|
+ RHS: Matrix<T, ROWS, COLUMNS>
|
|
|
+> PartialEq<RHS> for View<'a, T, ROWS, COLUMNS, BASE_ROWS, BASE_COLUMNS, M> {
|
|
|
+ fn eq(&self, other: &RHS) -> bool {
|
|
|
+ matrices_are_equal(self, other, T::epsilon())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn ne(&self, other: &RHS) -> bool {
|
|
|
+ !matrices_are_equal(self, other, T::epsilon())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use crate::{SquareMatrix};
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn view_of_generic_matrix() {
|
|
|
+ let mat = SquareMatrix::diagonal(&[1, 2, 3, 4]);
|
|
|
+ let view = mat.view::<2, 2>((1, 1));
|
|
|
+ assert_eq!(view, SquareMatrix::diagonal(&[2, 3]));
|
|
|
+ }
|
|
|
+}
|