From adbb7d989ea80c29e71c0708c94b3b8846cd50e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Fri, 2 Feb 2018 12:26:00 +0100 Subject: [PATCH] Add aliases for matrix slices. --- src/core/alias_slice.rs | 74 ++++++++++++++++++++++++++++++++++++++++ src/core/construction.rs | 42 ++++++++++++++++++++++- src/core/matrix_slice.rs | 36 ++++++++++--------- src/core/mod.rs | 2 ++ src/lib.rs | 2 +- 5 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 src/core/alias_slice.rs diff --git a/src/core/alias_slice.rs b/src/core/alias_slice.rs new file mode 100644 index 00000000..3720673d --- /dev/null +++ b/src/core/alias_slice.rs @@ -0,0 +1,74 @@ +use core::Matrix; +use core::dimension::{Dynamic, U1, U2, U3, U4, U5, U6}; +use core::matrix_vec::MatrixVec; +use core::storage::Owned; +use core::matrix_slice::{SliceStorage, SliceStorageMut}; + +/* + * + * + * Matrix slice aliases. + * + * + */ +/// A column-major matrix slice with `R` rows and `C` columns. +pub type MatrixSliceMN<'a, N, R, C, RStride = U1, CStride = R> + = Matrix>; + +pub type MatrixSliceN<'a, N, D, RStride = U1, CStride = D> = MatrixSliceMN<'a, N, D, D, RStride, CStride>; + +pub type DMatrixSlice<'a, N, RStride = U1, CStride = Dynamic> = MatrixSliceN<'a, N, Dynamic, RStride, CStride>; + +pub type MatrixSlice1<'a, N, RStride = U1, CStride = U1> = MatrixSliceN<'a, N, U1, RStride, CStride>; +pub type MatrixSlice2<'a, N, RStride = U1, CStride = U2> = MatrixSliceN<'a, N, U2, RStride, CStride>; +pub type MatrixSlice3<'a, N, RStride = U1, CStride = U3> = MatrixSliceN<'a, N, U3, RStride, CStride>; +pub type MatrixSlice4<'a, N, RStride = U1, CStride = U4> = MatrixSliceN<'a, N, U4, RStride, CStride>; +pub type MatrixSlice5<'a, N, RStride = U1, CStride = U5> = MatrixSliceN<'a, N, U5, RStride, CStride>; +pub type MatrixSlice6<'a, N, RStride = U1, CStride = U6> = MatrixSliceN<'a, N, U6, RStride, CStride>; + +pub type MatrixSlice1x2<'a, N, RStride = U1, CStride = U1> = MatrixSliceMN<'a, N, U2, U1, RStride, CStride>; +pub type MatrixSlice1x3<'a, N, RStride = U1, CStride = U1> = MatrixSliceMN<'a, N, U3, U1, RStride, CStride>; +pub type MatrixSlice1x4<'a, N, RStride = U1, CStride = U1> = MatrixSliceMN<'a, N, U4, U1, RStride, CStride>; +pub type MatrixSlice1x5<'a, N, RStride = U1, CStride = U1> = MatrixSliceMN<'a, N, U5, U1, RStride, CStride>; +pub type MatrixSlice1x6<'a, N, RStride = U1, CStride = U1> = MatrixSliceMN<'a, N, U6, U1, RStride, CStride>; + +pub type MatrixSlice2x2<'a, N, RStride = U1, CStride = U2> = MatrixSliceMN<'a, N, U2, U2, RStride, CStride>; +pub type MatrixSlice2x3<'a, N, RStride = U1, CStride = U2> = MatrixSliceMN<'a, N, U3, U2, RStride, CStride>; +pub type MatrixSlice2x4<'a, N, RStride = U1, CStride = U2> = MatrixSliceMN<'a, N, U4, U2, RStride, CStride>; +pub type MatrixSlice2x5<'a, N, RStride = U1, CStride = U2> = MatrixSliceMN<'a, N, U5, U2, RStride, CStride>; +pub type MatrixSlice2x6<'a, N, RStride = U1, CStride = U2> = MatrixSliceMN<'a, N, U6, U2, RStride, CStride>; + +pub type MatrixSlice3x2<'a, N, RStride = U1, CStride = U3> = MatrixSliceMN<'a, N, U2, U3, RStride, CStride>; +pub type MatrixSlice3x3<'a, N, RStride = U1, CStride = U3> = MatrixSliceMN<'a, N, U3, U3, RStride, CStride>; +pub type MatrixSlice3x4<'a, N, RStride = U1, CStride = U3> = MatrixSliceMN<'a, N, U4, U3, RStride, CStride>; +pub type MatrixSlice3x5<'a, N, RStride = U1, CStride = U3> = MatrixSliceMN<'a, N, U5, U3, RStride, CStride>; +pub type MatrixSlice3x6<'a, N, RStride = U1, CStride = U3> = MatrixSliceMN<'a, N, U6, U3, RStride, CStride>; + +pub type MatrixSlice4x2<'a, N, RStride = U1, CStride = U4> = MatrixSliceMN<'a, N, U2, U4, RStride, CStride>; +pub type MatrixSlice4x3<'a, N, RStride = U1, CStride = U4> = MatrixSliceMN<'a, N, U3, U4, RStride, CStride>; +pub type MatrixSlice4x4<'a, N, RStride = U1, CStride = U4> = MatrixSliceMN<'a, N, U4, U4, RStride, CStride>; +pub type MatrixSlice4x5<'a, N, RStride = U1, CStride = U4> = MatrixSliceMN<'a, N, U5, U4, RStride, CStride>; +pub type MatrixSlice4x6<'a, N, RStride = U1, CStride = U4> = MatrixSliceMN<'a, N, U6, U4, RStride, CStride>; + +pub type MatrixSlice5x2<'a, N, RStride = U1, CStride = U5> = MatrixSliceMN<'a, N, U2, U5, RStride, CStride>; +pub type MatrixSlice5x3<'a, N, RStride = U1, CStride = U5> = MatrixSliceMN<'a, N, U3, U5, RStride, CStride>; +pub type MatrixSlice5x4<'a, N, RStride = U1, CStride = U5> = MatrixSliceMN<'a, N, U4, U5, RStride, CStride>; +pub type MatrixSlice5x5<'a, N, RStride = U1, CStride = U5> = MatrixSliceMN<'a, N, U5, U5, RStride, CStride>; +pub type MatrixSlice5x6<'a, N, RStride = U1, CStride = U5> = MatrixSliceMN<'a, N, U6, U5, RStride, CStride>; + +pub type MatrixSlice6x2<'a, N, RStride = U1, CStride = U6> = MatrixSliceMN<'a, N, U2, U6, RStride, CStride>; +pub type MatrixSlice6x3<'a, N, RStride = U1, CStride = U6> = MatrixSliceMN<'a, N, U3, U6, RStride, CStride>; +pub type MatrixSlice6x4<'a, N, RStride = U1, CStride = U6> = MatrixSliceMN<'a, N, U4, U6, RStride, CStride>; +pub type MatrixSlice6x5<'a, N, RStride = U1, CStride = U6> = MatrixSliceMN<'a, N, U5, U6, RStride, CStride>; +pub type MatrixSlice6x6<'a, N, RStride = U1, CStride = U6> = MatrixSliceMN<'a, N, U6, U6, RStride, CStride>; + + +/* + * + * + * Same thing, but for mutable slices. + * + * + */ +pub type MatrixSliceMutMN<'a, N, R, C, RStride = U1, CStride = R> + = Matrix>; diff --git a/src/core/construction.rs b/src/core/construction.rs index ae536be4..8fac2959 100644 --- a/src/core/construction.rs +++ b/src/core/construction.rs @@ -10,10 +10,12 @@ use typenum::{self, Cmp, Greater}; use alga::general::{ClosedAdd, ClosedMul}; -use core::{DefaultAllocator, Scalar, Matrix, Vector, Unit, MatrixMN, MatrixN, VectorN}; +use core::{DefaultAllocator, Scalar, Matrix, Vector, Unit, MatrixMN, MatrixN, VectorN, + MatrixSliceMN, MatrixSliceMutMN}; use core::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6}; use core::allocator::Allocator; use core::storage::Storage; +use core::matrix_slice::{SliceStorage, SliceStorageMut}; /* * @@ -211,6 +213,44 @@ impl MatrixN } } +/* + * + * Slice constructors. + * + */ +impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> MatrixSliceMN<'a, N, R, C, RStride, CStride> { + pub fn new_slice_generic(data: &'a [N], nrows: R, ncols: C, rstride: RStride, cstride: CStride) -> Self { + // NOTE: The assertion implements the following formula, but without subtractions to avoid + // underflow panics: + // len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1 + assert!(data.len() + cstride.value() + rstride.value() >= + ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, + "Matrix slice: input data buffer to small."); + + + let data = unsafe { + SliceStorage::from_raw_parts(data.as_ptr(), (nrows, ncols), (rstride, cstride)) + }; + Self::from_data(data) + } +} + +impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> MatrixSliceMutMN<'a, N, R, C, RStride, CStride> { + pub fn new_slice_mut_generic(data: &'a mut [N], nrows: R, ncols: C, rstride: RStride, cstride: CStride) -> Self { + // NOTE: The assertion implements the following formula, but without subtractions to avoid + // underflow panics: + // len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1 + assert!(data.len() + cstride.value() + rstride.value() >= + ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, + "Matrix slice: input data buffer to small."); + + let data = unsafe { + SliceStorageMut::from_raw_parts(data.as_mut_ptr(), (nrows, ncols), (rstride, cstride)) + }; + Self::from_data(data) + } +} + /* * diff --git a/src/core/matrix_slice.rs b/src/core/matrix_slice.rs index 71b2ea99..1bd7ea25 100644 --- a/src/core/matrix_slice.rs +++ b/src/core/matrix_slice.rs @@ -20,6 +20,25 @@ macro_rules! slice_storage_impl( _phantoms: PhantomData<$Ref>, } + impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, N, R, C, RStride, CStride> { + /// Create a new matrix slice without bound checking and from a raw pointer. + #[inline] + pub unsafe fn from_raw_parts(ptr: $Ptr, + shape: (R, C), + strides: (RStride, CStride)) + -> Self + where RStride: Dim, + CStride: Dim { + + $T { + ptr: ptr, + shape: shape, + strides: strides, + _phantoms: PhantomData + } + } + } + // Dynamic is arbitrary. It's just to be able to call the constructors with `Slice::` impl<'a, N: Scalar, R: Dim, C: Dim> $T<'a, N, R, C, Dynamic, Dynamic> { /// Create a new matrix slice without bound checking. @@ -49,23 +68,6 @@ macro_rules! slice_storage_impl( $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides) } - - /// Create a new matrix slice without bound checking and from a raw pointer. - #[inline] - pub unsafe fn from_raw_parts(ptr: $Ptr, - shape: (R, C), - strides: (RStride, CStride)) - -> $T<'a, N, R, C, RStride, CStride> - where RStride: Dim, - CStride: Dim { - - $T { - ptr: ptr, - shape: shape, - strides: strides, - _phantoms: PhantomData - } - } } } ); diff --git a/src/core/mod.rs b/src/core/mod.rs index e3532703..b2a6456f 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -15,6 +15,7 @@ mod matrix; mod construction; mod properties; mod alias; +mod alias_slice; mod matrix_alga; mod conversion; mod matrix_slice; @@ -36,6 +37,7 @@ pub use self::dimension::*; pub use self::default_allocator::*; pub use self::alias::*; +pub use self::alias_slice::*; pub use self::matrix_slice::*; pub use self::matrix_array::*; pub use self::matrix_vec::*; diff --git a/src/lib.rs b/src/lib.rs index 2bcdf063..b285819c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,7 @@ an optimized set of tools for computer graphics and physics. Those features incl #![deny(non_upper_case_globals)] #![deny(unused_qualifications)] #![deny(unused_results)] -#![deny(missing_docs)] +#![warn(missing_docs)] #![doc(html_root_url = "http://nalgebra.org/rustdoc")] #[cfg(feature = "arbitrary")]