Skip to content

Commit 9f37d58

Browse files
committed
slice iter: more cleanup
1 parent 7d88079 commit 9f37d58

File tree

1 file changed

+34
-44
lines changed

1 file changed

+34
-44
lines changed

library/core/src/slice/iter.rs

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,26 +1415,21 @@ impl<'a, T> Iterator for Windows<'a, T> {
14151415
#[stable(feature = "rust1", since = "1.0.0")]
14161416
impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
14171417
#[inline]
1418-
fn next_back(&mut self) -> Option<&'a [T]> {
1419-
if self.size.get() > self.v.len() {
1420-
None
1421-
} else {
1422-
let ret = Some(&self.v[self.v.len() - self.size.get()..]);
1423-
self.v = &self.v[..self.v.len() - 1];
1424-
ret
1425-
}
1418+
fn next_back(&mut self) -> Option<Self::Item> {
1419+
self.nth_back(0)
14261420
}
14271421

14281422
#[inline]
14291423
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1430-
let (end, overflow) = self.v.len().overflowing_sub(n);
1431-
if end < self.size.get() || overflow {
1424+
if let Some(end) = self.v.len().checked_sub(n)
1425+
&& let Some(start) = end.checked_sub(self.size.get())
1426+
{
1427+
let res = &self.v[start..end];
1428+
self.v = &self.v[..end - 1];
1429+
Some(res)
1430+
} else {
14321431
self.v = &self.v[..0]; // cheaper than &[]
14331432
None
1434-
} else {
1435-
let ret = &self.v[end - self.size.get()..end];
1436-
self.v = &self.v[..end - 1];
1437-
Some(ret)
14381433
}
14391434
}
14401435
}
@@ -1903,13 +1898,10 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19031898

19041899
#[inline]
19051900
fn next(&mut self) -> Option<&'a [T]> {
1906-
if self.v.len() < self.chunk_size {
1907-
None
1908-
} else {
1909-
let (fst, snd) = self.v.split_at(self.chunk_size);
1910-
self.v = snd;
1911-
Some(fst)
1912-
}
1901+
self.v.split_at_checked(self.chunk_size).and_then(|(chunk, rest)| {
1902+
self.v = rest;
1903+
Some(chunk)
1904+
})
19131905
}
19141906

19151907
#[inline]
@@ -1925,14 +1917,14 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19251917

19261918
#[inline]
19271919
fn nth(&mut self, n: usize) -> Option<Self::Item> {
1928-
let (start, overflow) = n.overflowing_mul(self.chunk_size);
1929-
if start >= self.v.len() || overflow {
1920+
if let Some(start) = n.checked_mul(self.chunk_size)
1921+
&& start < self.v.len()
1922+
{
1923+
self.v = &self.v[start..];
1924+
self.next()
1925+
} else {
19301926
self.v = &self.v[..0]; // cheaper than &[]
19311927
None
1932-
} else {
1933-
let (_, snd) = self.v.split_at(start);
1934-
self.v = snd;
1935-
self.next()
19361928
}
19371929
}
19381930

@@ -2061,15 +2053,13 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20612053

20622054
#[inline]
20632055
fn next(&mut self) -> Option<&'a mut [T]> {
2064-
if self.v.len() < self.chunk_size {
2065-
None
2066-
} else {
2067-
// SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2068-
let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
2069-
self.v = tail;
2070-
// SAFETY: Nothing else points to or will point to the contents of this slice.
2071-
Some(unsafe { &mut *head })
2072-
}
2056+
// SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice
2057+
unsafe { slice::from_raw_parts_mut(self.v, self.len()) }
2058+
.split_at_mut_checked(self.chunk_size)
2059+
.and_then(|(chunk, rest)| {
2060+
self.v = rest;
2061+
Some(chunk)
2062+
})
20732063
}
20742064

20752065
#[inline]
@@ -2085,15 +2075,15 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20852075

20862076
#[inline]
20872077
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2088-
let (start, overflow) = n.overflowing_mul(self.chunk_size);
2089-
if start >= self.v.len() || overflow {
2090-
self.v = &mut [];
2091-
None
2092-
} else {
2093-
// SAFETY: The self.v contract ensures that any split_at_mut is valid.
2094-
let (_, snd) = unsafe { self.v.split_at_mut(start) };
2095-
self.v = snd;
2078+
if let Some(start) = n.checked_mul(self.chunk_size)
2079+
&& start < self.v.len()
2080+
{
2081+
// SAFETY: `start < self.v.len()`
2082+
self.v = unsafe { self.v.split_at_mut(start).1 };
20962083
self.next()
2084+
} else {
2085+
self.v = &self.v[..0]; // cheaper than &[]
2086+
None
20972087
}
20982088
}
20992089

0 commit comments

Comments
 (0)