prevent constructing MatrixSliceMutMN
for which disjoint indices may alias the same linear index
Fixes #486.
This commit is contained in:
parent
2838350ea4
commit
2e273ad6c5
@ -37,6 +37,7 @@ generic-array = "0.12"
|
||||
rand = { version = "0.6", default-features = false }
|
||||
num-traits = { version = "0.2", default-features = false }
|
||||
num-complex = { version = "0.2", default-features = false }
|
||||
num-rational = { version = "0.2", default-features = false }
|
||||
approx = { version = "0.3", default-features = false }
|
||||
alga = { version = "0.9", default-features = false }
|
||||
matrixmultiply = { version = "0.2", optional = true }
|
||||
|
@ -2,6 +2,7 @@ use crate::base::dimension::{Dim, DimName, Dynamic, U1};
|
||||
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
||||
|
||||
use num_rational::Ratio;
|
||||
/*
|
||||
*
|
||||
* Slice constructors.
|
||||
@ -107,6 +108,37 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||
"Matrix slice: input data buffer to small."
|
||||
);
|
||||
|
||||
assert!({
|
||||
let nrows = nrows.value();
|
||||
let ncols = ncols.value();
|
||||
let rstride = rstride.value();
|
||||
let cstride = cstride.value();
|
||||
|
||||
// `Storage::linear_index`
|
||||
let index = |i, j| (i * rstride) + (j * cstride);
|
||||
|
||||
// The final condition of each arm is an expression in the form:
|
||||
// index(i₀, j₀) != index(i₁, j₁)
|
||||
// If this expression is `false`, then the values (i₀, j₀)
|
||||
// and (i₁, j₁) are concrete examples of indices that would
|
||||
// collide if the matrix was actually constructed.
|
||||
nrows * ncols <= 1 ||
|
||||
match (rstride, cstride) {
|
||||
(0, 0) => index(0, 0) != index(nrows - 1, ncols - 1),
|
||||
(0, _) => nrows <= 1 || index(0, 0) != index(nrows - 1, 0),
|
||||
(_, 0) => ncols <= 1 || index(0, 0) != index(0, ncols - 1),
|
||||
(_, _) => {
|
||||
let ratio = Ratio::new(rstride, cstride);
|
||||
let numer = *ratio.numer();
|
||||
let denom = *ratio.denom();
|
||||
|
||||
nrows <= denom || ncols <= numer
|
||||
|| index(0, numer) != index(denom, 0)
|
||||
}
|
||||
}
|
||||
},
|
||||
"Matrix slice: dimensions and strides result in aliased indices.");
|
||||
|
||||
unsafe {
|
||||
Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ extern crate generic_array;
|
||||
extern crate matrixmultiply;
|
||||
extern crate num_complex;
|
||||
extern crate num_traits as num;
|
||||
extern crate num_rational;
|
||||
extern crate rand;
|
||||
extern crate typenum;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user