Generalize From<_> for MatrixSlice(Mut) to allow different strides

This commit is contained in:
Andreas Longva 2019-11-05 17:11:39 +01:00 committed by Sébastien Crozet
parent 796db161d8
commit f03bd552c2
2 changed files with 57 additions and 14 deletions

View File

@ -20,6 +20,7 @@ use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::VecStorage; use crate::base::VecStorage;
use crate::base::{SliceStorage, SliceStorageMut};
use crate::base::{DefaultAllocator, Matrix, ArrayStorage, MatrixMN, MatrixSlice, MatrixSliceMut, Scalar}; use crate::base::{DefaultAllocator, Matrix, ArrayStorage, MatrixMN, MatrixSlice, MatrixSliceMut, Scalar};
use crate::constraint::DimEq; use crate::constraint::DimEq;
@ -426,59 +427,101 @@ where
} }
} }
impl<'a, N, R, C, RSlice, CSlice, S> From<&'a Matrix<N, R, C, S>> impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<N, R, C, S>>
for MatrixSlice<'a, N, RSlice, CSlice, S::RStride, S::CStride> for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim,
CStride: Dim,
S: Storage<N, R, C>, S: Storage<N, R, C>,
ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice> ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>
{ {
fn from(m: &'a Matrix<N, R, C, S>) -> Self { fn from(m: &'a Matrix<N, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.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<N, R, C, S>> impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>>
for MatrixSlice<'a, N, RSlice, CSlice, S::RStride, S::CStride> for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim,
CStride: Dim,
S: Storage<N, R, C>, S: Storage<N, R, C>,
ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice> ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>
{ {
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self { fn from(m: &'a mut Matrix<N, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.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<N, R, C, S>> impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>>
for MatrixSliceMut<'a, N, RSlice, CSlice, S::RStride, S::CStride> for MatrixSliceMut<'a, N, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim,
CStride: Dim,
S: StorageMut<N, R, C>, S: StorageMut<N, R, C>,
ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice> ShapeConstraint: DimEq<R, RSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>
{ {
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self { fn from(m: &'a mut Matrix<N, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.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)
}
} }
} }

View File

@ -8,7 +8,7 @@ use na::{
RowVector4, RowVector5, RowVector6, Similarity3, Transform3, Translation3, UnitQuaternion, RowVector4, RowVector5, RowVector6, Similarity3, Transform3, Translation3, UnitQuaternion,
Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
}; };
use na::{U3, U4}; use na::{U1, U3, U4};
use na::{DMatrix, MatrixSlice, MatrixSliceMut, DMatrixSlice, DMatrixSliceMut}; use na::{DMatrix, MatrixSlice, MatrixSliceMut, DMatrixSlice, DMatrixSliceMut};
quickcheck!{ 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 // 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, // across the different tests. Moreover, the output type depends on the stride of the input,
// which is different for static and dynamic matrices. // which is different for static and dynamic matrices.
macro_rules! dynamic_slice { ($mref:expr) => { DMatrixSlice::from($mref) } } macro_rules! dynamic_slice { ($mref:expr) => { DMatrixSlice::<_>::from($mref) } }
macro_rules! dynamic_slice_mut { ($mref:expr) => { DMatrixSliceMut::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! fixed_slice { ($mref:expr) => { MatrixSlice::<_, U3, U4, U1, U3>::from($mref)} };
macro_rules! fixed_slice_mut { 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 // TODO: The `into_owned()` is a result of `PartialEq` not being implemented for different