@@ -69,11 +69,11 @@ pub fn dim_stride_overlap<D: Dimension>(dim: &D, strides: &D) -> bool {
6969/// lengths does not exceed `isize::MAX`.
7070///
7171/// If `size_of_checked_shape(dim)` returns `Ok(size)`, the data buffer is a
72- /// `Vec` of length `size`, and `strides` are created with
72+ /// slice or `Vec` of length `size`, and `strides` are created with
7373/// `self.default_strides()` or `self.fortran_strides()`, then the invariants
7474/// are met to construct an array from the data buffer, `dim`, and `strides`.
75- /// (The data buffer being a `Vec` guarantees that it contains no more than
76- /// `isize::MAX` bytes.)
75+ /// (The data buffer being a slice or `Vec` guarantees that it contains no more
76+ /// than `isize::MAX` bytes.)
7777pub fn size_of_shape_checked < D : Dimension > ( dim : & D ) -> Result < usize , ShapeError > {
7878 let size_nonzero = dim
7979 . slice ( )
@@ -94,13 +94,9 @@ pub fn size_of_shape_checked<D: Dimension>(dim: &D) -> Result<usize, ShapeError>
9494///
9595/// To meet the invariants,
9696///
97- /// 1. The offset in units of `A` and in units of bytes between the least
98- /// address and greatest address accessible by moving along all axes must
99- /// not exceed `isize::MAX`.
97+ /// 1. The product of non-zero axis lengths must not exceed `isize::MAX`.
10098///
101- /// 2. The product of non-zero axis lengths must not exceed `isize::MAX`.
102- ///
103- /// 3. The result of `dim.size()` (assuming no overflow) must be less than or
99+ /// 2. The result of `dim.size()` (assuming no overflow) must be less than or
104100/// equal to the length of the slice.
105101///
106102/// (Since `dim.default_strides()` and `dim.fortran_strides()` always return
@@ -112,31 +108,17 @@ pub fn size_of_shape_checked<D: Dimension>(dim: &D) -> Result<usize, ShapeError>
112108/// difference between the least address and greatest address accessible by
113109/// moving along all axes is ≤ the length of the slice.)
114110///
115- /// Note that if `data` is a slice of a `Vec<A>`, conditions 2 and 3 are
116- /// sufficient to guarantee condition 1 because `Vec` never allocates more than
117- /// `isize::MAX` bytes.
111+ /// Note that since slices cannot contain more than `isize::MAX` bytes,
112+ /// conditions 1 and 2 are sufficient to guarantee that the offset in units of
113+ /// `A` and in units of bytes between the least address and greatest address
114+ /// accessible by moving along all axes does not exceed `isize::MAX`.
118115pub fn can_index_slice_not_custom < A , D : Dimension > ( data : & [ A ] , dim : & D ) -> Result < ( ) , ShapeError > {
119- // Condition 2 and 1a .
116+ // Condition 1 .
120117 let len = size_of_shape_checked ( dim) ?;
121-
122- // Calculate offset in units of `A` between the least address and greatest
123- // address accessible by moving along all axes.
124- let max_offset = len. saturating_sub ( 1 ) ;
125- // Calcaulte offset in units of bytes between the least address and
126- // greatest address accessible by moving along all axes.
127- let max_offset_bytes = max_offset
128- . checked_mul ( mem:: size_of :: < A > ( ) )
129- . ok_or_else ( || from_kind ( ErrorKind :: Overflow ) ) ?;
130-
131- // Condition 1b.
132- if max_offset_bytes > isize:: MAX as usize {
133- return Err ( from_kind ( ErrorKind :: Overflow ) ) ;
134- }
135- // Condition 3.
118+ // Condition 2.
136119 if len > data. len ( ) {
137120 return Err ( from_kind ( ErrorKind :: OutOfBounds ) ) ;
138121 }
139-
140122 Ok ( ( ) )
141123}
142124
@@ -200,40 +182,37 @@ where
200182///
201183/// 1. The ndim of `dim` and `strides` must be the same.
202184///
203- /// 2. The absolute difference in units of `A` and in units of bytes between
204- /// the least address and greatest address accessible by moving along all axes
205- /// must not exceed `isize::MAX`.
206- ///
207- /// 3. The product of non-zero axis lengths must not exceed `isize::MAX`.
185+ /// 2. The product of non-zero axis lengths must not exceed `isize::MAX`.
208186///
209- /// 4 . For axes with length > 1, the stride must be nonnegative. This is
187+ /// 3 . For axes with length > 1, the stride must be nonnegative. This is
210188/// necessary to make sure the pointer cannot move backwards outside the
211189/// slice. For axes with length ≤ 1, the stride can be anything.
212190///
213- /// 5 . If the array will be empty (any axes are zero-length), the difference
191+ /// 4 . If the array will be empty (any axes are zero-length), the difference
214192/// between the least address and greatest address accessible by moving
215193/// along all axes must be ≤ `data.len()`. (It's fine in this case to move
216194/// one byte past the end of the slice since the pointers will be offset but
217195/// never dereferenced.)
218196///
219197/// If the array will not be empty, the difference between the least address
220198/// and greatest address accessible by moving along all axes must be <
221- /// `data.len()`. This and #4 ensure that all dereferenceable pointers point
199+ /// `data.len()`. This and #3 ensure that all dereferenceable pointers point
222200/// to elements within the slice.
223201///
224- /// 6 . The strides must not allow any element to be referenced by two different
202+ /// 5 . The strides must not allow any element to be referenced by two different
225203/// indices.
226204///
227- /// Note that if `data` is a slice of a `Vec<A>`, conditions 4 and 5 are
228- /// sufficient to guarantee condition 2 because `Vec` never allocates more than
229- /// `isize::MAX` bytes.
205+ /// Note that since slices cannot contain more than `isize::MAX` bytes,
206+ /// condition 4 is sufficient to guarantee that the absolute difference in
207+ /// units of `A` and in units of bytes between the least address and greatest
208+ /// address accessible by moving along all axes does not exceed `isize::MAX`.
230209pub fn can_index_slice < A , D : Dimension > ( data : & [ A ] , dim : & D , strides : & D )
231210 -> Result < ( ) , ShapeError >
232211{
233- // Check conditions 1, 2, and 3 .
212+ // Check conditions 1 and 2 and calculate `max_offset` .
234213 let max_offset = max_abs_offset_check_overflow :: < A , _ > ( dim, strides) ?;
235214
236- // Check condition 5 .
215+ // Check condition 4 .
237216 let is_empty = dim. slice ( ) . iter ( ) . any ( |& d| d == 0 ) ;
238217 if is_empty && max_offset > data. len ( ) {
239218 return Err ( from_kind ( ErrorKind :: OutOfBounds ) ) ;
@@ -242,15 +221,15 @@ pub fn can_index_slice<A, D: Dimension>(data: &[A], dim: &D, strides: &D)
242221 return Err ( from_kind ( ErrorKind :: OutOfBounds ) ) ;
243222 }
244223
245- // Check condition 4 .
224+ // Check condition 3 .
246225 for ( & d, & s) in izip ! ( dim. slice( ) , strides. slice( ) ) {
247226 let s = s as isize ;
248227 if d > 1 && s < 0 {
249228 return Err ( from_kind ( ErrorKind :: Unsupported ) ) ;
250229 }
251230 }
252231
253- // Check condition 6 .
232+ // Check condition 5 .
254233 if !is_empty && dim_stride_overlap ( dim, strides) {
255234 return Err ( from_kind ( ErrorKind :: Unsupported ) ) ;
256235 }
0 commit comments