Skip to content

Commit

Permalink
optimize chunks and chunks_mut
Browse files Browse the repository at this point in the history
  • Loading branch information
the8472 committed Jul 2, 2021
1 parent 851c82e commit 24094a0
Showing 1 changed file with 11 additions and 13 deletions.
24 changes: 11 additions & 13 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,18 +1418,17 @@ impl<'a, T> Iterator for Chunks<'a, T> {
#[doc(hidden)]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
None => self.v.len(),
Some(end) => cmp::min(end, self.v.len()),
};
// SAFETY: the caller guarantees that `i` is in bounds,
// which means that `start` must be in bounds of the
// underlying `self.v` slice, and we made sure that `end`
// underlying `self.v` slice, and we made sure that `len`
// is also in bounds of `self.v`. Thus, `start` cannot overflow
// an `isize`, and the slice constructed by `from_raw_parts`
// is a subslice of `self.v` which is guaranteed to be valid
// for the lifetime `'a` of `self.v`.
unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
unsafe {
let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
from_raw_parts(self.v.as_ptr().add(start), len)
}
}
}

Expand Down Expand Up @@ -1457,7 +1456,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
} else {
let start = (len - 1 - n) * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
Some(res) => cmp::min(res, self.v.len()),
Some(res) => cmp::min(self.v.len(), res),
None => self.v.len(),
};
let nth_back = &self.v[start..end];
Expand Down Expand Up @@ -1579,17 +1578,16 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
#[doc(hidden)]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
let start = idx * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
None => self.v.len(),
Some(end) => cmp::min(end, self.v.len()),
};
// SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
//
// Also note that the caller also guarantees that we're never called
// with the same index again, and that no other methods that will
// access this subslice are called, so it is valid for the returned
// slice to be mutable.
unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
unsafe {
let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
}
}
}

Expand Down Expand Up @@ -1619,7 +1617,7 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
} else {
let start = (len - 1 - n) * self.chunk_size;
let end = match start.checked_add(self.chunk_size) {
Some(res) => cmp::min(res, self.v.len()),
Some(res) => cmp::min(self.v.len(), res),
None => self.v.len(),
};
let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
Expand Down

0 comments on commit 24094a0

Please sign in to comment.