2021-01-03 22:20:34 +08:00
|
|
|
|
use crate::base::dimension::{Const, Dim, DimName, Dynamic};
|
2022-11-12 00:29:55 +08:00
|
|
|
|
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
|
2022-11-14 16:37:21 +08:00
|
|
|
|
use crate::base::{MatrixView, MatrixViewMut, Scalar};
|
2018-02-02 19:26:04 +08:00
|
|
|
|
|
2019-04-10 02:39:36 +08:00
|
|
|
|
use num_rational::Ratio;
|
2020-11-15 23:57:49 +08:00
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// # Creating matrix views from `&[T]`
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
2022-11-11 23:10:39 +08:00
|
|
|
|
MatrixView<'a, T, R, C, RStride, CStride>
|
2018-04-27 13:53:08 +08:00
|
|
|
|
{
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bounds checking, a matrix view from an array and with dimensions and strides specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2021-07-04 11:19:07 +08:00
|
|
|
|
/// # Safety
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
|
|
|
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:18 +08:00
|
|
|
|
#[inline]
|
2018-04-27 13:53:08 +08:00
|
|
|
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a [T],
|
2018-02-02 19:26:35 +08:00
|
|
|
|
start: usize,
|
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
|
|
|
|
rstride: RStride,
|
|
|
|
|
cstride: CStride,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2022-11-11 22:46:04 +08:00
|
|
|
|
let data = ViewStorage::from_raw_parts(
|
2020-11-16 21:59:53 +08:00
|
|
|
|
data.as_ptr().add(start),
|
2018-02-02 19:26:35 +08:00
|
|
|
|
(nrows, ncols),
|
|
|
|
|
(rstride, cstride),
|
|
|
|
|
);
|
2018-02-02 19:26:18 +08:00
|
|
|
|
Self::from_data(data)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// Panics if the input data array dose not contain enough elements.
|
|
|
|
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
#[inline]
|
2018-04-27 13:53:08 +08:00
|
|
|
|
pub fn from_slice_with_strides_generic(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a [T],
|
2018-02-02 19:26:35 +08:00
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
|
|
|
|
rstride: RStride,
|
|
|
|
|
cstride: CStride,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2018-02-02 19:26:04 +08:00
|
|
|
|
// NOTE: The assertion implements the following formula, but without subtractions to avoid
|
|
|
|
|
// underflow panics:
|
|
|
|
|
// len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
data.len() + cstride.value() + rstride.value()
|
|
|
|
|
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
2022-11-14 21:40:53 +08:00
|
|
|
|
"Matrix view: input data buffer too small."
|
2018-02-02 19:26:35 +08:00
|
|
|
|
);
|
2018-02-02 19:26:04 +08:00
|
|
|
|
|
2018-04-27 13:53:08 +08:00
|
|
|
|
unsafe {
|
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
|
|
|
|
|
}
|
2018-02-02 19:26:18 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-11 23:10:39 +08:00
|
|
|
|
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixView<'a, T, R, C> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound-checking, a matrix view from an array and with dimensions specified by generic types instances.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
///
|
2021-07-04 11:19:07 +08:00
|
|
|
|
/// # Safety
|
2020-11-15 23:57:49 +08:00
|
|
|
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
|
|
|
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub unsafe fn from_slice_generic_unchecked(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a [T],
|
2020-11-15 23:57:49 +08:00
|
|
|
|
start: usize,
|
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
|
|
|
|
) -> Self {
|
2021-01-03 22:20:34 +08:00
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(
|
|
|
|
|
data, start, nrows, ncols, Const::<1>, nrows,
|
|
|
|
|
)
|
2020-11-15 23:57:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
///
|
|
|
|
|
/// Panics if the input data array dose not contain enough elements.
|
|
|
|
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
|
2021-01-03 22:20:34 +08:00
|
|
|
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
2020-11-15 23:57:49 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! impl_constructors(
|
|
|
|
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
2022-11-11 23:10:39 +08:00
|
|
|
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixView<'a, T, $($Dims),*> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a new matrix view from the given data array.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
///
|
|
|
|
|
/// Panics if `data` does not contain enough elements.
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice(data: &'a [T], $($args: usize),*) -> Self {
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::from_slice_generic(data, $($gargs),*)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound checking, a new matrix view from the given data array.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-11 23:10:39 +08:00
|
|
|
|
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixView<'a, T, $($Dims,)* Dynamic, Dynamic> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a new matrix view with the specified strides from the given data array.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
///
|
|
|
|
|
/// Panics if `data` does not contain enough elements.
|
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
|
2020-11-15 23:57:49 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
2020-11-15 23:57:49 +08:00
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// TODO: this is not very pretty. We could find a better call syntax.
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
|
|
|
|
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
2020-11-15 23:57:49 +08:00
|
|
|
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
|
|
|
|
); // Arguments for non-generic constructors.
|
|
|
|
|
|
|
|
|
|
impl_constructors!(R, Dynamic;
|
|
|
|
|
=> R: DimName;
|
|
|
|
|
R::name(), Dynamic::new(ncols);
|
|
|
|
|
ncols);
|
|
|
|
|
|
|
|
|
|
impl_constructors!(Dynamic, C;
|
|
|
|
|
=> C: DimName;
|
|
|
|
|
Dynamic::new(nrows), C::name();
|
|
|
|
|
nrows);
|
|
|
|
|
|
|
|
|
|
impl_constructors!(Dynamic, Dynamic;
|
|
|
|
|
;
|
|
|
|
|
Dynamic::new(nrows), Dynamic::new(ncols);
|
|
|
|
|
nrows, ncols);
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// # Creating mutable matrix views from `&mut [T]`
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
2022-11-14 16:37:21 +08:00
|
|
|
|
MatrixViewMut<'a, T, R, C, RStride, CStride>
|
2018-04-27 13:53:08 +08:00
|
|
|
|
{
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound-checking, a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2021-07-04 11:19:07 +08:00
|
|
|
|
/// # Safety
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
|
|
|
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:18 +08:00
|
|
|
|
#[inline]
|
2018-04-27 13:53:08 +08:00
|
|
|
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a mut [T],
|
2018-02-02 19:26:35 +08:00
|
|
|
|
start: usize,
|
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
|
|
|
|
rstride: RStride,
|
|
|
|
|
cstride: CStride,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2022-11-11 22:46:04 +08:00
|
|
|
|
let data = ViewStorageMut::from_raw_parts(
|
2020-11-16 21:59:53 +08:00
|
|
|
|
data.as_mut_ptr().add(start),
|
2018-02-02 19:26:35 +08:00
|
|
|
|
(nrows, ncols),
|
|
|
|
|
(rstride, cstride),
|
|
|
|
|
);
|
2018-02-02 19:26:04 +08:00
|
|
|
|
Self::from_data(data)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// Panics if the input data array dose not contain enough elements.
|
|
|
|
|
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
#[inline]
|
2018-04-27 13:53:08 +08:00
|
|
|
|
pub fn from_slice_with_strides_generic(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a mut [T],
|
2018-02-02 19:26:35 +08:00
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
|
|
|
|
rstride: RStride,
|
|
|
|
|
cstride: CStride,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2018-02-02 19:26:04 +08:00
|
|
|
|
// NOTE: The assertion implements the following formula, but without subtractions to avoid
|
|
|
|
|
// underflow panics:
|
|
|
|
|
// len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
|
2018-02-02 19:26:35 +08:00
|
|
|
|
assert!(
|
|
|
|
|
data.len() + cstride.value() + rstride.value()
|
|
|
|
|
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
|
2022-11-14 21:40:53 +08:00
|
|
|
|
"Matrix view: input data buffer too small."
|
2018-02-02 19:26:35 +08:00
|
|
|
|
);
|
2018-02-02 19:26:04 +08:00
|
|
|
|
|
2020-04-06 00:49:48 +08:00
|
|
|
|
assert!(
|
|
|
|
|
{
|
|
|
|
|
let nrows = nrows.value();
|
|
|
|
|
let ncols = ncols.value();
|
|
|
|
|
let rstride = rstride.value();
|
|
|
|
|
let cstride = cstride.value();
|
2019-04-10 02:39:36 +08:00
|
|
|
|
|
2020-04-06 00:49:48 +08:00
|
|
|
|
nrows * ncols <= 1
|
|
|
|
|
|| match (rstride, cstride) {
|
|
|
|
|
(0, 0) => false, // otherwise: matrix[(0, 0)] == index[(nrows - 1, ncols - 1)],
|
|
|
|
|
(0, _) => nrows <= 1, // otherwise: matrix[(0, 0)] == index[(nrows - 1, 0)],
|
|
|
|
|
(_, 0) => ncols <= 1, // otherwise: matrix[(0, 0)] == index[(0, ncols - 1)],
|
|
|
|
|
(_, _) => {
|
|
|
|
|
// otherwise: matrix[(0, numer)] == index[(denom, 0)]
|
|
|
|
|
let ratio = Ratio::new(rstride, cstride);
|
|
|
|
|
nrows <= *ratio.denom() || ncols <= *ratio.numer()
|
|
|
|
|
}
|
2019-04-10 02:39:36 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
2022-11-14 21:40:53 +08:00
|
|
|
|
"Matrix view: dimensions and strides result in aliased indices."
|
2020-04-06 00:49:48 +08:00
|
|
|
|
);
|
2019-04-10 02:39:36 +08:00
|
|
|
|
|
2018-02-02 19:26:18 +08:00
|
|
|
|
unsafe {
|
2018-04-27 13:53:08 +08:00
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
|
2018-02-02 19:26:18 +08:00
|
|
|
|
}
|
2018-02-02 19:26:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 16:37:21 +08:00
|
|
|
|
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixViewMut<'a, T, R, C> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound-checking, a mutable matrix view from an array and with dimensions specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2021-07-04 11:19:07 +08:00
|
|
|
|
/// # Safety
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
|
|
|
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:18 +08:00
|
|
|
|
#[inline]
|
2018-04-27 13:53:08 +08:00
|
|
|
|
pub unsafe fn from_slice_generic_unchecked(
|
2021-04-11 17:00:38 +08:00
|
|
|
|
data: &'a mut [T],
|
2018-02-02 19:26:35 +08:00
|
|
|
|
start: usize,
|
|
|
|
|
nrows: R,
|
|
|
|
|
ncols: C,
|
2020-04-06 00:49:48 +08:00
|
|
|
|
) -> Self {
|
2021-01-03 22:20:34 +08:00
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(
|
|
|
|
|
data, start, nrows, ncols, Const::<1>, nrows,
|
|
|
|
|
)
|
2018-02-02 19:26:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// Panics if the input data array dose not contain enough elements.
|
|
|
|
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
|
2021-01-03 22:20:34 +08:00
|
|
|
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
2018-02-02 19:26:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! impl_constructors_mut(
|
|
|
|
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
2022-11-14 16:37:21 +08:00
|
|
|
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixViewMut<'a, T, $($Dims),*> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a new mutable matrix view from the given data array.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// Panics if `data` does not contain enough elements.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice(data: &'a mut [T], $($args: usize),*) -> Self {
|
2018-04-27 13:53:08 +08:00
|
|
|
|
Self::from_slice_generic(data, $($gargs),*)
|
2018-02-02 19:26:04 +08:00
|
|
|
|
}
|
2018-02-02 19:26:18 +08:00
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound checking, a new mutable matrix view from the given data array.
|
2018-02-02 19:26:18 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
2018-04-27 13:53:08 +08:00
|
|
|
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
2018-02-02 19:26:18 +08:00
|
|
|
|
}
|
2018-02-02 19:26:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 16:37:21 +08:00
|
|
|
|
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixViewMut<'a, T, $($Dims,)* Dynamic, Dynamic> {
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates a new mutable matrix view with the specified strides from the given data array.
|
2018-04-27 13:53:08 +08:00
|
|
|
|
///
|
2018-02-02 19:26:40 +08:00
|
|
|
|
/// Panics if `data` does not contain enough elements.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
2018-04-27 13:53:08 +08:00
|
|
|
|
Self::from_slice_with_strides_generic(
|
2018-02-02 19:26:04 +08:00
|
|
|
|
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
2018-02-02 19:26:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 21:02:36 +08:00
|
|
|
|
/// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
|
2018-02-02 19:26:18 +08:00
|
|
|
|
#[inline]
|
2021-04-11 17:00:38 +08:00
|
|
|
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
2018-04-27 13:53:08 +08:00
|
|
|
|
Self::from_slice_with_strides_generic_unchecked(
|
2018-02-02 19:26:18 +08:00
|
|
|
|
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
2018-02-02 19:26:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2020-11-15 23:57:49 +08:00
|
|
|
|
// TODO: this is not very pretty. We could find a better call syntax.
|
2021-04-11 17:00:38 +08:00
|
|
|
|
impl_constructors_mut!(R, C; // Arguments for Matrix<T, ..., S>
|
|
|
|
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
2020-06-07 15:07:25 +08:00
|
|
|
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
|
|
|
|
); // Arguments for non-generic constructors.
|
2018-02-02 19:26:04 +08:00
|
|
|
|
|
|
|
|
|
impl_constructors_mut!(R, Dynamic;
|
|
|
|
|
=> R: DimName;
|
|
|
|
|
R::name(), Dynamic::new(ncols);
|
|
|
|
|
ncols);
|
|
|
|
|
|
|
|
|
|
impl_constructors_mut!(Dynamic, C;
|
|
|
|
|
=> C: DimName;
|
|
|
|
|
Dynamic::new(nrows), C::name();
|
|
|
|
|
nrows);
|
|
|
|
|
|
|
|
|
|
impl_constructors_mut!(Dynamic, Dynamic;
|
|
|
|
|
;
|
|
|
|
|
Dynamic::new(nrows), Dynamic::new(ncols);
|
|
|
|
|
nrows, ncols);
|