From 2f77d732261fcae31c0feecbd0da7c1f499946c0 Mon Sep 17 00:00:00 2001 From: Andreas Longva Date: Tue, 5 Nov 2019 17:11:39 +0100 Subject: [PATCH] Generalize From<_> for MatrixSlice(Mut) to allow different strides --- src/base/conversion.rs | 61 ++++++++++++++++++++++++++++++++++------ tests/core/conversion.rs | 10 +++---- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/base/conversion.rs b/src/base/conversion.rs index 36ac43c1..7763a086 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -20,6 +20,7 @@ use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut}; #[cfg(any(feature = "std", feature = "alloc"))] use crate::base::VecStorage; +use crate::base::{SliceStorage, SliceStorageMut}; use crate::base::{DefaultAllocator, Matrix, ArrayStorage, MatrixMN, MatrixSlice, MatrixSliceMut, Scalar}; use crate::constraint::DimEq; @@ -426,59 +427,101 @@ where } } -impl<'a, N, R, C, RSlice, CSlice, S> From<&'a Matrix> -for MatrixSlice<'a, N, RSlice, CSlice, S::RStride, S::CStride> +impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix> +for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride> where N: Scalar, R: Dim, C: Dim, RSlice: Dim, CSlice: Dim, + RStride: Dim, + CStride: Dim, S: Storage, ShapeConstraint: DimEq + DimEq + + DimEq + DimEq { fn from(m: &'a Matrix) -> Self { let (row, col) = m.data.shape(); let row_slice = RSlice::from_usize(row.value()); let col_slice = CSlice::from_usize(col.value()); - m.generic_slice((0, 0), (row_slice, col_slice)) + + let (rstride, cstride) = m.strides(); + + let rstride_slice = RStride::from_usize(rstride); + let cstride_slice = CStride::from_usize(cstride); + + unsafe { + let data = SliceStorage::from_raw_parts(m.data.ptr(), + (row_slice, col_slice), + (rstride_slice, cstride_slice)); + Matrix::from_data_statically_unchecked(data) + } } } -impl<'a, N, R, C, RSlice, CSlice, S> From<&'a mut Matrix> -for MatrixSlice<'a, N, RSlice, CSlice, S::RStride, S::CStride> +impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix> +for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride> where N: Scalar, R: Dim, C: Dim, RSlice: Dim, CSlice: Dim, + RStride: Dim, + CStride: Dim, S: Storage, ShapeConstraint: DimEq + DimEq + + DimEq + DimEq { fn from(m: &'a mut Matrix) -> Self { let (row, col) = m.data.shape(); let row_slice = RSlice::from_usize(row.value()); let col_slice = CSlice::from_usize(col.value()); - m.generic_slice((0, 0), (row_slice, col_slice)) + + let (rstride, cstride) = m.strides(); + + let rstride_slice = RStride::from_usize(rstride); + let cstride_slice = CStride::from_usize(cstride); + + unsafe { + let data = SliceStorage::from_raw_parts(m.data.ptr(), + (row_slice, col_slice), + (rstride_slice, cstride_slice)); + Matrix::from_data_statically_unchecked(data) + } } } -impl<'a, N, R, C, RSlice, CSlice, S> From<&'a mut Matrix> -for MatrixSliceMut<'a, N, RSlice, CSlice, S::RStride, S::CStride> +impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix> +for MatrixSliceMut<'a, N, RSlice, CSlice, RStride, CStride> where N: Scalar, R: Dim, C: Dim, RSlice: Dim, CSlice: Dim, + RStride: Dim, + CStride: Dim, S: StorageMut, ShapeConstraint: DimEq + DimEq + + DimEq + DimEq { fn from(m: &'a mut Matrix) -> Self { let (row, col) = m.data.shape(); let row_slice = RSlice::from_usize(row.value()); let col_slice = CSlice::from_usize(col.value()); - m.generic_slice_mut((0, 0), (row_slice, col_slice)) + + let (rstride, cstride) = m.strides(); + + let rstride_slice = RStride::from_usize(rstride); + let cstride_slice = CStride::from_usize(cstride); + + unsafe { + let data = SliceStorageMut::from_raw_parts(m.data.ptr_mut(), + (row_slice, col_slice), + (rstride_slice, cstride_slice)); + Matrix::from_data_statically_unchecked(data) + } } } \ No newline at end of file diff --git a/tests/core/conversion.rs b/tests/core/conversion.rs index 20954a25..783654ca 100644 --- a/tests/core/conversion.rs +++ b/tests/core/conversion.rs @@ -8,7 +8,7 @@ use na::{ RowVector4, RowVector5, RowVector6, Similarity3, Transform3, Translation3, UnitQuaternion, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, }; -use na::{U3, U4}; +use na::{U1, U3, U4}; use na::{DMatrix, MatrixSlice, MatrixSliceMut, DMatrixSlice, DMatrixSliceMut}; quickcheck!{ @@ -265,11 +265,11 @@ fn matrix_slice_from_matrix_ref() { // Note: these have to be macros, and not functions, because the input type is different // across the different tests. Moreover, the output type depends on the stride of the input, // which is different for static and dynamic matrices. - macro_rules! dynamic_slice { ($mref:expr) => { DMatrixSlice::from($mref) } } - macro_rules! dynamic_slice_mut { ($mref:expr) => { DMatrixSliceMut::from($mref) } } - macro_rules! fixed_slice { ($mref:expr) => { MatrixSlice::<_, U3, U4, _, _>::from($mref)} }; + macro_rules! dynamic_slice { ($mref:expr) => { DMatrixSlice::<_>::from($mref) } } + macro_rules! dynamic_slice_mut { ($mref:expr) => { DMatrixSliceMut::<_>::from($mref) } } + macro_rules! fixed_slice { ($mref:expr) => { MatrixSlice::<_, U3, U4, U1, U3>::from($mref)} }; macro_rules! fixed_slice_mut { - ($mref:expr) => { MatrixSliceMut::<_, U3, U4, _, _>::from($mref) } + ($mref:expr) => { MatrixSliceMut::<_, U3, U4, U1, U3>::from($mref) } }; // TODO: The `into_owned()` is a result of `PartialEq` not being implemented for different