Skip to content

Commit ab52a98

Browse files
committed
FIX: Split shape check functions into less generic parts
Split these shape check functions into parts that don't require using the element type as a generic parameter. This means that less instantiations of this code is needed for a typical user of ndarray.
1 parent f998a62 commit ab52a98

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

src/dimension/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ pub fn can_index_slice_not_custom<A, D: Dimension>(data: &[A], dim: &D) -> Resul
139139
/// also implies that the length of any individual axis does not exceed
140140
/// `isize::MAX`.)
141141
pub fn max_abs_offset_check_overflow<A, D>(dim: &D, strides: &D) -> Result<usize, ShapeError>
142+
where
143+
D: Dimension,
144+
{
145+
max_abs_offset_check_overflow_impl(mem::size_of::<A>(), dim, strides)
146+
}
147+
148+
fn max_abs_offset_check_overflow_impl<D>(elem_size: usize, dim: &D, strides: &D)
149+
-> Result<usize, ShapeError>
142150
where
143151
D: Dimension,
144152
{
@@ -168,7 +176,7 @@ where
168176
// Determine absolute difference in units of bytes between least and
169177
// greatest address accessible by moving along all axes
170178
let max_offset_bytes = max_offset
171-
.checked_mul(mem::size_of::<A>())
179+
.checked_mul(elem_size)
172180
.ok_or_else(|| from_kind(ErrorKind::Overflow))?;
173181
// Condition 2b.
174182
if max_offset_bytes > isize::MAX as usize {
@@ -216,13 +224,21 @@ pub fn can_index_slice<A, D: Dimension>(
216224
) -> Result<(), ShapeError> {
217225
// Check conditions 1 and 2 and calculate `max_offset`.
218226
let max_offset = max_abs_offset_check_overflow::<A, _>(dim, strides)?;
227+
can_index_slice_impl(max_offset, data.len(), dim, strides)
228+
}
219229

230+
fn can_index_slice_impl<D: Dimension>(
231+
max_offset: usize,
232+
data_len: usize,
233+
dim: &D,
234+
strides: &D,
235+
) -> Result<(), ShapeError> {
220236
// Check condition 4.
221237
let is_empty = dim.slice().iter().any(|&d| d == 0);
222-
if is_empty && max_offset > data.len() {
238+
if is_empty && max_offset > data_len {
223239
return Err(from_kind(ErrorKind::OutOfBounds));
224240
}
225-
if !is_empty && max_offset >= data.len() {
241+
if !is_empty && max_offset >= data_len {
226242
return Err(from_kind(ErrorKind::OutOfBounds));
227243
}
228244

0 commit comments

Comments
 (0)