Skip to content

Commit 4962b40

Browse files
committed
slice iter: cleanup and make similar Chunks[Mut]::nth
1 parent 1897787 commit 4962b40

File tree

1 file changed

+19
-25
lines changed

1 file changed

+19
-25
lines changed

library/core/src/slice/iter.rs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,13 +1537,13 @@ impl<'a, T> Iterator for Chunks<'a, T> {
15371537

15381538
#[inline]
15391539
fn nth(&mut self, n: usize) -> Option<Self::Item> {
1540-
let (start, overflow) = n.overflowing_mul(self.chunk_size);
1541-
// min(len) makes a wrong start harmless, but enables optimizing this to brachless code
1542-
let chunk_start = &self.v[start.min(self.v.len())..];
1543-
let (nth, remainder) = chunk_start.split_at(self.chunk_size.min(chunk_start.len()));
1544-
if !overflow && start < self.v.len() {
1545-
self.v = remainder;
1546-
Some(nth)
1540+
if let Some(start) = n.checked_mul(self.chunk_size)
1541+
&& start < self.v.len()
1542+
{
1543+
let rest = &self.v[start..];
1544+
let (chunk, rest) = rest.split_at(self.chunk_size.min(rest.len()));
1545+
self.v = rest;
1546+
Some(chunk)
15471547
} else {
15481548
self.v = &self.v[..0]; // cheaper than &[]
15491549
None
@@ -1613,10 +1613,7 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
16131613
None
16141614
} else {
16151615
let start = (len - 1 - n) * self.chunk_size;
1616-
let end = match start.checked_add(self.chunk_size) {
1617-
Some(res) => cmp::min(self.v.len(), res),
1618-
None => self.v.len(),
1619-
};
1616+
let end = (start + self.chunk_size).min(self.v.len());
16201617
let nth_back = &self.v[start..end];
16211618
self.v = &self.v[..start];
16221619
Some(nth_back)
@@ -1719,22 +1716,19 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
17191716

17201717
#[inline]
17211718
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
1722-
let (start, overflow) = n.overflowing_mul(self.chunk_size);
1723-
if start >= self.v.len() || overflow {
1719+
if let Some(start) = n.checked_mul(self.chunk_size)
1720+
&& start < self.v.len()
1721+
{
1722+
// SAFETY: `start < self.v.len()` ensures this is in bounds
1723+
let (_, rest) = unsafe { self.v.split_at_mut(start) };
1724+
// SAFETY: `.min(rest.len()` ensures this is in bounds
1725+
let (chunk, rest) = unsafe { rest.split_at_mut(self.chunk_size.min(rest.len())) };
1726+
self.v = rest;
1727+
// SAFETY: Nothing else points to or will point to the contents of this slice.
1728+
Some(unsafe { &mut *chunk })
1729+
} else {
17241730
self.v = &mut [];
17251731
None
1726-
} else {
1727-
let end = match start.checked_add(self.chunk_size) {
1728-
Some(sum) => cmp::min(self.v.len(), sum),
1729-
None => self.v.len(),
1730-
};
1731-
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
1732-
let (head, tail) = unsafe { self.v.split_at_mut(end) };
1733-
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
1734-
let (_, nth) = unsafe { head.split_at_mut(start) };
1735-
self.v = tail;
1736-
// SAFETY: Nothing else points to or will point to the contents of this slice.
1737-
Some(unsafe { &mut *nth })
17381732
}
17391733
}
17401734

0 commit comments

Comments
 (0)