| 1368 | F: FnOnce(StrideShape<D>, *mut T) -> ArrayBase<S, D>, |
| 1369 | { |
| 1370 | fn inner<D: Dimension>( |
| 1371 | shape: &[usize], |
| 1372 | strides: &[isize], |
| 1373 | itemsize: usize, |
| 1374 | mut data_ptr: *mut u8, |
| 1375 | ) -> (StrideShape<D>, u32, *mut u8) { |
| 1376 | let shape = D::from_dimension(&Dim(shape)).expect(DIMENSIONALITY_MISMATCH_ERR); |
| 1377 | |
| 1378 | assert!(strides.len() <= 32, "{}", MAX_DIMENSIONALITY_ERR); |
| 1379 | |
| 1380 | let mut new_strides = D::zeros(strides.len()); |
| 1381 | let mut inverted_axes = 0_u32; |
| 1382 | |
| 1383 | for i in 0..strides.len() { |
| 1384 | // FIXME(kngwyu): Replace this hacky negative strides support with |
| 1385 | // a proper constructor, when it's implemented. |
| 1386 | // See https://github.com/rust-ndarray/ndarray/issues/842 for more. |
| 1387 | if strides[i] >= 0 { |
| 1388 | new_strides[i] = strides[i] as usize / itemsize; |
| 1389 | } else { |
| 1390 | // Move the pointer to the start position. |
| 1391 | data_ptr = unsafe { data_ptr.offset(strides[i] * (shape[i] as isize - 1)) }; |
| 1392 | |
| 1393 | new_strides[i] = (-strides[i]) as usize / itemsize; |
| 1394 | inverted_axes |= 1 << i; |
| 1395 | } |
| 1396 | } |
| 1397 | |
| 1398 | (shape.strides(new_strides), inverted_axes, data_ptr) |
| 1399 | } |
| 1400 | |
| 1401 | let (shape, mut inverted_axes, data_ptr) = inner( |
| 1402 | slf.shape(), |