prevent constructing `MatrixSliceMutMN` for which disjoint indices may alias the same linear index
Fixes #486.
This commit is contained in:
parent
049957ff55
commit
306f096c64
|
@ -37,6 +37,7 @@ generic-array = "0.12"
|
||||||
rand = { version = "0.6", default-features = false }
|
rand = { version = "0.6", default-features = false }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
num-complex = { 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 }
|
approx = { version = "0.3", default-features = false }
|
||||||
alga = { version = "0.9", default-features = false }
|
alga = { version = "0.9", default-features = false }
|
||||||
matrixmultiply = { version = "0.2", optional = true }
|
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::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||||
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
||||||
|
|
||||||
|
use num_rational::Ratio;
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Slice constructors.
|
* 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."
|
"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 {
|
unsafe {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
|
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 matrixmultiply;
|
||||||
extern crate num_complex;
|
extern crate num_complex;
|
||||||
extern crate num_traits as num;
|
extern crate num_traits as num;
|
||||||
|
extern crate num_rational;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate typenum;
|
extern crate typenum;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue